Skip to content

Commit 7dca8c4

Browse files
subyssurendran666SougandhS
authored andcommitted
Fix NPE in Navigate to declaration + Support for lambda
Variable Navigation throwing NPE and support for variable navigation in lambda for non-java projects Fix: #712
1 parent 4e55929 commit 7dca8c4

File tree

1 file changed

+103
-18
lines changed

1 file changed

+103
-18
lines changed

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/NavigateToVarDeclAction.java

Lines changed: 103 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@
2323
import org.eclipse.debug.internal.ui.DebugUIPlugin;
2424
import org.eclipse.debug.ui.DebugUITools;
2525
import org.eclipse.jdt.core.ICompilationUnit;
26+
import org.eclipse.jdt.core.IJavaElement;
2627
import org.eclipse.jdt.core.IJavaProject;
28+
import org.eclipse.jdt.core.IOrdinaryClassFile;
2729
import org.eclipse.jdt.core.IType;
2830
import org.eclipse.jdt.core.JavaCore;
2931
import org.eclipse.jdt.core.dom.AST;
3032
import org.eclipse.jdt.core.dom.ASTParser;
3133
import org.eclipse.jdt.core.dom.ASTVisitor;
3234
import org.eclipse.jdt.core.dom.CompilationUnit;
35+
import org.eclipse.jdt.core.dom.LambdaExpression;
3336
import org.eclipse.jdt.core.dom.MethodDeclaration;
3437
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
3538
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
@@ -42,10 +45,14 @@
4245
import org.eclipse.jface.text.IRegion;
4346
import org.eclipse.jface.viewers.IStructuredSelection;
4447
import org.eclipse.ui.IEditorPart;
48+
import org.eclipse.ui.IWorkbenchWindow;
49+
import org.eclipse.ui.PlatformUI;
4550
import org.eclipse.ui.texteditor.IDocumentProvider;
4651
import org.eclipse.ui.texteditor.ITextEditor;
4752

