下面列出了com.intellij.psi.util.PsiTreeUtil#collectElements ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static List<String> loadImportedTags(@NotNull XmlFile file, @NotNull XmlTag context) {
// PsiElement[] arr = file.getRootTag().getChildren();
// Collection<HtmlTag> tags = PsiTreeUtil.findChildrenOfType(file, HtmlTag.class);
PsiElement[] reqTags = PsiTreeUtil.collectElements(file, new PsiElementFilter() {
@Override
public boolean isAccepted(PsiElement element) {
return element instanceof HtmlTag && (((HtmlTag) element).getName().equals(RTTagDescriptorsProvider.RT_REQUIRE) || ((HtmlTag) element).getName().equals(RTTagDescriptorsProvider.RT_IMPORT));
}
});
List<String> importedTags = new ArrayList<String>();
for (PsiElement elem : reqTags) {
String as = ((HtmlTag) elem).getAttributeValue("as");
if (!Strings.isNullOrEmpty(as)) {
importedTags.add(as);
}
}
return importedTags;
}
@Nullable
public static PsiElement[] getMethodParameterReferences(Method method, int parameterIndex) {
// we dont have a parameter on resolved method
Parameter[] parameters = method.getParameters();
if(parameters.length == 0 || parameterIndex >= parameters.length) {
return null;
}
final String tempVariableName = parameters[parameterIndex].getName();
return PsiTreeUtil.collectElements(method.getLastChild(), new PsiElementFilter() {
@Override
public boolean isAccepted(PsiElement element) {
return element instanceof Variable && tempVariableName.equals(((Variable) element).getName());
}
});
}
/**
* Performs search in all modules that are included in specified class. So
* if ruby-class contains explicit includes:
*
* include Admin::MyModule
* include Concerns::Logging
*
* the specified methodName will be searched in both modules in order
* of their declaration.
*
* @param ctrlClass Class to look for modules.
* @param methodName Method name to search within modules of specified ruby
* class
* @return First method which name matches methodName
*/
@Nullable
private static RMethod findMethodInClassModules(RClass ctrlClass, String methodName) {
PsiElement[] elements = PsiTreeUtil.collectElements(ctrlClass,
INCLUDE_MODULE_FILTER);
// Iterate from the end of the list as next included module can override
// same-named methods of previously included module.
int i = elements.length;
while (--i >= 0) {
RCall includeMethodCall = (RCall)elements[i];
RPsiElement moduleNameArg = includeMethodCall.getArguments().get(0);
if (moduleNameArg == null)
continue;
RContainer cont = findClassOrModule(moduleNameArg.getText(),
ctrlClass.getProject());
if (cont instanceof RModule)
return RubyPsiUtil.getMethodWithPossibleZeroArgsByName(cont, methodName);
}
return null;
}
public static MethodReference[] getFormBuilderTypes(Method method) {
List<MethodReference> methodReferences = new ArrayList<>();
PsiTreeUtil.collectElements(method, methodReference -> {
if (methodReference instanceof MethodReference) {
String methodName = ((MethodReference) methodReference).getName();
if (methodName != null && (methodName.equals("add") || methodName.equals("create"))) {
if(PhpElementsUtil.isMethodReferenceInstanceOf((MethodReference) methodReference, FormUtil.PHP_FORM_BUILDER_SIGNATURES)) {
methodReferences.add((MethodReference) methodReference);
return true;
}
}
}
return false;
});
return methodReferences.toArray(new MethodReference[methodReferences.size()]);
}
private void attachTemplateFoldingDescriptors(PsiElement psiElement, List<FoldingDescriptor> descriptors) {
// find path calls in file
PsiElement[] fileReferences = PsiTreeUtil.collectElements(psiElement, psiElement1 ->
TwigPattern.getTemplateFileReferenceTagPattern().accepts(psiElement1) || TwigPattern.getFormThemeFileTagPattern().accepts(psiElement1)
);
if(fileReferences.length == 0) {
return;
}
for(PsiElement fileReference: fileReferences) {
final String templateShortcutName = TwigUtil.getFoldingTemplateName(fileReference.getText());
if(templateShortcutName != null) {
descriptors.add(new FoldingDescriptor(fileReference.getNode(),
new TextRange(fileReference.getTextRange().getStartOffset(), fileReference.getTextRange().getEndOffset())) {
@Override
public String getPlaceholderText() {
return templateShortcutName;
}
});
}
}
}
/**
* Remove TODO; moved to core
*/
@Deprecated
@NotNull
public static String findEol(@NotNull PsiElement psiElement) {
for(PsiElement child: YamlHelper.getChildrenFix(psiElement)) {
if(PlatformPatterns.psiElement(YAMLTokenTypes.EOL).accepts(child)) {
return child.getText();
}
}
PsiElement[] indentPsiElements = PsiTreeUtil.collectElements(psiElement.getContainingFile(), element ->
PlatformPatterns.psiElement(YAMLTokenTypes.EOL).accepts(element)
);
if(indentPsiElements.length > 0) {
return indentPsiElements[0].getText();
}
return "\n";
}
/**
* Finds the first {@link RuleSpecNode} or {@link ModeSpecNode} matching the {@code ruleName} defined in
* the given {@code grammar}.
*
* Rule specs can be either children of the {@link RulesNode}, or under one of the {@code mode}s defined in
* the grammar. This means we have to walk the whole grammar to find matching candidates.
*/
public static PsiElement findSpecNode(GrammarSpecNode grammar, final String ruleName) {
PsiElementFilter definitionFilter = new PsiElementFilter() {
@Override
public boolean isAccepted(PsiElement element1) {
if (!(element1 instanceof RuleSpecNode)) {
return false;
}
GrammarElementRefNode id = ((RuleSpecNode) element1).getId();
return id != null && id.getText().equals(ruleName);
}
};
PsiElement[] ruleSpec = PsiTreeUtil.collectElements(grammar, definitionFilter);
if (ruleSpec.length > 0) {
return ruleSpec[0];
}
return null;
}
public static PsiElement[] collectAtActions(PsiElement root, final String tokenText) {
return PsiTreeUtil.collectElements(root, new PsiElementFilter() {
@Override
public boolean isAccepted(PsiElement element) {
PsiElement p = element.getContext();
if (p != null) p = p.getContext();
return p instanceof AtAction &&
element instanceof ParserRuleRefNode &&
element.getText().equals(tokenText);
}
});
}
public static PsiElement[] collectNodesWithText(PsiElement root, final String text) {
return PsiTreeUtil.collectElements(root, new PsiElementFilter() {
@Override
public boolean isAccepted(PsiElement element) {
return element.getText().equals(text);
}
});
}
@Nullable
public static PsiElement[] getMethodParameterReferences(Method method, int parameterIndex) {
// we dont have a parameter on resolved method
Parameter[] parameters = method.getParameters();
if(parameters.length == 0 || parameterIndex >= parameters.length) {
return null;
}
final String tempVariableName = parameters[parameterIndex].getName();
return PsiTreeUtil.collectElements(method.getLastChild(), element -> element instanceof Variable && tempVariableName.equals(((Variable) element).getName()));
}
@Nullable
public static PsiElement[] getMethodParameterReferences(Method method, int parameterIndex) {
// we dont have a parameter on resolved method
Parameter[] parameters = method.getParameters();
if(parameters.length == 0 || parameterIndex >= parameters.length) {
return null;
}
final String tempVariableName = parameters[parameterIndex].getName();
return PsiTreeUtil.collectElements(method.getLastChild(), element -> element instanceof Variable && tempVariableName.equals(((Variable) element).getName()));
}
public static PsiElement[] findChildrenOfType(PsiElement startingElement, final IElementType elementType) {
return PsiTreeUtil.collectElements(startingElement, new PsiElementFilter() {
@Override
public boolean isAccepted(PsiElement element) {
return element.getNode() != null && element.getNode().getElementType() == elementType;
}
});
}
public PsiElement[] getParameterLists() {
if(parameterLists != null) {
return parameterLists;
}
return parameterLists = PsiTreeUtil.collectElements(method, psiElement ->
psiElement.getParent() instanceof ParameterList
);
}
/** Search all internal and leaf nodes looking for token or internal node
* with specific text.
* This saves having to create lots of java classes just to identify psi nodes.
*/
public static PsiElement[] collectNodesWithName(PsiElement root, final String tokenText) {
return PsiTreeUtil.collectElements(root, new PsiElementFilter() {
@Override
public boolean isAccepted(PsiElement element) {
String tokenTypeName = element.getNode().getElementType().toString();
return tokenTypeName.equals(tokenText);
}
});
}
private void attachConstantFoldingDescriptors(PsiElement psiElement, List<FoldingDescriptor> descriptors) {
// find path calls in file
PsiElement[] constantReferences = PsiTreeUtil.collectElements(psiElement, psiElement1 ->
TwigPattern.getPrintBlockOrTagFunctionPattern("constant").accepts(psiElement1)
);
if(constantReferences.length == 0) {
return;
}
for(PsiElement fileReference: constantReferences) {
String contents = fileReference.getText();
if(StringUtils.isNotBlank(contents) && contents.contains(":")) {
final String[] parts = contents.split("::");
if(parts.length == 2) {
descriptors.add(new FoldingDescriptor(fileReference.getNode(),
new TextRange(fileReference.getTextRange().getStartOffset(), fileReference.getTextRange().getEndOffset())) {
@Nullable
@Override
public String getPlaceholderText() {
return parts[1];
}
});
}
}
}
}
@NotNull
public static PsiElement[] getMethodParameterReferences(@NotNull Method method, int parameterIndex) {
// we dont have a parameter on resolved method
Parameter[] parameters = method.getParameters();
if(parameters.length == 0 || parameterIndex >= parameters.length) {
return new PsiElement[0];
}
String tempVariableName = parameters[parameterIndex].getName();
return PsiTreeUtil.collectElements(method.getLastChild(), element ->
element instanceof Variable && tempVariableName.equals(((Variable) element).getName())
);
}
private void visitAnnotationDocTag(@NotNull PhpDocTag phpDocTag, @NotNull ProblemsHolder holder, @NotNull AnnotationInspectionUtil.LazyNamespaceImportResolver lazyUseImporterCollector) {
for (PsiElement element : PsiTreeUtil.collectElements(phpDocTag, psiElement -> psiElement.getNode().getElementType() == PhpDocTokenTypes.DOC_STATIC)) {
PsiElement nextSibling = element.getNextSibling();
if (nextSibling == null || nextSibling.getNode().getElementType() != PhpDocTokenTypes.DOC_IDENTIFIER || !"class".equals(nextSibling.getText())) {
continue;
}
PsiElement prevSibling = element.getPrevSibling();
if (prevSibling == null) {
return;
}
String namespaceForDocIdentifier = PhpDocUtil.getNamespaceForDocIdentifier(prevSibling);
if (namespaceForDocIdentifier == null) {
return;
}
String clazz = AnnotationInspectionUtil.getClassFqnString(namespaceForDocIdentifier, lazyUseImporterCollector);
if (clazz == null) {
return;
}
PhpClass classInterface = PhpElementsUtil.getClassInterface(phpDocTag.getProject(), clazz);
if (classInterface == null) {
holder.registerProblem(
nextSibling,
MESSAGE,
ProblemHighlightType.GENERIC_ERROR_OR_WARNING
);
}
}
}
/**
* Like PsiTreeUtil.findChildrenOfType, except no collection is created and it doesnt use recursion.
* @param parent the element whose children will be searched
* @param types the types to search for
* @return an iterable that will traverse the psi tree depth-first, including only the elements
* whose type is contained in the provided tokenset.
*/
public static Iterable<PsiElement> findChildrenOfType(final PsiElement parent, final TokenSet types) {
PsiElement[] psiElements = PsiTreeUtil.collectElements(parent, new PsiElementFilter() {
@Override
public boolean isAccepted(PsiElement input) {
if ( input==null ) return false;
ASTNode node = input.getNode();
if ( node==null ) return false;
return types.contains(node.getElementType());
}
});
return Arrays.asList(psiElements);
}
private void visitAnnotationDocTag(@NotNull PhpDocTag phpDocTag, @NotNull ProblemsHolder holder, @NotNull AnnotationInspectionUtil.LazyNamespaceImportResolver lazyUseImporterCollector) {
for (PsiElement element : PsiTreeUtil.collectElements(phpDocTag, psiElement -> psiElement.getNode().getElementType() == PhpDocTokenTypes.DOC_STATIC)) {
PsiElement nextSibling = element.getNextSibling();
if (nextSibling == null || nextSibling.getNode().getElementType() != PhpDocTokenTypes.DOC_IDENTIFIER) {
continue;
}
PsiElement prevSibling = element.getPrevSibling();
if (prevSibling == null) {
return;
}
String namespaceForDocIdentifier = PhpDocUtil.getNamespaceForDocIdentifier(prevSibling);
if (namespaceForDocIdentifier == null) {
return;
}
String clazz = AnnotationInspectionUtil.getClassFqnString(namespaceForDocIdentifier, lazyUseImporterCollector);
if (clazz == null) {
return;
}
PhpClass phpClass = PhpElementsUtil.getClassInterface(phpDocTag.getProject(), clazz);
if (phpClass == null) {
return;
}
// ::class direct class access
String text = nextSibling.getText();
if ("class".equals(text)) {
if (phpClass.isDeprecated()) {
holder.registerProblem(
nextSibling,
MESSAGE,
ProblemHighlightType.LIKE_DEPRECATED
);
}
return;
}
// ::CONST fetch the field
Field fieldByName = phpClass.findFieldByName(text, true);
if (fieldByName != null && fieldByName.isConstant() && fieldByName.isDeprecated()) {
holder.registerProblem(
nextSibling,
MESSAGE,
ProblemHighlightType.LIKE_DEPRECATED
);
}
}
}
@NotNull
private List<PsiElement> collectPsiElementsRecursive(@NotNull PsiElement psiElement) {
PsiElement[] psiElements = PsiTreeUtil.collectElements(psiElement.getContainingFile(), e -> true);
return Arrays.asList(psiElements);
}