forked from eclipse-jdt/eclipse.jdt.core
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move the DOM-based search into the javac bundle
Signed-off-by: Rob Stryker <[email protected]>
- Loading branch information
Rob Stryker
committed
Feb 7, 2025
1 parent
8b6d476
commit cd5f0e1
Showing
16 changed files
with
2,825 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
190 changes: 190 additions & 0 deletions
190
org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/core/search/DOMASTNodeUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
Oops, something went wrong.