下面列出了怎么用com.intellij.psi.util.PsiTreeUtil的API类实例代码及写法,或者点击链接到github查看源代码。
public PsiElement findInside(@Nonnull PsiElement element, int startOffset, int endOffset) {
PsiElement anchor = AbstractFileViewProvider.findElementAt(element, startOffset); // finds child in this tree only, unlike PsiElement.findElementAt()
if (anchor == null && startOffset == element.getTextLength()) {
anchor = PsiTreeUtil.getDeepestLast(element);
}
if (anchor == null) return null;
PsiElement result = findParent(startOffset, endOffset, anchor);
if (endOffset == startOffset) {
while ((result == null || result.getTextRange().getStartOffset() != startOffset) && anchor.getTextRange().getStartOffset() == endOffset) {
anchor = PsiTreeUtil.prevLeaf(anchor, false);
if (anchor == null) break;
result = findParent(startOffset, endOffset, anchor);
}
}
return result;
}
public boolean containsFieldAccessOfEnclosingClass() {
//check for field access like SegmentedTimeline.this.segmentsIncluded
if (getPsiMethod().getBody() == null) {
return false;
}
ExpressionExtractor expressionExtractor = new ExpressionExtractor();
List<PsiExpression> fieldAccesses = expressionExtractor.getVariableInstructions(getPsiMethod().getBody().getStatements());
for (PsiExpression expression : fieldAccesses) {
PsiReferenceExpression fieldReference = (PsiReferenceExpression) expression;
Collection<PsiElement> psiElements = PsiTreeUtil.findChildrenOfType(fieldReference, PsiThisExpression.class);
for (PsiElement thisExpressionElement : psiElements) {
PsiThisExpression thisExpression = (PsiThisExpression) thisExpressionElement;
if (thisExpression.getQualifier() != null) {
return true;
}
}
}
return false;
}
/**
* Find definitions that have been re-exported.
*
* <code>
* module Foo (module Bar, foo) where
* import Bar
* import Baz (foo)
* </code>
*/
private static void findDefinitionNodeInExport(@NotNull Project project, HaskellFile f, @Nullable String name,
@Nullable PsiNamedElement e, List<PsiNamedElement> result) {
List<HaskellPsiUtil.Import> imports = HaskellPsiUtil.parseImports(f);
for (HaskellExport export : PsiTreeUtil.findChildrenOfType(f, HaskellExport.class)) {
boolean exportFn = export.getQvar() != null && export.getQvar().getQvarid() != null
&& export.getQvar().getQvarid().getVarid().getName().equals(name);
String moduleName = exportFn
? getModule(export.getQvar().getQvarid().getConidList())
: export.getModuletoken() != null && export.getQconid() != null ? export.getQconid().getText() : null;
if (!exportFn && moduleName == null) continue;
for (HaskellPsiUtil.Import imprt : imports) {
if (moduleName != null && !moduleName.equals(imprt.module) && !moduleName.equals(imprt.alias)) continue;
boolean hidden = imprt.getHidingNames() != null && ArrayUtil.contains(name, imprt.getHidingNames());
boolean notImported = imprt.getImportedNames() != null && !ArrayUtil.contains(name, imprt.getImportedNames());
if (hidden || notImported) continue;
for (HaskellFile f2 : HaskellModuleIndex.getFilesByModuleName(project, imprt.module, GlobalSearchScope.allScope(project))) {
findDefinitionNode(f2, name, e, result);
findDefinitionNodeInExport(project, f2, name, e, result);
}
}
}
}
@Override
public void actionPerformedImpl(@NotNull final Project project, final Editor editor) {
PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project);
if(file == null) {
return;
}
int offset = editor.getCaretModel().getOffset();
PsiElement psiElement = file.findElementAt(offset);
if(psiElement == null) {
return;
}
PsiLocalVariable psiLocalVariable = PsiTreeUtil.getParentOfType(psiElement, PsiLocalVariable.class);
InflateViewAnnotator.InflateContainer inflateContainer = InflateViewAnnotator.matchInflate(psiLocalVariable);
if(inflateContainer == null) {
return;
}
generate(inflateContainer, editor, file);
}
/**
* This tree walkup method does continue even if a valid definition has been found on an more-inner level.
* Bash is different in regard to the definitions, the most outer definitions count, not the most inner / the first one found.
*
* @param processor
* @param entrance
* @param maxScope
* @param state
* @return
*/
public static boolean varResolveTreeWalkUp(@NotNull final PsiScopeProcessor processor,
@NotNull final BashVar entrance,
@Nullable final PsiElement maxScope,
@NotNull final ResolveState state) {
PsiElement prevParent = entrance;
PsiElement scope = entrance;
boolean hasResult = false;
while (scope != null) {
hasResult |= !scope.processDeclarations(processor, state, prevParent, entrance);
if (scope == maxScope) {
break;
}
prevParent = scope;
scope = PsiTreeUtil.getStubOrPsiParent(prevParent);
}
return !hasResult;
}
@Nullable
private PsiElement resolveAsLoadArgument(
Project project, VirtualFile sourceFile, BuckLoadArgument buckLoadArgument) {
BuckLoadCall buckLoadCall = PsiTreeUtil.getParentOfType(buckLoadArgument, BuckLoadCall.class);
if (buckLoadCall == null) {
return null;
}
BuckTargetLocator buckTargetLocator = BuckTargetLocator.getInstance(project);
return Optional.of(buckLoadCall.getLoadTargetArgument().getString())
.map(BuckString::getValue)
.flatMap(BuckTarget::parse)
.flatMap(target -> buckTargetLocator.resolve(sourceFile, target))
.flatMap(buckTargetLocator::findVirtualFileForExtensionFile)
.map(PsiManager.getInstance(project)::findFile)
.map(
psiFile ->
BuckPsiUtils.findSymbolInPsiTree(psiFile, buckLoadArgument.getString().getValue()))
.orElse(null);
}
@Override
public boolean processDeclarations(@Nonnull PsiScopeProcessor processor,
@Nonnull ResolveState state,
PsiElement lastParent,
@Nonnull PsiElement place)
{
if(lastParent == null || !PsiTreeUtil.isAncestor(this, lastParent, false))
{
return true;
}
for(PsiElement psiElement : getChildren())
{
if(!psiElement.processDeclarations(processor, state, lastParent, place))
{
return false;
}
}
return super.processDeclarations(processor, state, lastParent, place);
}
@RequiredReadAction
@Override
public void process(@Nonnull CSharpResolveOptions options,
@Nonnull DotNetGenericExtractor defaultExtractor,
@Nullable PsiElement forceQualifierElement,
@Nonnull Processor<ResolveResult> processor)
{
DotNetTypeDeclaration thisTypeDeclaration = PsiTreeUtil.getContextOfType(options.getElement(), DotNetTypeDeclaration.class);
if(thisTypeDeclaration != null)
{
thisTypeDeclaration = CSharpCompositeTypeDeclaration.selectCompositeOrSelfType(thisTypeDeclaration);
DotNetGenericExtractor genericExtractor = DotNetGenericExtractor.EMPTY;
int genericParametersCount = thisTypeDeclaration.getGenericParametersCount();
if(genericParametersCount > 0)
{
Map<DotNetGenericParameter, DotNetTypeRef> map = new THashMap<>(genericParametersCount);
for(DotNetGenericParameter genericParameter : thisTypeDeclaration.getGenericParameters())
{
map.put(genericParameter, new CSharpTypeRefFromGenericParameter(genericParameter));
}
genericExtractor = CSharpGenericExtractor.create(map);
}
processor.process(new CSharpResolveResultWithExtractor(thisTypeDeclaration, genericExtractor));
}
}
@Test
public void getAllClassNames() throws IOException {
// Add file to cache
final Project project = testHelper.getFixture().getProject();
final PsiFile file = testHelper.configure("LayoutSpec.java");
ApplicationManager.getApplication()
.invokeAndWait(
() -> {
final ComponentShortNamesCache namesCache = new ComponentShortNamesCache(project);
// Add file to cache
final PsiClass cls = PsiTreeUtil.findChildOfType(file, PsiClass.class);
ComponentsCacheService.getInstance(project).maybeUpdate(cls, false);
final String[] allClassNames = namesCache.getAllClassNames();
assertThat(allClassNames.length).isOne();
assertThat(allClassNames[0]).isEqualTo("Layout");
});
}
private static PsiElement resolveInImportedFiles(PsiFile grammarFile, String ruleName, List<PsiFile> visitedFiles) {
DelegateGrammarsVisitor visitor = new DelegateGrammarsVisitor();
grammarFile.accept(visitor);
for ( PsiFile importedGrammar : visitor.importedGrammars ) {
if ( visitedFiles.contains(importedGrammar) ) {
continue;
}
visitedFiles.add(importedGrammar);
GrammarSpecNode grammar = PsiTreeUtil.getChildOfType(importedGrammar, GrammarSpecNode.class);
PsiElement specNode = MyPsiUtils.findSpecNode(grammar, ruleName);
if ( specNode!=null ) {
return specNode;
}
// maybe the imported grammar also imports other grammars itself?
specNode = resolveInImportedFiles(importedGrammar, ruleName, visitedFiles);
if ( specNode!=null ) {
return specNode;
}
}
return null;
}
@Override
public boolean isCamelExpressionUsedAsPredicate(PsiElement element, String language) {
// xml
XmlTag xml = PsiTreeUtil.getParentOfType(element, XmlTag.class);
if (xml != null) {
// if its coming from the log EIP then its not a predicate
if ("simple".equals(language) && xml.getLocalName().equals("log")) {
return false;
}
// special for loop which can be both expression or predicate
if (getIdeaUtils().hasParentXmlTag(xml, "loop")) {
XmlTag parent = PsiTreeUtil.getParentOfType(xml, XmlTag.class);
if (parent != null) {
String doWhile = parent.getAttributeValue("doWhile");
return "true".equalsIgnoreCase(doWhile);
}
}
return Arrays.stream(PREDICATE_EIPS).anyMatch(n -> getIdeaUtils().hasParentXmlTag(xml, n));
}
return false;
}
@Override
public PsiElement getGotoDeclarationTarget(@Nullable PsiElement source, Editor editor) {
if (source != null && source.getLanguage() instanceof BuckLanguage) {
// The parent type of the element must be BuckValue
BuckValue value = PsiTreeUtil.getParentOfType(source, BuckValue.class);
if (value == null) {
return null;
}
final Project project = editor.getProject();
if (project == null) {
return null;
}
String target = source.getText();
if (target.startsWith("'") && target.endsWith("'")) {
target = target.substring(1, target.length() - 1);
}
VirtualFile targetBuckFile =
BuckBuildUtil.getBuckFileFromAbsoluteTarget(project, target);
if (targetBuckFile == null) {
return null;
}
return PsiManager.getInstance(project).findFile(targetBuckFile);
}
return null;
}
@Override
public boolean isSuppressedFor(@NotNull PsiElement element, @NotNull String toolId) {
if (!toolId.equals("PhpUnused")) {
return false;
}
if (isActionMethod(element)) {
PsiElement classParent = PsiTreeUtil.findFirstParent(element, e -> e instanceof PhpClass);
if (classParent == null) {
return false;
}
return isControllerPhpClass((PhpClass) classParent);
}
if (isControllerClassElement(element)) {
return isControllerPhpClass((PhpClass) element);
}
return false;
}
/**
* Gets all classes in the element.
*
* @param element the Element
* @return the Classes
*/
public static List<PsiClass> getClasses(PsiElement element) {
List<PsiClass> elements = Lists.newArrayList();
List<PsiClass> classElements = PsiTreeUtil.getChildrenOfTypeAsList(element, PsiClass.class);
elements.addAll(classElements);
for (PsiClass classElement : classElements) {
elements.addAll(getClasses(classElement));
}
return elements;
}
@NotNull
private BashWord configureWord(String text) {
PsiFile file = myFixture.configureByText(BashFileType.BASH_FILE_TYPE, text);
BashWord string = PsiTreeUtil.findChildOfType(file, BashWord.class);
Assert.assertNotNull(string);
return string;
}
private PsiAnnotation getBeanInjectAnnotation(PsiElement element) {
if (element instanceof PsiIdentifier && element.getText().equals("BeanInject")) {
PsiAnnotation annotation = PsiTreeUtil.getParentOfType(element, PsiAnnotation.class);
if (annotation != null && CamelIdeaUtils.BEAN_INJECT_ANNOTATION.equals(annotation.getQualifiedName())) {
return annotation;
}
}
return null;
}
public static FileFQN resolveHierarchically(PsiElement psiElement) {
PsiJavaFile psiJavaFile = PsiTreeUtil.getParentOfType(psiElement, PsiJavaFile.class, true);
if (psiJavaFile == null) {
return null;
}
return from((PsiJavaFile) psiJavaFile);
}
public void testEndif() {
FileBase f = parseCode("#if BS then\nx\n#else\ny\n#endif");
PsiDirective e = PsiTreeUtil.findChildOfType(f, PsiDirective.class);
assertNotNull(e);
assertEquals("#if BS then\nx\n#else\ny\n#endif", e.getText());
}
@Nullable
private static ScInfixExpr getContainingInfixExpr(
PsiElement element, Predicate<PsiElement> predicate) {
while (element != null && !predicate.test(element)) {
element = PsiTreeUtil.getParentOfType(element, ScInfixExpr.class);
}
return (ScInfixExpr) element;
}
/**
* @return the only {@link SQFFileScope} instance for this file
*/
@NotNull
public SQFFileScope getFileScope() {
SQFFileScope scope = PsiTreeUtil.findChildOfType(this, SQFFileScope.class);
if (scope == null) {
throw new IllegalStateException("scope shouldn't be null");
}
return scope;
}
public void testFunctorInstantiationChaining() {
PsiFile file = parseCode("module KeyTable = Hashtbl.Make(KeyHash);\ntype infos;");
List<PsiNameIdentifierOwner> expressions = new ArrayList<>(expressions(file));
assertEquals(2, expressions.size());
PsiInnerModule module = (PsiInnerModule) expressions.get(0);
assertNull(module.getBody());
PsiFunctorCall call = PsiTreeUtil.findChildOfType(module, PsiFunctorCall.class);
assertNotNull(call);
assertEquals("Hashtbl.Make(KeyHash)", call.getText());
}
@Override
public void invoke(@NotNull Project project, @NotNull PsiFile psiFile, @Nullable("is null when called from inspection") Editor editor, @NotNull PsiElement element, @NotNull PsiElement end) throws IncorrectOperationException {
JSIndexedPropertyAccessExpression indexed = PsiTreeUtil.getParentOfType(element, JSIndexedPropertyAccessExpression.class);
JSReferenceExpression ref = PsiTreeUtil.findChildOfType(indexed, JSReferenceExpression.class);
JSLiteralExpression literalExpression = (JSLiteralExpression) indexed.getIndexExpression();
String path = StringUtil.stripQuotesAroundValue(literalExpression.getText());
ASTNode dotExp = JSChangeUtil.createStatementFromText(project, ref.getText() + '.' + path);
indexed.replace(dotExp.getPsi());
}
public void testFunctionFun() {
PsiLet e = first(letExpressions(parseCode("let _ = fun (_, info as ei) -> x")));
assertTrue(e.isFunction());
PsiFunction function = e.getFunction();
assertEquals("(_, info as ei)", PsiTreeUtil.findChildOfType(function, PsiParameters.class).getText());
assertEquals("x", function.getBody().getText());
}
static List<NASMIdentifier> findIdentifierReferences(PsiFile containingFile, NASMIdentifier identifier) {
List<NASMIdentifier> result = new ArrayList<>();
PsiElement targetIdentifierId = identifier.getNameIdentifier();
// First check the containing file's identifiers
Collection<NASMIdentifier> nasmIdentifiers = PsiTreeUtil.collectElementsOfType(containingFile, NASMIdentifier.class);
for (NASMIdentifier nasmIdentifier : nasmIdentifiers) {
if (nasmIdentifier != identifier) {
if (targetIdentifierId.getText().equals(nasmIdentifier.getNameIdentifier().getText())) {
result.add(nasmIdentifier);
}
}
}
return result;
}
public void testFunctionPrefixReferenceForPredeclaredNamespace() {
myFixture.configureByFiles("FunctionPrefixReferenceForPredeclaredNamespace.xq");
PsiElement resolvedReference = getTargetOfReferenceAtCaret(myFixture, XQueryPrefix.class);
PsiElement originalElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
XQueryPrefix sourceOfReference = PsiTreeUtil.getParentOfType(originalElement, XQueryPrefix.class);
assertEquals(resolvedReference, sourceOfReference);
}
public static PsiElement createLeafFromText(Project project, PsiElement context,
String text, IElementType type)
{
PsiFileFactoryImpl factory = (PsiFileFactoryImpl)PsiFileFactory.getInstance(project);
PsiElement el = factory.createElementFromText(text,
ANTLRv4Language.INSTANCE,
type,
context);
return PsiTreeUtil.getDeepestFirst(el); // forces parsing of file!!
// start rule depends on root passed in
}
public void testInnerFunction() {
PsiLet e = first(letExpressions(parseCode("let _ = error => Belt.Array.mapU(errors, (. error) => error##message);")));
PsiFunction functionOuter = (PsiFunction) e.getBinding().getFirstChild();
assertEquals("Belt.Array.mapU(errors, (. error) => error##message)", functionOuter.getBody().getText());
PsiFunction functionInner = PsiTreeUtil.findChildOfType(functionOuter, PsiFunction.class);
assertEquals("error##message", functionInner.getBody().getText());
}
public SignalSlotMethodReference(@NotNull ClassConstantReference classConstantReference, @NotNull StringLiteralExpression subject, TextRange range) {
super(subject, range);
this.methodName = subject.getContents();
ClassReference classReference = PsiTreeUtil.findChildOfType(classConstantReference, ClassReference.class);
if (classReference == null || classReference.getFQN() == null) {
classFqn = "";
return;
}
this.classFqn = classReference.getFQN();
}
@Override
public void invoke(@NotNull Project project, @NotNull PsiFile psiFile, @Nullable Editor editor, @NotNull PsiElement psiElement, @NotNull PsiElement psiElement1) {
if(editor == null) {
return;
}
PhpClass phpClass = PhpElementsUtil.getClass(project, expectedClass);
if(phpClass == null) {
return;
}
Collection<ContainerService> suggestions = ServiceUtil.getServiceSuggestionForPhpClass(phpClass, ContainerCollectionResolver.getServices(project));
if(suggestions.size() == 0) {
HintManager.getInstance().showErrorHint(editor, "No suggestion found");
return;
}
XmlTag xmlTag = PsiTreeUtil.getParentOfType(psiElement, XmlTag.class);
if(xmlTag == null) {
return;
}
ServiceSuggestDialog.create(
editor,
ContainerUtil.map(suggestions, ContainerService::getName),
new XmlServiceSuggestIntention.MyInsertCallback(xmlTag)
);
}
/** The text range of our annotation should be based on the element at that offset. */
@Nullable
private TextRange getTextRange(@NotNull PsiFile psiFile) {
final String text = psiFile.getText();
final int offsetStart = getOffsetStart(text);
if (offsetStart == -1) return null;
PsiElement el = PsiTreeUtil.findElementOfClassAtOffset(psiFile, offsetStart, PsiElement.class, false);
if (el == null) return null;
// It's prettier to show the entire import line as unused instead of just the `import` keyword.
if (isUnusedImport && el.getParent() instanceof HaskellImpdecl) return el.getParent().getTextRange();
return el.getTextRange();
}