Skip to content

Commit ce2ac52

Browse files
committed
Fix NPE on goto to invalid method reference
- check if element is a record before listing components - removed reflective method calls and updated logic - added regression test
1 parent 6ab1e9b commit ce2ac52

File tree

2 files changed

+40
-25
lines changed

2 files changed

+40
-25
lines changed

java/java.editor/src/org/netbeans/modules/editor/java/GoToSupport.java

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@
4545
import java.awt.Toolkit;
4646
import java.awt.event.KeyEvent;
4747
import java.io.IOException;
48-
import java.lang.reflect.InvocationTargetException;
49-
import java.lang.reflect.Method;
5048
import java.net.URL;
5149
import java.util.ArrayList;
5250
import java.util.Collections;
@@ -478,30 +476,17 @@ public static Context resolveContext(CompilationInfo controller, Document doc, i
478476
}
479477
}
480478
if (el != null && el.getKind() == ElementKind.METHOD) {
481-
for (Element peer : el.getEnclosingElement().getEnclosedElements()) {
482-
if (peer.getKind().name().contains("RECORD_COMPONENT")) {
483-
try {
484-
Class<?> recordComponent = Class.forName("javax.lang.model.element.RecordComponentElement", true, VariableTree.class.getClassLoader());
485-
Method getAccessor = recordComponent.getDeclaredMethod("getAccessor");
486-
Method getRecordComponents = TypeElement.class.getDeclaredMethod("getRecordComponents");
487-
for (Element component : (Iterable<Element>) getRecordComponents.invoke(peer.getEnclosingElement())) {
488-
if (Objects.equals(el, getAccessor.invoke(component))) {
489-
el = component;
490-
break;
479+
Element enclosing = el.getEnclosingElement();
480+
if (enclosing.getKind() == ElementKind.RECORD) {
481+
OUTER:
482+
for (Element peer : enclosing.getEnclosedElements()) {
483+
if (peer.getKind() == ElementKind.RECORD_COMPONENT) {
484+
for (RecordComponentElement rc : ((TypeElement)enclosing).getRecordComponents()) {
485+
if (Objects.equals(el, rc.getAccessor())) {
486+
el = rc;
487+
break OUTER;
491488
}
492489
}
493-
} catch (ClassNotFoundException ex) {
494-
Exceptions.printStackTrace(ex);
495-
} catch (IllegalAccessException ex) {
496-
Exceptions.printStackTrace(ex);
497-
} catch (IllegalArgumentException ex) {
498-
Exceptions.printStackTrace(ex);
499-
} catch (InvocationTargetException ex) {
500-
Exceptions.printStackTrace(ex);
501-
} catch (NoSuchMethodException ex) {
502-
Exceptions.printStackTrace(ex);
503-
} catch (SecurityException ex) {
504-
Exceptions.printStackTrace(ex);
505490
}
506491
}
507492
}
@@ -869,7 +854,7 @@ public Void scan(Tree tree, Void p) {
869854
if (found != null) {
870855
return null;
871856
}
872-
if (tree != null && "BINDING_PATTERN".equals(tree.getKind().name())) {
857+
if (tree != null && tree.getKind() == Kind.BINDING_PATTERN) {
873858
if (process(new TreePath(getCurrentPath(), tree))) {
874859
return null;
875860
}

java/java.editor/test/unit/src/org/netbeans/modules/editor/java/GoToSupportTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import org.openide.util.Exceptions;
7373
import org.openide.util.lookup.ServiceProvider;
7474
import static java.nio.file.StandardCopyOption.*;
75+
import java.util.concurrent.atomic.AtomicBoolean;
7576

7677
/**
7778
*
@@ -1620,6 +1621,35 @@ public void run(CompilationController parameter) throws Exception {
16201621
assertTrue(wasCalled[0]);
16211622
}
16221623

1624+
public void testNoExceptionOnInvalidMethodReference() throws Exception {
1625+
this.sourceLevel = getLatestSourceVersion();
1626+
JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true;
1627+
final String code = """
1628+
package test;
1629+
public class Test {
1630+
private static void method() {
1631+
javax.swing.event.ChangeListener l = Test::in|valid;
1632+
}
1633+
}
1634+
""";
1635+
AtomicBoolean called = new AtomicBoolean();
1636+
performTest(code, new UiUtilsCaller() {
1637+
@Override public boolean open(FileObject fo, int pos) {
1638+
return false;
1639+
}
1640+
@Override public boolean open(ClasspathInfo info, ElementHandle<?> el, String fileName) {
1641+
return false;
1642+
}
1643+
@Override public void beep(boolean goToSource, boolean goToJavadoc) {
1644+
fail("Should not be called.");
1645+
}
1646+
@Override public void warnCannotOpen(String displayName) {
1647+
called.set(true);
1648+
}
1649+
}, false, false);
1650+
assertTrue(called.get());
1651+
}
1652+
16231653
private static boolean hasPatterns() {
16241654
try {
16251655
SourceVersion.valueOf("RELEASE_14"); //NOI18N

0 commit comments

Comments
 (0)