Skip to content

Commit 10fe71a

Browse files
mickaelistriaRob Stryker
authored andcommitted
Make MatchLocator capable of working with DOM
Extra strategy in MatchLocator to use DOM, and tweaks in various Locators to properly handle DOM. Tests in JavaSearchTests help a lot (currently ~130/270 passing) It basically clones and adapt some methods and adapt them to DOM, A new flag is introduced to decide the strategy. Done-ish (often with remaining issues) * FieldLocator * LocalVariableLocator * MethodLocator * SuperTypeReferenceLocator * TypeDeclarationLocator * TypeParameterLocator * TypeReferenceLocator TODO: * AndLocator * ModuleLocator * PackageDeclarationLocator * PackageReferenceLocator * OrLocator * VariableLocator Make some match locator work with DOM Fix NPE, convert 4 errors to fails Signed-off-by: Rob Stryker <[email protected]> Handle match files in the order they arrived Signed-off-by: Rob Stryker <[email protected]> Fix testBug251827b and 5 others - import declarations java element must be found Signed-off-by: Rob Stryker <[email protected]> Move the DOM-based search into the javac bundle Signed-off-by: Rob Stryker <[email protected]> Cleanup Signed-off-by: Rob Stryker <[email protected]> Move the DOM-based search into the javac bundle Signed-off-by: Rob Stryker <[email protected]>
1 parent 9cfa61a commit 10fe71a

23 files changed

+2858
-9
lines changed

org.eclipse.jdt.core.javac/fragment.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,12 @@
1515
id="org.eclipse.jdt.core.dom.DOMCompletionEngineProvider">
1616
</resolver>
1717
</extension>
18+
<extension
19+
point="org.eclipse.jdt.core.javaSearchDelegate">
20+
<searchDelegate
21+
class="org.eclipse.jdt.internal.core.search.DOMJavaSearchDelegate"
22+
id="org.eclipse.jdt.internal.core.search.DOMJavaSearchDelegate">
23+
</searchDelegate>
24+
</extension>
1825