4853
public class NavigateToVarDeclAction extends ObjectActionDelegate {
54+
55+
private IType iTypeGlobal;
4956
@Override
5057
public void run(IAction action) {
5158
IStructuredSelection selection = getCurrentSelection();
@@ -58,10 +65,22 @@ public void run(IAction action) {
5865
Object frame = DebugUITools.getDebugContext();
5966
if (frame instanceof IStackFrame jFrame) {
6067
if (jFrame instanceof IJavaStackFrame javaStackFrame) {
68+
IJavaProject iJavaProject = null;
6169
String type = javaStackFrame.getLaunch().getLaunchConfiguration().getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String) null);
62-
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(type);
63-
IJavaProject iJavaProject = JavaCore.create(project);
70+
if (type == null) {
71+
for (IJavaProject proj : JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaProjects()) {
72+
IType type2 = proj.findType(javaStackFrame.getDeclaringTypeName());
73+
if (type2 != null && type2.exists()) {
74+
iJavaProject = proj;
75+
}
76+
}
77+
}
78+
if (iJavaProject == null && type != null) {
79+
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(type);
80+
iJavaProject = JavaCore.create(project);
81+
}
6482
IType iType = iJavaProject.findType(javaStackFrame.getReceivingTypeName());
83+
int currentLine = javaStackFrame.getLineNumber();
6584
String currentMethod = javaStackFrame.getMethodName();
6685
List<String> frameParams = javaStackFrame.getArgumentTypeNames();
6786
List<String> ref = frameParams.stream().map(e -> {
@@ -71,48 +90,111 @@ public void run(IAction action) {
7190
}
7291
return e;
7392
}).collect(Collectors.toList());
74-
ICompilationUnit cu = iType.getCompilationUnit();
75-
ASTParser parse = ASTParser.newParser(AST.getJLSLatest());
76-
parse.setSource(cu);
77-
parse.setKind(ASTParser.K_COMPILATION_UNIT);
78-
parse.setResolveBindings(true);
79-
CompilationUnit ast = (CompilationUnit) parse.createAST(null);
93+
ICompilationUnit cu;
94+
if (iType == null) {
95+
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
96+
IEditorPart editor = window.getActivePage().getActiveEditor();
97+
IJavaElement element = JavaUI.getEditorInputJavaElement(editor.getEditorInput());
98+
cu = (element instanceof ICompilationUnit cuElement) ? cuElement : null;
99+
} else {
100+
cu = iType.getCompilationUnit();
101+
}
102+
ASTParser parser = ASTParser.newParser(AST.getJLSLatest());
103+
if (cu == null) {
104+
IOrdinaryClassFile classFile = iType.getClassFile();
105+
if (classFile != null && classFile.getSource() != null) {
106+
String source = classFile.getSource();
107+
parser.setSource(source.toCharArray());
108+
parser.setKind(ASTParser.K_COMPILATION_UNIT);
109+
iTypeGlobal = iType;
110+
}
111+
} else {
112+
parser.setSource(cu);
113+
parser.setKind(ASTParser.K_COMPILATION_UNIT);
114+
parser.setResolveBindings(true);
115+
}
116+
CompilationUnit ast = (CompilationUnit) parser.createAST(null);
80117
ast.accept(new ASTVisitor() {
81118
boolean meth = false;
82119
boolean found = false;
120+
boolean inTargetContext = false;
83121
@Override
84122
public boolean visit(MethodDeclaration node) {
85123
if (node.getName().getIdentifier().equals(currentMethod)) {
86124
List<Object> parameters = node.parameters();
87125
List<String> methodParams = parameters.stream().map(p -> ((SingleVariableDeclaration) p).getType().toString()).toList();
88-
if (methodParams.equals(ref)) {
89-
meth = true;
90-
for (Object op : node.parameters()) {
91-
SingleVariableDeclaration parm = (SingleVariableDeclaration) op;
92-
if (parm.getName().getIdentifier().equals(name)) {
93-
highlightLine(ast, cu, node.getStartPosition());
94-
found = true;
95-
return false;
126+
int start = node.getStartPosition();
127+
int end = start + node.getLength();
128+
int startLine = ast.getLineNumber(start);
129+
int endLine = ast.getLineNumber(end);
130+
if (currentLine >= startLine && currentLine <= endLine) {
131+
inTargetContext = true;
132+
if (methodParams.equals(ref)) {
133+
meth = true;
134+
for (Object op : node.parameters()) {
135+
SingleVariableDeclaration parm = (SingleVariableDeclaration) op;
136+
if (parm.getName().getIdentifier().equals(name)) {
137+
highlightLine(ast, cu, parm.getStartPosition());
138+
found = true;
139+
return false;
140+
}
96141
}
142+
return true;
97143
}
98-
return true;
99144
}
100145
}
101146
return true;
102147
}
103148

149+
@Override
150+
public void endVisit(MethodDeclaration node) {
151+
inTargetContext = false;
152+
}
153+
104154
@Override
105155
public boolean visit(VariableDeclarationFragment node) {
106156
if (found) {
107157
return false;
108158
}
109-
if (meth && node.getName().getIdentifier().equals(name)) {
159+
if ((meth || inTargetContext) && node.getName().getIdentifier().equals(name)) {
110160
found = true;
111161
highlightLine(ast, cu, node.getStartPosition());
112162
return false;
113163
}
114164
return true;
115165
}
166+
167+
@Override
168+
public boolean visit(LambdaExpression node) {
169+
if (found) {
170+
return false;
171+
}
172+
List<Object> parameters = node.parameters();
173+
int start = node.getStartPosition();
174+
int end = start + node.getLength();
175+
int startLine = ast.getLineNumber(start);
176+
int endLine = ast.getLineNumber(end);
177+
if (currentLine >= startLine && currentLine <= endLine) {
178+
inTargetContext = true;
179+
for (Object param : parameters) {
180+
if (param instanceof SingleVariableDeclaration) {
181+
SingleVariableDeclaration svd = (SingleVariableDeclaration) param;
182+
if (svd.getName().getIdentifier().equals(name)) {
183+
highlightLine(ast, cu, svd.getStartPosition());
184+
found = true;
185+
return false;
186+
}
187+
}
188+
}
189+
}
190+
return true;
191+
192+
}
193+
194+
@Override
195+
public void endVisit(LambdaExpression node) {
196+
inTargetContext = false;
197+
}
116198
});
117199
}
118200
}
@@ -136,6 +218,9 @@ private void highlightLine(CompilationUnit ast, ICompilationUnit cu, int startPo
136218
int line = ast.getLineNumber(startPos);
137219
try {
138220
IEditorPart editor = JavaUI.openInEditor(cu);
221+
if (editor == null) {
222+
editor = JavaUI.openInEditor(iTypeGlobal.getClassFile());
223+
}
139224
if (editor instanceof ITextEditor txtEd) {
140225
IDocumentProvider prov = txtEd.getDocumentProvider();
141226
IDocument doc = prov.getDocument(txtEd.getEditorInput());

0 commit comments

Comments
 (0)