Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move the DOM-based search into the javac bundle #1221

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions org.eclipse.jdt.core.javac/fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,12 @@
id="org.eclipse.jdt.core.dom.DOMCompletionEngineProvider">
</resolver>
</extension>
<extension
point="org.eclipse.jdt.core.javaSearchDelegate">
<searchDelegate
class="org.eclipse.jdt.internal.core.search.DOMJavaSearchDelegate"
id="org.eclipse.jdt.internal.core.search.DOMJavaSearchDelegate">
</searchDelegate>
</extension>

</fragment>
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat, Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.jdt.internal.core.search;

import java.util.List;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IParent;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.*;

public class DOMASTNodeUtils {

public static IJavaElement getEnclosingJavaElement(ASTNode node) {
if (node == null) {
return null;
}
if (node instanceof AbstractTypeDeclaration
|| node instanceof MethodDeclaration
|| node instanceof FieldDeclaration
|| node instanceof Initializer
|| node instanceof ImportDeclaration
|| node instanceof CompilationUnit
|| node instanceof AnnotationTypeMemberDeclaration) {
return getDeclaringJavaElement(node);
}
return getEnclosingJavaElement(node.getParent());
}

public static IJavaElement getDeclaringJavaElement(ASTNode key) {
if (key instanceof CompilationUnit unit) {
return unit.getJavaElement();
}
IJavaElement je = findElementForNodeViaDirectBinding(key);
if( je != null ) {
return je;
}
IJavaElement je2 = findElementForNodeCustom(key);
return je2;
}

private static IJavaElement findElementForNodeCustom(ASTNode key) {
if( key instanceof FieldDeclaration fd ) {
List fragments = fd.fragments();
if( fragments.size() > 0 ) {
VariableDeclarationFragment vdf = (VariableDeclarationFragment)fragments.get(0);
if( vdf != null ) {
IJavaElement ret = findElementForNodeViaDirectBinding(vdf);
return ret;
}
}
}
if( key instanceof Initializer i) {
ASTNode parentNode = i.getParent();
int domOccurance = -1;
if( parentNode instanceof AbstractTypeDeclaration typeDecl) {
List parentBody = typeDecl.bodyDeclarations();
for( int z = 0; z < parentBody.size() && domOccurance == -1; z++ ) {
if( parentBody.get(z) == key) {
domOccurance = z + 1;
}
}
}
IJavaElement parentEl = findElementForNodeViaDirectBinding(parentNode);
if( parentEl instanceof IParent parentElement) {
try {
IJavaElement[] kiddos = parentElement.getChildren();
for( int q = 0; q < kiddos.length; q++ ) {
if( kiddos[q] instanceof IMember kiddoMember) {
int count = kiddoMember.getOccurrenceCount();
if( count == domOccurance ) {
return kiddos[q];
}
}
}
} catch( JavaModelException jme) {
// ignore
}
}
}
if( key instanceof ImportDeclaration id) {
ASTNode parentNode = id.getParent();
if( parentNode instanceof CompilationUnit unit) {
IJavaElement parentEl = ((CompilationUnit)id.getParent()).getJavaElement();
return ((org.eclipse.jdt.internal.core.CompilationUnit) parentEl).getImport(id.getName().toString());
}
}
return null;
}

private static IJavaElement findElementForNodeViaDirectBinding(ASTNode key) {
if( key != null ) {
IBinding b = DOMASTNodeUtils.getBinding(key);
if( b != null ) {
IJavaElement el = b.getJavaElement();
return el;
}
}
return null;
}

public static IBinding getBinding(ASTNode astNode) {
if (astNode instanceof Name name) {
return name.resolveBinding();
}
if (astNode instanceof VariableDeclaration variable) {
return variable.resolveBinding();
}
if (astNode instanceof EnumConstantDeclaration enumConstantDeclaration) {
return enumConstantDeclaration.resolveVariable();
}
if (astNode instanceof FieldAccess fieldAcces) {
return fieldAcces.resolveFieldBinding();
}
if (astNode instanceof MethodInvocation method) {
return method.resolveMethodBinding();
}
if (astNode instanceof Type type) {
return type.resolveBinding();
}
if (astNode instanceof AbstractTypeDeclaration type) {
return type.resolveBinding();
}
if (astNode instanceof MethodDeclaration method) {
return method.resolveBinding();
}
if (astNode instanceof SuperFieldAccess superField) {
return superField.resolveFieldBinding();
}
if (astNode instanceof SuperMethodInvocation superMethod) {
return superMethod.resolveMethodBinding();
}
if (astNode instanceof SuperMethodReference superRef) {
return superRef.resolveMethodBinding();
}
if (astNode instanceof SuperConstructorInvocation superRef) {
return superRef.resolveConstructorBinding();
}
if (astNode instanceof MethodRef methodRef) {
return methodRef.resolveBinding();
}
if (astNode instanceof MethodReference methodRef) {
return methodRef.resolveMethodBinding();
}
if (astNode instanceof AnnotationTypeMemberDeclaration methodRef) {
return methodRef.resolveBinding();
}
if (astNode instanceof ClassInstanceCreation ref) {
return ref.resolveConstructorBinding();
}
if (astNode instanceof TypeParameter ref) {
return ref.resolveBinding();
}
// TODO more...
return null;
}

public static boolean insideDocComment(org.eclipse.jdt.core.dom.ASTNode node) {
return node.getRoot() instanceof org.eclipse.jdt.core.dom.CompilationUnit unit &&
((List<Comment>)unit.getCommentList()).stream().anyMatch(comment -> comment.getStartPosition() <= node.getStartPosition() && comment.getStartPosition() + comment.getLength() >= node.getStartPosition() + node.getLength());
}

public static boolean isWithinRange(org.eclipse.jdt.core.dom.ASTNode node, IJavaElement el) {
if( el instanceof ISourceReference isr) {
try {
ISourceRange r = isr.getSourceRange();
if( r != null ) {
int astStart = node.getStartPosition();
int astLen = node.getLength();
int rangeStart = r.getOffset();
int rangeLen = r.getLength();
return astStart >= rangeStart && (astStart + astLen) <= (rangeStart + rangeLen);
}
} catch(JavaModelException jme) {
// Ignore
}
}
return false;
}
}
Loading