1926
</fragment>
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2023 Red Hat, Inc. and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
package org.eclipse.jdt.internal.core.search;
12+
13+
import java.util.List;
14+
import org.eclipse.jdt.core.IJavaElement;
15+
import org.eclipse.jdt.core.IMember;
16+
import org.eclipse.jdt.core.IParent;
17+
import org.eclipse.jdt.core.ISourceRange;
18+
import org.eclipse.jdt.core.ISourceReference;
19+
import org.eclipse.jdt.core.JavaModelException;
20+
import org.eclipse.jdt.core.dom.*;
21+
22+
public class DOMASTNodeUtils {
23+
24+
public static IJavaElement getEnclosingJavaElement(ASTNode node) {
25+
if (node == null) {
26+
return null;
27+
}
28+
if (node instanceof AbstractTypeDeclaration
29+
|| node instanceof MethodDeclaration
30+
|| node instanceof FieldDeclaration
31+
|| node instanceof Initializer
32+
|| node instanceof ImportDeclaration
33+
|| node instanceof CompilationUnit
34+
|| node instanceof AnnotationTypeMemberDeclaration) {
35+
return getDeclaringJavaElement(node);
36+
}
37+
return getEnclosingJavaElement(node.getParent());
38+
}
39+
40+
public static IJavaElement getDeclaringJavaElement(ASTNode key) {
41+
if (key instanceof CompilationUnit unit) {
42+
return unit.getJavaElement();
43+
}
44+
IJavaElement je = findElementForNodeViaDirectBinding(key);
45+
if( je != null ) {
46+
return je;
47+
}
48+
IJavaElement je2 = findElementForNodeCustom(key);
49+
return je2;
50+
}
51+
52+
private static IJavaElement findElementForNodeCustom(ASTNode key) {
53+
if( key instanceof FieldDeclaration fd ) {
54+
List fragments = fd.fragments();
55+
if( fragments.size() > 0 ) {
56+
VariableDeclarationFragment vdf = (VariableDeclarationFragment)fragments.get(0);
57+
if( vdf != null ) {
58+
IJavaElement ret = findElementForNodeViaDirectBinding(vdf);
59+
return ret;
60+
}
61+
}
62+
}
63+
if( key instanceof Initializer i) {
64+
ASTNode parentNode = i.getParent();
65+
int domOccurance = -1;
66+
if( parentNode instanceof AbstractTypeDeclaration typeDecl) {
67+
List parentBody = typeDecl.bodyDeclarations();
68+
for( int z = 0; z < parentBody.size() && domOccurance == -1; z++ ) {
69+
if( parentBody.get(z) == key) {
70+
domOccurance = z + 1;
71+
}
72+
}
73+
}
74+
IJavaElement parentEl = findElementForNodeViaDirectBinding(parentNode);
75+
if( parentEl instanceof IParent parentElement) {
76+
try {
77+
IJavaElement[] kiddos = parentElement.getChildren();
78+
for( int q = 0; q < kiddos.length; q++ ) {
79+
if( kiddos[q] instanceof IMember kiddoMember) {
80+
int count = kiddoMember.getOccurrenceCount();
81+
if( count == domOccurance ) {
82+
return kiddos[q];
83+
}
84+
}
85+
}
86+
} catch( JavaModelException jme) {
87+
// ignore
88+
}
89+
}
90+
}
91+
if( key instanceof ImportDeclaration id) {
92+
ASTNode parentNode = id.getParent();
93+
if( parentNode instanceof CompilationUnit unit) {
94+
IJavaElement parentEl = ((CompilationUnit)id.getParent()).getJavaElement();
95+
return ((org.eclipse.jdt.internal.core.CompilationUnit) parentEl).getImport(id.getName().toString());
96+
}
97+
}
98+
return null;
99+
}
100+
101+
private static IJavaElement findElementForNodeViaDirectBinding(ASTNode key) {
102+
if( key != null ) {
103+
IBinding b = DOMASTNodeUtils.getBinding(key);
104+
if( b != null ) {
105+
IJavaElement el = b.getJavaElement();
106+
return el;
107+
}
108+
}
109+
return null;
110+
}
111+
112+
public static IBinding getBinding(ASTNode astNode) {
113+
if (astNode instanceof Name name) {
114+
return name.resolveBinding();
115+
}
116+
if (astNode instanceof VariableDeclaration variable) {
117+
return variable.resolveBinding();
118+
}
119+
if (astNode instanceof EnumConstantDeclaration enumConstantDeclaration) {
120+
return enumConstantDeclaration.resolveVariable();
121+
}
122+
if (astNode instanceof FieldAccess fieldAcces) {
123+
return fieldAcces.resolveFieldBinding();
124+
}
125+
if (astNode instanceof MethodInvocation method) {
126+
return method.resolveMethodBinding();
127+
}
128+
if (astNode instanceof Type type) {
129+
return type.resolveBinding();
130+
}
131+
if (astNode instanceof AbstractTypeDeclaration type) {
132+
return type.resolveBinding();
133+
}
134+
if (astNode instanceof MethodDeclaration method) {
135+
return method.resolveBinding();
136+
}
137+
if (astNode instanceof SuperFieldAccess superField) {
138+
return superField.resolveFieldBinding();
139+
}
140+
if (astNode instanceof SuperMethodInvocation superMethod) {
141+
return superMethod.resolveMethodBinding();
142+
}
143+
if (astNode instanceof SuperMethodReference superRef) {
144+
return superRef.resolveMethodBinding();
145+
}
146+
if (astNode instanceof SuperConstructorInvocation superRef) {
147+
return superRef.resolveConstructorBinding();
148+
}
149+
if (astNode instanceof MethodRef methodRef) {
150+
return methodRef.resolveBinding();
151+
}
152+
if (astNode instanceof MethodReference methodRef) {
153+
return methodRef.resolveMethodBinding();
154+
}
155+
if (astNode instanceof AnnotationTypeMemberDeclaration methodRef) {
156+
return methodRef.resolveBinding();
157+
}
158+
if (astNode instanceof ClassInstanceCreation ref) {
159+
return ref.resolveConstructorBinding();
160+
}
161+
if (astNode instanceof TypeParameter ref) {
162+
return ref.resolveBinding();
163+
}
164+
// TODO more...
165+
return null;
166+
}
167+
168+
public static boolean insideDocComment(org.eclipse.jdt.core.dom.ASTNode node) {
169+
return node.getRoot() instanceof org.eclipse.jdt.core.dom.CompilationUnit unit &&
170+
((List<Comment>)unit.getCommentList()).stream().anyMatch(comment -> comment.getStartPosition() <= node.getStartPosition() && comment.getStartPosition() + comment.getLength() >= node.getStartPosition() + node.getLength());
171+
}
172+
173+
public static boolean isWithinRange(org.eclipse.jdt.core.dom.ASTNode node, IJavaElement el) {
174+
if( el instanceof ISourceReference isr) {
175+
try {
176+
ISourceRange r = isr.getSourceRange();
177+
if( r != null ) {
178+
int astStart = node.getStartPosition();
179+
int astLen = node.getLength();
180+
int rangeStart = r.getOffset();
181+
int rangeLen = r.getLength();
182+
return astStart >= rangeStart && (astStart + astLen) <= (rangeStart + rangeLen);
183+
}
184+
} catch(JavaModelException jme) {
185+
// Ignore
186+
}
187+
}
188+
return false;
189+
}
190+
}

0 commit comments

Comments
 (0)