use of com.intellij.lang.folding.FoldingDescriptor in project intellij-plugins by JetBrains.
the class DartFoldingBuilder method foldMultilineStrings.
private static void foldMultilineStrings(@NotNull final List<FoldingDescriptor> descriptors, @NotNull final Collection<PsiElement> psiElements) {
for (PsiElement element : psiElements) {
if (element instanceof DartStringLiteralExpression) {
DartStringLiteralExpression dartString = (DartStringLiteralExpression) element;
PsiElement child = dartString.getFirstChild();
if (child == null)
continue;
IElementType type = child.getNode().getElementType();
if (type == DartTokenTypes.RAW_TRIPLE_QUOTED_STRING || (type == DartTokenTypes.OPEN_QUOTE && child.getTextLength() == 3)) {
descriptors.add(new FoldingDescriptor(dartString, dartString.getTextRange()));
}
}
}
}
use of com.intellij.lang.folding.FoldingDescriptor in project intellij-plugins by JetBrains.
the class DartFoldingBuilder method foldComments.
private static void foldComments(@NotNull final List<FoldingDescriptor> descriptors, @NotNull final Collection<PsiElement> psiElements, @Nullable final TextRange fileHeaderRange) {
PsiElement psiElement;
for (Iterator<PsiElement> iter = psiElements.iterator(); iter.hasNext(); ) {
psiElement = iter.next();
if (!(psiElement instanceof PsiComment)) {
continue;
}
if (fileHeaderRange != null && fileHeaderRange.intersects(psiElement.getTextRange())) {
continue;
}
final IElementType elementType = psiElement.getNode().getElementType();
if ((elementType == DartTokenTypesSets.MULTI_LINE_DOC_COMMENT || elementType == DartTokenTypesSets.MULTI_LINE_COMMENT) && !isCustomRegionElement(psiElement)) {
descriptors.add(new FoldingDescriptor(psiElement, psiElement.getTextRange()));
} else if (elementType == DartTokenTypesSets.SINGLE_LINE_DOC_COMMENT || elementType == DartTokenTypesSets.SINGLE_LINE_COMMENT) {
final PsiElement firstCommentInSequence = psiElement;
PsiElement lastCommentInSequence = firstCommentInSequence;
PsiElement nextElement = firstCommentInSequence;
boolean containsCustomRegionMarker = isCustomRegionElement(nextElement);
while (iter.hasNext() && (nextElement = nextElement.getNextSibling()) != null && (nextElement instanceof PsiWhiteSpace || nextElement.getNode().getElementType() == elementType)) {
if (nextElement.getNode().getElementType() == elementType) {
// advance iterator to skip processed comments sequence
iter.next();
lastCommentInSequence = nextElement;
containsCustomRegionMarker |= isCustomRegionElement(nextElement);
}
}
if (lastCommentInSequence != firstCommentInSequence && !containsCustomRegionMarker) {
final TextRange range = TextRange.create(firstCommentInSequence.getTextRange().getStartOffset(), lastCommentInSequence.getTextRange().getEndOffset());
descriptors.add(new FoldingDescriptor(firstCommentInSequence, range));
}
}
}
}
use of com.intellij.lang.folding.FoldingDescriptor in project intellij-plugins by JetBrains.
the class HbFoldingBuilder method appendDescriptors.
private void appendDescriptors(PsiElement psi, List<FoldingDescriptor> descriptors, Document document) {
if (isSingleLine(psi, document)) {
return;
}
if (HbTokenTypes.COMMENT == psi.getNode().getElementType()) {
ASTNode commentNode = psi.getNode();
String commentText = commentNode.getText();
// tags before we allow folding
if (commentText.length() > 6 && commentText.substring(0, 3).equals("{{!") && commentText.substring(commentText.length() - 2, commentText.length()).equals("}}")) {
TextRange range = new TextRange(commentNode.getTextRange().getStartOffset() + 3, commentNode.getTextRange().getEndOffset() - 2);
descriptors.add(new FoldingDescriptor(commentNode, range));
}
}
if (psi instanceof HbBlockWrapper) {
PsiElement endOpenBlockStache = getOpenBlockCloseStacheElement(psi.getFirstChild());
PsiElement endCloseBlockStache = getCloseBlockCloseStacheElement(psi.getLastChild());
// if we've got a well formed block with the open and close elems we need, define a region to fold
if (endOpenBlockStache != null && endCloseBlockStache != null) {
int endOfFirstOpenStacheLine = document.getLineEndOffset(document.getLineNumber(psi.getTextRange().getStartOffset()));
// we set the start of the text we'll fold to be just before the close braces of the open stache,
// or, if the open stache spans multiple lines, to the end of the first line
int foldingRangeStartOffset = Math.min(endOpenBlockStache.getTextRange().getStartOffset(), endOfFirstOpenStacheLine);
// we set the end of the text we'll fold to be just before the final close braces in this block
int foldingRangeEndOffset = endCloseBlockStache.getTextRange().getStartOffset();
TextRange range = new TextRange(foldingRangeStartOffset, foldingRangeEndOffset);
descriptors.add(new FoldingDescriptor(psi, range));
}
}
PsiElement child = psi.getFirstChild();
while (child != null) {
appendDescriptors(child, descriptors, document);
child = child.getNextSibling();
}
}
use of com.intellij.lang.folding.FoldingDescriptor 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.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.
the class JsonFoldingBuilder method collectDescriptorsRecursively.
private static void collectDescriptorsRecursively(@NotNull ASTNode node, @NotNull Document document, @NotNull List<FoldingDescriptor> descriptors) {
final IElementType type = node.getElementType();
if ((type == JsonElementTypes.OBJECT || type == JsonElementTypes.ARRAY) && spanMultipleLines(node, document)) {
descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
} else if (type == JsonElementTypes.BLOCK_COMMENT) {
descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
} else if (type == JsonElementTypes.LINE_COMMENT) {
final Couple<PsiElement> commentRange = expandLineCommentsRange(node.getPsi());
final int startOffset = commentRange.getFirst().getTextRange().getStartOffset();
final int endOffset = commentRange.getSecond().getTextRange().getEndOffset();
if (document.getLineNumber(startOffset) != document.getLineNumber(endOffset)) {
descriptors.add(new FoldingDescriptor(node, new TextRange(startOffset, endOffset)));
}
}
for (ASTNode child : node.getChildren(null)) {
collectDescriptorsRecursively(child, document, descriptors);
}
}
Aggregations