use of com.intellij.psi.search.PsiElementProcessor in project intellij-elixir by KronicDeth.
the class Builder method buildFoldRegions.
/*
* Instance Methods
*/
/**
* Builds the folding regions for the specified node in the AST tree and its children.
*
* @param root the element for which folding is requested.
* @param document the document for which folding is built. Can be used to retrieve line
* numbers for folding regions.
* @param quick whether the result should be provided as soon as possible. Is true, when
* an editor is opened and we need to auto-fold something immediately, like Java imports.
* If true, one should perform no reference resolving and avoid complex checks if possible.
* @return the array of folding descriptors.
*/
@NotNull
@Override
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, final boolean quick) {
final List<FoldingDescriptor> foldingDescriptorList = new ArrayList<FoldingDescriptor>();
PsiTreeUtil.processElements(root, new PsiElementProcessor() {
private Map<String, FoldingGroup> foldingGroupByModuleAttributeName = new HashMap<String, FoldingGroup>();
/*
*
* Instance Methods
*
*/
/*
* Public Instance Methods
*/
@Override
public boolean execute(@NotNull PsiElement element) {
boolean keepProcessing = true;
if (element instanceof AtNonNumericOperation) {
keepProcessing = execute((AtNonNumericOperation) element);
} else if (element instanceof AtUnqualifiedNoParenthesesCall) {
keepProcessing = execute((AtUnqualifiedNoParenthesesCall) element);
} else if (element instanceof ElixirDoBlock) {
keepProcessing = execute((ElixirDoBlock) element);
} else if (element instanceof ElixirStabOperation) {
keepProcessing = execute((ElixirStabOperation) element);
} else if (element instanceof Call) {
keepProcessing = execute((Call) element);
}
return keepProcessing;
}
/*
* Private Instance Methods
*/
private boolean execute(@NotNull AtNonNumericOperation atNonNumericOperation) {
boolean keepProcessing = true;
if (!quick) {
keepProcessing = slowExecute(atNonNumericOperation);
}
return keepProcessing;
}
private boolean execute(@NotNull AtUnqualifiedNoParenthesesCall atUnqualifiedNoParenthesesCall) {
String moduleAttributeName = moduleAttributeName(atUnqualifiedNoParenthesesCall);
String name = moduleAttributeName.substring(1);
if (ModuleAttribute.isDocumentationName(name)) {
ElixirNoParenthesesOneArgument noParenthesesOneArgument = atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument();
foldingDescriptorList.add(new NamedFoldingDescriptor(noParenthesesOneArgument.getNode(), noParenthesesOneArgument.getTextRange(), null, "\"...\""));
} else if (ModuleAttribute.isTypeName(name)) {
ElixirNoParenthesesOneArgument noParenthesesOneArgument = atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument();
PsiElement[] children = noParenthesesOneArgument.getChildren();
if (children.length == 1) {
PsiElement child = children[0];
if (child instanceof Type) {
Type type = (Type) child;
PsiElement rightOperand = Normalized.rightOperand(type);
if (rightOperand != null) {
foldingDescriptorList.add(new NamedFoldingDescriptor(rightOperand.getNode(), rightOperand.getTextRange(), null, "..."));
}
}
}
}
return true;
}
private boolean execute(@NotNull Call call) {
for (String resolvedFunctionName : RESOLVED_FUNCTION_NAMES) {
if (call.isCalling(KERNEL, resolvedFunctionName)) {
if (isFirstInGroup(call, KERNEL, resolvedFunctionName)) {
Call last = lastInGroup(call, KERNEL, resolvedFunctionName);
PsiElement[] finalArguments = finalArguments(call);
if (finalArguments != null && finalArguments.length >= 1) {
TextRange textRange = new TextRange(finalArguments[0].getTextOffset(), last.getTextRange().getEndOffset());
foldingDescriptorList.add(new NamedFoldingDescriptor(call.getParent().getNode(), textRange, null, "..."));
}
}
}
}
return true;
}
private boolean execute(@NotNull ElixirDoBlock doBlock) {
foldingDescriptorList.add(new FoldingDescriptor(doBlock, doBlock.getTextRange()));
return true;
}
private boolean execute(@NotNull ElixirStabOperation stabOperation) {
int startOffset = stabOperation.operator().getTextOffset();
int endOffset = stabOperation.getTextRange().getEndOffset();
TextRange textRange = new TextRange(startOffset, endOffset);
foldingDescriptorList.add(new FoldingDescriptor(stabOperation, textRange));
return true;
}
private boolean isFirstInGroup(@NotNull Call call, @NotNull String resolvedModuleName, @NotNull String resolvedFunctionName) {
PsiElement previousSiblingExpression = previousSiblingExpression(call);
boolean first = true;
if (previousSiblingExpression instanceof Call) {
Call previousSiblingExpressionCall = (Call) previousSiblingExpression;
first = !previousSiblingExpressionCall.isCalling(resolvedModuleName, resolvedFunctionName);
}
return first;
}
@NotNull
private Call lastInGroup(@NotNull Call first, @NotNull String resolvedModuleName, @NotNull String resolvedFunctionName) {
PsiElement expression = first;
Call last = first;
while (true) {
expression = nextSiblingExpression(expression);
if (expression instanceof Call) {
Call call = (Call) expression;
if (call.isCalling(resolvedModuleName, resolvedFunctionName)) {
last = call;
continue;
}
}
break;
}
return last;
}
private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation) {
boolean keepProcessing = true;
PsiReference reference = atNonNumericOperation.getReference();
if (reference != null) {
keepProcessing = slowExecute(atNonNumericOperation, reference);
}
return keepProcessing;
}
private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull final AtUnqualifiedNoParenthesesCall atUnqualifiedNoParenthesesCall) {
return slowExecute(atNonNumericOperation, atUnqualifiedNoParenthesesCall, atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument().getText());
}
private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiElement target) {
boolean keepProcessing = true;
if (target instanceof AtUnqualifiedNoParenthesesCall) {
keepProcessing = slowExecute(atNonNumericOperation, (AtUnqualifiedNoParenthesesCall) target);
} else if (target instanceof QualifiableAlias) {
keepProcessing = slowExecute(atNonNumericOperation, (QualifiableAlias) target);
}
return keepProcessing;
}
private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiReference reference) {
PsiElement target = reference.resolve();
boolean keepProcessing = true;
if (target != null) {
keepProcessing = slowExecute(atNonNumericOperation, target);
}
return keepProcessing;
}
private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull final QualifiableAlias qualifiableAlias) {
return slowExecute(atNonNumericOperation, qualifiableAlias, qualifiableAlias.getName());
}
private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiElement element, @Nullable final String placeHolderText) {
String moduleAttributeName = atNonNumericOperation.moduleAttributeName();
FoldingGroup foldingGroup = foldingGroupByModuleAttributeName.get(moduleAttributeName);
if (foldingGroup == null) {
foldingGroup = FoldingGroup.newGroup(moduleAttributeName);
foldingGroupByModuleAttributeName.put(moduleAttributeName, foldingGroup);
}
foldingDescriptorList.add(new FoldingDescriptor(atNonNumericOperation.getNode(), atNonNumericOperation.getTextRange(), foldingGroup, Collections.<Object>singleton(element)) {
@Nullable
@Override
public String getPlaceholderText() {
return placeHolderText;
}
});
return true;
}
});
return foldingDescriptorList.toArray(new FoldingDescriptor[foldingDescriptorList.size()]);
}
use of com.intellij.psi.search.PsiElementProcessor in project intellij-community by JetBrains.
the class LocalToFieldHandler method convertLocalToField.
public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) {
boolean tempIsStatic = myIsConstant;
PsiElement parent = local.getParent();
final List<PsiClass> classes = new ArrayList<>();
while (parent != null && parent.getContainingFile() != null) {
if (parent instanceof PsiClass && !(myIsConstant && parent instanceof PsiAnonymousClass)) {
classes.add((PsiClass) parent);
}
if (parent instanceof PsiFile && FileTypeUtils.isInServerPageFile(parent)) {
String message = RefactoringBundle.message("error.not.supported.for.jsp", REFACTORING_NAME);
CommonRefactoringUtil.showErrorHint(myProject, editor, message, REFACTORING_NAME, HelpID.LOCAL_TO_FIELD);
return false;
}
if (parent instanceof PsiModifierListOwner && ((PsiModifierListOwner) parent).hasModifierProperty(PsiModifier.STATIC)) {
tempIsStatic = true;
}
parent = parent.getParent();
}
if (classes.isEmpty())
return false;
final AbstractInplaceIntroducer activeIntroducer = AbstractInplaceIntroducer.getActiveIntroducer(editor);
final boolean shouldSuggestDialog = activeIntroducer instanceof InplaceIntroduceConstantPopup && activeIntroducer.startsOnTheSameElement(null, local);
if (classes.size() == 1 || ApplicationManager.getApplication().isUnitTestMode() || shouldSuggestDialog) {
if (convertLocalToField(local, classes.get(getChosenClassIndex(classes)), editor, tempIsStatic))
return false;
} else {
final boolean isStatic = tempIsStatic;
final PsiClass firstClass = classes.get(0);
final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, firstClass);
NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(), "Choose class to introduce " + (myIsConstant ? "constant" : "field"), new PsiElementProcessor<PsiClass>() {
@Override
public boolean execute(@NotNull PsiClass aClass) {
AnonymousTargetClassPreselectionUtil.rememberSelection(aClass, aClass);
convertLocalToField(local, aClass, editor, isStatic);
return false;
}
}, preselection).showInBestPositionFor(editor);
}
return true;
}
use of com.intellij.psi.search.PsiElementProcessor in project intellij-community by JetBrains.
the class GrHighlightUtil method collectReassignedNames.
private static Set<String> collectReassignedNames(PsiElement scope) {
final Set<String> result = ContainerUtil.newHashSet();
PsiTreeUtil.processElements(scope, new PsiElementProcessor() {
@Override
public boolean execute(@NotNull PsiElement element) {
if (!(element instanceof GrReferenceExpression) || !((GrReferenceExpression) element).isQualified()) {
return true;
}
GrReferenceExpression ref = (GrReferenceExpression) element;
if (isWriteAccess(ref)) {
String varName = ref.getReferenceName();
if (!result.contains(varName)) {
PsiElement target = ref.resolve();
if (target instanceof GrVariable && ((GrVariable) target).getInitializerGroovy() != null || target instanceof GrParameter) {
result.add(varName);
}
}
}
return true;
}
});
return result;
}
use of com.intellij.psi.search.PsiElementProcessor in project intellij-community by JetBrains.
the class ElementProcessor method processExternalFile.
public void processExternalFile(PsiFile psiFile, XmlTag place) {
final XmlDocument document = ((XmlFile) psiFile).getDocument();
assert document != null;
final XmlTag rootTag = document.getRootTag();
assert rootTag != null;
myInclude++;
try {
rootTag.processElements(new PsiElementProcessor() {
public boolean execute(@NotNull PsiElement element) {
if (element instanceof XmlTag) {
return process((XmlTag) element);
}
return shouldContinue();
}
}, place);
} finally {
myInclude--;
}
}
use of com.intellij.psi.search.PsiElementProcessor in project intellij-community by JetBrains.
the class XsltCodeInsightUtil method findFirstRealTagChild.
@Nullable
public static PsiElement findFirstRealTagChild(@NotNull XmlTag xmlTag) {
final PsiElement[] child = new PsiElement[1];
xmlTag.processElements(new PsiElementProcessor() {
public boolean execute(@NotNull PsiElement element) {
if (element instanceof XmlToken) {
if (((XmlToken) element).getTokenType() == XmlTokenType.XML_TAG_END) {
child[0] = element.getNextSibling();
return false;
}
}
return true;
}
}, xmlTag);
return child[0];
}
Aggregations