Skip to content

Commit 41079c7

Browse files
author
Rob Stryker
committed
Move the DOM-based search into the javac bundle
Signed-off-by: Rob Stryker <stryker@redhat.com>
1 parent c906abc commit 41079c7

40 files changed

+3071
-2116
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>

org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DOMASTNodeUtils.java renamed to org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/core/search/DOMASTNodeUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
* SPDX-License-Identifier: EPL-2.0
1010
*******************************************************************************/
11-
package org.eclipse.jdt.internal.core.search.matching;
11+
package org.eclipse.jdt.internal.core.search;
1212

1313
import java.util.List;
1414
import org.eclipse.jdt.core.IJavaElement;

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/core/search/DOMJavaSearchDelegate.java

Lines changed: 354 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
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.function.Function;
14+
15+
import org.eclipse.jdt.core.dom.ASTNode;
16+
import org.eclipse.jdt.core.dom.ASTVisitor;
17+
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
18+
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
19+
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
20+
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
21+
import org.eclipse.jdt.core.dom.CreationReference;
22+
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
23+
import org.eclipse.jdt.core.dom.EnumDeclaration;
24+
import org.eclipse.jdt.core.dom.ExpressionMethodReference;
25+
import org.eclipse.jdt.core.dom.IBinding;
26+
import org.eclipse.jdt.core.dom.ImportDeclaration;
27+
import org.eclipse.jdt.core.dom.IntersectionType;
28+
import org.eclipse.jdt.core.dom.MethodDeclaration;
29+
import org.eclipse.jdt.core.dom.MethodInvocation;
30+
import org.eclipse.jdt.core.dom.Name;
31+
import org.eclipse.jdt.core.dom.NameQualifiedType;
32+
import org.eclipse.jdt.core.dom.ParameterizedType;
33+
import org.eclipse.jdt.core.dom.QualifiedName;
34+
import org.eclipse.jdt.core.dom.QualifiedType;
35+
import org.eclipse.jdt.core.dom.RecordDeclaration;
36+
import org.eclipse.jdt.core.dom.SimpleName;
37+
import org.eclipse.jdt.core.dom.SimpleType;
38+
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
39+
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
40+
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
41+
import org.eclipse.jdt.core.dom.SuperMethodReference;
42+
import org.eclipse.jdt.core.dom.Type;
43+
import org.eclipse.jdt.core.dom.TypeDeclaration;
44+
import org.eclipse.jdt.core.dom.TypeParameter;
45+
import org.eclipse.jdt.core.dom.UnionType;
46+
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
47+
import org.eclipse.jdt.internal.core.search.matching.ConstructorLocator;
48+
import org.eclipse.jdt.internal.core.search.matching.DOMConstructorLocator;
49+
import org.eclipse.jdt.internal.core.search.matching.DOMFieldLocator;
50+
import org.eclipse.jdt.internal.core.search.matching.DOMLocalVariableLocator;
51+
import org.eclipse.jdt.internal.core.search.matching.DOMMethodLocator;
52+
import org.eclipse.jdt.internal.core.search.matching.DOMPackageReferenceLocator;
53+
import org.eclipse.jdt.internal.core.search.matching.DOMPatternLocator;
54+
import org.eclipse.jdt.internal.core.search.matching.DOMSuperTypeReferenceLocator;
55+
import org.eclipse.jdt.internal.core.search.matching.DOMTypeDeclarationLocator;
56+
import org.eclipse.jdt.internal.core.search.matching.DOMTypeParameterLocator;
57+
import org.eclipse.jdt.internal.core.search.matching.DOMTypeReferenceLocator;
58+
import org.eclipse.jdt.internal.core.search.matching.FieldLocator;
59+
import org.eclipse.jdt.internal.core.search.matching.LocalVariableLocator;
60+
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
61+
import org.eclipse.jdt.internal.core.search.matching.MethodLocator;
62+
import org.eclipse.jdt.internal.core.search.matching.NodeSetWrapper;
63+
import org.eclipse.jdt.internal.core.search.matching.PackageReferenceLocator;
64+
import org.eclipse.jdt.internal.core.search.matching.PatternLocator;
65+
import org.eclipse.jdt.internal.core.search.matching.SuperTypeReferenceLocator;
66+
import org.eclipse.jdt.internal.core.search.matching.TypeDeclarationLocator;
67+
import org.eclipse.jdt.internal.core.search.matching.TypeParameterLocator;
68+
import org.eclipse.jdt.internal.core.search.matching.TypeReferenceLocator;
69+
70+
/**
71+
* Visits an AST to feel the possible match with nodes
72+
*/
73+
class PatternLocatorVisitor extends ASTVisitor {
74+
75+
private final PatternLocator patternLocator;
76+
private final NodeSetWrapper nodeSet;
77+
private MatchLocator locator;
78+
79+
public PatternLocatorVisitor(PatternLocator patternLocator, NodeSetWrapper nodeSet, MatchLocator locator) {
80+
super(true);
81+
this.patternLocator = patternLocator;
82+
this.nodeSet = nodeSet;
83+
this.locator = locator;
84+
}
85+
86+
private DOMPatternLocator getWrapper(PatternLocator locator) {
87+
// TODO implement all this.
88+
if( locator instanceof FieldLocator fl) {
89+
return new DOMFieldLocator(fl);
90+
}
91+
if( locator instanceof ConstructorLocator cl) {
92+
return new DOMConstructorLocator(cl);
93+
}
94+
if( locator instanceof LocalVariableLocator lcl) {
95+
return new DOMLocalVariableLocator(lcl);
96+
}
97+
if( locator instanceof MethodLocator ml) {
98+
return new DOMMethodLocator(ml);
99+
}
100+
if( locator instanceof PackageReferenceLocator prl) {
101+
return new DOMPackageReferenceLocator(prl);
102+
}
103+
if( locator instanceof SuperTypeReferenceLocator strl) {
104+
return new DOMSuperTypeReferenceLocator(strl);
105+
}
106+
if( locator instanceof TypeDeclarationLocator tdl) {
107+
return new DOMTypeDeclarationLocator(tdl);
108+
}
109+
if( locator instanceof TypeParameterLocator tpl) {
110+
return new DOMTypeParameterLocator(tpl);
111+
}
112+
if( locator instanceof TypeReferenceLocator trl) {
113+
return new DOMTypeReferenceLocator(trl);
114+
}
115+
return new DOMPatternLocator(null); // stub
116+
}
117+
118+
private <T extends ASTNode> boolean defaultVisitImplementation(T node, Function<T, Integer> levelFunc) {
119+
return defaultVisitImplementationWithFunc(node, levelFunc, DOMASTNodeUtils::getBinding);
120+
}
121+
122+
private <T extends ASTNode> boolean defaultVisitImplementationWithFunc(
123+
T node,
124+
Function<T, Integer> levelFunc,
125+
Function<T, IBinding> bindingFunc) {
126+
int level = levelFunc.apply(node);
127+
if ((level & PatternLocator.MATCH_LEVEL_MASK) == PatternLocator.POSSIBLE_MATCH && (this.nodeSet.getWrapped().mustResolve || this.patternLocator.isMustResolve())) {
128+
level = getWrapper(this.patternLocator).resolveLevel(node, bindingFunc.apply(node), this.locator);
129+
}
130+
this.nodeSet.addMatch(node, level);
131+
return true;
132+
133+
}
134+
135+
136+
@Override
137+
public boolean visit(AnnotationTypeDeclaration node) {
138+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
139+
}
140+
@Override
141+
public boolean visit(TypeParameter node) {
142+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
143+
}
144+
@Override
145+
public boolean visit(MethodDeclaration node) {
146+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
147+
}
148+
@Override
149+
public boolean visit(MethodInvocation node) {
150+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
151+
}
152+
@Override
153+
public boolean visit(ExpressionMethodReference node) {
154+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
155+
}
156+
@Override
157+
public boolean visit(SuperMethodReference node) {
158+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
159+
}
160+
@Override
161+
public boolean visit(SuperMethodInvocation node) {
162+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
163+
}
164+
165+
private boolean visitAbstractTypeDeclaration(AbstractTypeDeclaration node) {
166+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
167+
}
168+
@Override
169+
public boolean visit(EnumDeclaration node) {
170+
return visitAbstractTypeDeclaration(node);
171+
}
172+
@Override
173+
public boolean visit(TypeDeclaration node) {
174+
return visitAbstractTypeDeclaration(node);
175+
}
176+
@Override
177+
public boolean visit(RecordDeclaration node) {
178+
return visitAbstractTypeDeclaration(node);
179+
}
180+
@Override
181+
public boolean visit(AnonymousClassDeclaration node) {
182+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
183+
}
184+
185+
private boolean visitType(Type node) {
186+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
187+
}
188+
@Override
189+
public boolean visit(SimpleType type) {
190+
visitType(type);
191+
Name n = type.getName();
192+
if( n instanceof QualifiedName qn ) {
193+
Name qualifier = qn.getQualifier();
194+
if( qualifier instanceof SimpleName sn1 ) {
195+
visit(sn1);
196+
} else if( qualifier instanceof QualifiedName qn1) {
197+
visit(qn1);
198+
}
199+
}
200+
return false; // No need to visit single name child
201+
}
202+
@Override
203+
public boolean visit(QualifiedType type) {
204+
return visitType(type);
205+
}
206+
@Override
207+
public boolean visit(NameQualifiedType type) {
208+
return visitType(type);
209+
}
210+
@Override
211+
public boolean visit(ParameterizedType node) {
212+
return visitType(node);
213+
}
214+
@Override
215+
public boolean visit(IntersectionType node) {
216+
return visitType(node);
217+
}
218+
@Override
219+
public boolean visit(UnionType node) {
220+
return visitType(node);
221+
}
222+
@Override
223+
public boolean visit(ClassInstanceCreation node) {
224+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
225+
}
226+
@Override
227+
public boolean visit(CreationReference node) {
228+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
229+
}
230+
@Override
231+
public boolean visit(SuperConstructorInvocation node) {
232+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
233+
}
234+
@Override
235+
public boolean visit(SimpleName node) {
236+
if (
237+
node.getLocationInParent() == VariableDeclarationFragment.NAME_PROPERTY ||
238+
node.getLocationInParent() == SingleVariableDeclaration.NAME_PROPERTY ||
239+
node.getLocationInParent() == TypeDeclaration.NAME_PROPERTY ||
240+
node.getLocationInParent() == EnumDeclaration.NAME_PROPERTY ||
241+
node.getLocationInParent() == MethodDeclaration.NAME_PROPERTY) {
242+
return false; // skip as parent was most likely already matched
243+
}
244+
int level = getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator);
245+
if ((level & PatternLocator.MATCH_LEVEL_MASK) == PatternLocator.POSSIBLE_MATCH && (this.nodeSet.getWrapped().mustResolve || this.patternLocator.isMustResolve())) {
246+
IBinding b = node.resolveBinding();
247+
level = getWrapper(this.patternLocator).resolveLevel(node, b, this.locator);
248+
}
249+
this.nodeSet.addMatch(node, level);
250+
return level == 0;
251+
}
252+
@Override
253+
public boolean visit(VariableDeclarationFragment node) {
254+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
255+
}
256+
@Override
257+
public boolean visit(SingleVariableDeclaration node) {
258+
return defaultVisitImplementation(node, x -> getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator));
259+
}
260+
@Override
261+
public boolean visit(EnumConstantDeclaration node) {
262+
int level = getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator);
263+
if ((level & PatternLocator.MATCH_LEVEL_MASK) == PatternLocator.POSSIBLE_MATCH && (this.nodeSet.getWrapped().mustResolve || this.patternLocator.isMustResolve())) {
264+
int l1 = getWrapper(this.patternLocator).resolveLevel(node, node.resolveVariable(), this.locator);
265+
int l2 = getWrapper(this.patternLocator).resolveLevel(node, node.resolveConstructorBinding(), this.locator);
266+
level = Math.max(l1, l2);
267+
}
268+
this.nodeSet.addMatch(node, level);
269+
return true;
270+
}
271+
@Override
272+
public boolean visit(QualifiedName node) {
273+
if (node.getLocationInParent() == SimpleType.NAME_PROPERTY) {
274+
return false; // type was already checked
275+
}
276+
int level = getWrapper(this.patternLocator).match(node, this.nodeSet, this.locator);
277+
if ((level & PatternLocator.MATCH_LEVEL_MASK) == PatternLocator.POSSIBLE_MATCH && (this.nodeSet.getWrapped().mustResolve || this.patternLocator.isMustResolve())) {
278+
level = getWrapper(this.patternLocator).resolveLevel(node, node.resolveBinding(), this.locator);
279+
}
280+
this.nodeSet.addMatch(node, level);
281+
if( (level & PatternLocator.MATCH_LEVEL_MASK) == PatternLocator.IMPOSSIBLE_MATCH ) {
282+
return true;
283+
}
284+
return false;
285+
}
286+
287+
@Override
288+
public boolean visit(ImportDeclaration node) {
289+
return true;
290+
}
291+
}

0 commit comments

Comments
 (0)