@Nullable public static PsiElement skipSiblingsBackwardByPredicate( @Nullable PsiElement element, Predicate<PsiElement> elementsToSkip) { if (element == null) return null; for (PsiElement e = element.getPrevSibling(); e != null; e = e.getPrevSibling()) { if (elementsToSkip.apply(e)) continue; return e; } return null; }
private static int findClosingBrace(GrTypeDefinitionBody block, int startOffset) { PsiElement rbrace = block.getRBrace(); if (rbrace == null) return block.getTextRange().getEndOffset(); while (PsiImplUtil.isWhiteSpace(rbrace.getPrevSibling()) && rbrace.getPrevSibling().getTextRange().getStartOffset() > startOffset) { rbrace = rbrace.getPrevSibling(); } return rbrace.getTextRange().getStartOffset(); }
private static int calcStartReformatOffset(@NotNull PsiElement element) { int result = element.getTextRange().getStartOffset(); for (PsiElement e = element.getPrevSibling(); e != null; e = e.getPrevSibling()) { if (e instanceof PsiWhiteSpace) { result = e.getTextRange().getStartOffset(); } else { break; } } return result; }
protected static PsiElement adjustSibling( @NotNull Editor editor, @NotNull LineRange sourceRange, @NotNull MoveInfo info, boolean down) { PsiElement element = down ? sourceRange.lastElement : sourceRange.firstElement; PsiElement sibling = down ? element.getNextSibling() : element.getPrevSibling(); PsiElement whiteSpaceTestSubject = sibling; if (sibling == null) { PsiElement parent = element.getParent(); if (parent != null && isBracelessBlock(parent)) { whiteSpaceTestSubject = down ? parent.getNextSibling() : parent.getPrevSibling(); } } if (whiteSpaceTestSubject instanceof PsiWhiteSpace) { if (getElementLineCount(whiteSpaceTestSubject, editor) > 1) { int nearLine = down ? sourceRange.endLine : sourceRange.startLine - 1; info.toMove = sourceRange; info.toMove2 = new LineRange(nearLine, nearLine + 1); info.indentTarget = false; return null; } if (sibling != null) { sibling = firstNonWhiteElement(sibling, down); } } if (sibling == null) { JetCallExpression callExpression = PsiTreeUtil.getParentOfType(element, JetCallExpression.class); if (callExpression != null) { JetBlockExpression dslBlock = getDSLLambdaBlock(callExpression, down); if (PsiTreeUtil.isAncestor(dslBlock, element, false)) { //noinspection ConstantConditions PsiElement blockParent = dslBlock.getParent(); return down ? JetPsiUtil.findChildByType(blockParent, JetTokens.RBRACE) : JetPsiUtil.findChildByType(blockParent, JetTokens.LBRACE); } } info.toMove2 = null; return null; } return sibling; }
@Nullable public static <T extends PsiElement> T getPrevSiblingOfType( @Nullable PsiElement sibling, ElementPattern<T> pattern) { if (sibling == null) return null; for (PsiElement child = sibling.getPrevSibling(); child != null; child = child.getPrevSibling()) { if (pattern.accepts(child)) { //noinspection unchecked return (T) child; } } return null; }
public static boolean processChildren( PsiElement element, PsiScopeProcessor processor, ResolveState substitutor, PsiElement lastParent, PsiElement place) { PsiElement run = lastParent == null ? element.getLastChild() : lastParent.getPrevSibling(); while (run != null) { if (PsiTreeUtil.findCommonParent(place, run) != run && !run.processDeclarations(processor, substitutor, null, place)) return false; run = run.getPrevSibling(); } return true; }
@Override public void visitClassInitializer(PsiClassInitializer initializer) { JavaElementArrangementEntry entry = createNewEntry(initializer, initializer.getTextRange(), FIELD, null, true); if (entry == null) { return; } PsiElement classLBrace = null; PsiClass clazz = initializer.getContainingClass(); if (clazz != null) { classLBrace = clazz.getLBrace(); } for (PsiElement e = initializer.getPrevSibling(); e != null; e = e.getPrevSibling()) { JavaElementArrangementEntry prevEntry; if (e == classLBrace) { prevEntry = myEntries.get(clazz); } else { prevEntry = myEntries.get(e); } if (prevEntry != null) { entry.addDependency(prevEntry); } if (!(e instanceof PsiWhiteSpace)) { break; } } }
private static boolean statementCanBePlacedAlong(final PsiElement element) { if (element instanceof JspTemplateStatement) { PsiElement neighbour = element.getPrevSibling(); // we can place statement inside scriptlet only return neighbour != null && !(neighbour instanceof JspTemplateStatement); } if (element instanceof PsiBlockStatement) return false; final PsiElement parent = element.getParent(); if (parent instanceof JspClassLevelDeclarationStatement) return false; if (parent instanceof PsiCodeBlock) return true; if (parent instanceof PsiIfStatement && (element == ((PsiIfStatement) parent).getThenBranch() || element == ((PsiIfStatement) parent).getElseBranch())) { return true; } if (parent instanceof PsiWhileStatement && element == ((PsiWhileStatement) parent).getBody()) { return true; } if (parent instanceof PsiDoWhileStatement && element == ((PsiDoWhileStatement) parent).getBody()) { return true; } // know nothing about that return false; }
private boolean fieldGroupEnded(PsiElement psi) { if (!mySettings.ALIGN_GROUP_FIELD_DECLARATIONS) return true; PsiElement prevSibling = psi.getPrevSibling(); return prevSibling != null && StringUtil.countChars(prevSibling.getText(), '\n') >= mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS; }
private void calculateAlignments(List<ASTNode> children, boolean classLevel) { List<GrStatement> currentGroup = null; boolean spock = true; for (ASTNode child : children) { PsiElement psi = child.getPsi(); if (psi instanceof GrLabeledStatement) { alignGroup(currentGroup, spock, classLevel); currentGroup = ContainerUtil.newArrayList((GrStatement) psi); spock = true; } else if (currentGroup != null && spock && isTablePart(psi)) { currentGroup.add((GrStatement) psi); } else if (psi instanceof GrVariableDeclaration) { GrVariable[] variables = ((GrVariableDeclaration) psi).getVariables(); if (variables.length > 0) { if (!classLevel || currentGroup == null || fieldGroupEnded(psi) || spock) { alignGroup(currentGroup, spock, classLevel); currentGroup = ContainerUtil.newArrayList(); spock = false; } currentGroup.add((GrStatement) psi); } } else { if (psi instanceof PsiComment) { PsiElement prev = psi.getPrevSibling(); if (prev != null && prev.getNode().getElementType() != mNLS || classLevel && !fieldGroupEnded(psi)) { continue; } } alignGroup(currentGroup, spock, classLevel); currentGroup = null; } } }
@Nullable private static JetBlockExpression findClosestBlock( @NotNull PsiElement anchor, boolean down, boolean strict) { PsiElement current = PsiTreeUtil.getParentOfType(anchor, JetBlockExpression.class, strict); while (current != null) { PsiElement parent = current.getParent(); if (parent instanceof JetClassBody || parent instanceof JetClassInitializer || parent instanceof JetNamedFunction || (parent instanceof JetProperty && !((JetProperty) parent).isLocal())) { return null; } if (parent instanceof JetBlockExpression) return (JetBlockExpression) parent; PsiElement sibling = down ? current.getNextSibling() : current.getPrevSibling(); if (sibling != null) { //noinspection unchecked JetBlockExpression block = (JetBlockExpression) JetPsiUtil.getOutermostDescendantElement(sibling, down, CHECK_BLOCK); if (block != null) return block; current = sibling; } else { current = parent; } } return null; }
public void extractFromCodeBlock(GrCodeBlock block, PsiElement from) throws IncorrectOperationException { if (block == null) return; PsiElement rBrace = block.getRBrace(); PsiElement lBrace = block.getLBrace(); PsiElement firstBodyElement; if (lBrace == null) { firstBodyElement = null; } else { firstBodyElement = lBrace.getNextSibling(); if (firstBodyElement == rBrace) { firstBodyElement = null; } } PsiElement lastBodyElement; if (rBrace == null) { lastBodyElement = null; } else { lastBodyElement = rBrace.getPrevSibling(); if (lastBodyElement == lBrace) { lastBodyElement = null; } } extract(firstBodyElement, lastBodyElement, from); }
private static boolean isTagStartOrEnd(@Nullable PsiElement element) { if (element == null) return false; final IElementType type = element.getNode().getElementType(); if (type == XmlTokenType.XML_NAME) return isTagStartOrEnd(element.getNextSibling()) || isTagStartOrEnd(element.getPrevSibling()); return type == XmlTokenType.XML_START_TAG_START || type == XmlTokenType.XML_END_TAG_START || type == XmlTokenType.XML_TAG_END; }
public static boolean enumEntryAfterEnumMember(@NotNull JetEnumEntry enumEntry) { PsiElement previous = enumEntry.getPrevSibling(); while (previous != null) { if (previous instanceof JetEnumEntry) return false; if (previous instanceof JetDeclaration) return true; previous = previous.getPrevSibling(); } return false; }
@NotNull @Override public ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters) { // 1. Do not automatically insert completion for first reference expression in block inside // function literal if it has no parameters yet. // 2. The same but for the case when first expression is additionally surrounded with brackets PsiElement position = parameters.getPosition(); JetFunctionLiteralExpression functionLiteral = PsiTreeUtil.getParentOfType(position, JetFunctionLiteralExpression.class); if (functionLiteral != null) { PsiElement expectedReference = position.getParent(); if (expectedReference instanceof JetSimpleNameExpression) { if (PsiTreeUtil.findChildOfType(functionLiteral, JetParameterList.class) == null) { { // 1. PsiElement expectedBlock = expectedReference.getParent(); if (expectedBlock instanceof JetBlockExpression) { if (expectedReference.getPrevSibling() == null) { return ThreeState.NO; } } } { // 2. PsiElement expectedParenthesized = expectedReference.getParent(); if (expectedParenthesized instanceof JetParenthesizedExpression) { PsiElement expectedBlock = expectedParenthesized.getParent(); if (expectedBlock instanceof JetBlockExpression) { if (expectedParenthesized.getPrevSibling() == null) { return ThreeState.NO; } } } } } } } return ThreeState.UNSURE; }
@Nullable public static PsiElement realPrevious(PsiElement previousLeaf) { while (previousLeaf != null && (previousLeaf instanceof PsiWhiteSpace || previousLeaf instanceof PsiComment || previousLeaf instanceof PsiErrorElement)) { previousLeaf = previousLeaf.getPrevSibling(); } return previousLeaf; }
public static String getPrevSiblingAsTextUntil( PsiElement psiElement, ElementPattern pattern, boolean includeMatching) { String prevText = ""; for (PsiElement child = psiElement.getPrevSibling(); child != null; child = child.getPrevSibling()) { if (pattern.accepts(child)) { if (includeMatching) { return child.getText() + prevText; } return prevText; } else { prevText = child.getText() + prevText; } } return prevText; }
@Override public String getContinuosText() // fixme some caching here would be nice; Also we now could implement // smarter logic { StringBuilder builder = new StringBuilder(""); PsiElement currentElement = this; while (currentElement.getPrevSibling() instanceof PerlStringContentElement) { currentElement = currentElement.getPrevSibling(); } while (currentElement instanceof PerlStringContentElement) { builder.append(currentElement.getNode().getText()); currentElement = currentElement.getNextSibling(); } return builder.toString(); }
public static <T extends PsiElement> void setQualifier( @NotNull GrQualifiedReference<T> ref, @Nullable T newQualifier) { final T oldQualifier = ref.getQualifier(); final ASTNode node = ref.getNode(); final PsiElement refNameElement = ref.getReferenceNameElement(); if (newQualifier == null) { if (oldQualifier != null && refNameElement != null) { ref.deleteChildRange(ref.getFirstChild(), refNameElement.getPrevSibling()); } } else { if (oldQualifier == null) { if (refNameElement != null) { node.addLeaf(mDOT, ".", refNameElement.getNode()); ref.addBefore(newQualifier, refNameElement.getPrevSibling()); } } else { oldQualifier.replace(newQualifier); } } }
public GLSLElement findPrevSiblingByClasses(Class<? extends GLSLElement>... clazzes) { PsiElement prev = getPrevSibling(); while (prev != null) { for (Class<? extends GLSLElement> clazz : clazzes) { if (clazz.isInstance(prev)) { return clazz.cast(prev); } } prev = prev.getPrevSibling(); } return null; }
@Nullable @Override public LineMarkerInfo getLineMarkerInfo(@NotNull final PsiElement element) { if (myDaemonSettings.SHOW_METHOD_SEPARATORS) { if (element instanceof DartMethodDeclaration || element instanceof DartFunctionDeclarationWithBody || element instanceof DartFunctionDeclarationWithBodyOrNative || element instanceof DartGetterDeclaration || element instanceof DartSetterDeclaration || element instanceof DartFactoryConstructorDeclaration || element instanceof AbstractDartMethodDeclarationImpl || element instanceof DartNamedConstructorDeclaration || element instanceof DartIncompleteDeclaration) { PsiElement markerLocation = element; while (markerLocation.getPrevSibling() != null && (markerLocation.getPrevSibling() instanceof PsiComment || (markerLocation.getPrevSibling() instanceof PsiWhiteSpace && markerLocation.getPrevSibling().getPrevSibling() != null && markerLocation.getPrevSibling().getPrevSibling() instanceof PsiComment))) { markerLocation = markerLocation.getPrevSibling(); } LineMarkerInfo info = new LineMarkerInfo<PsiElement>( markerLocation, markerLocation.getTextRange(), null, Pass.UPDATE_ALL, FunctionUtil.<Object, String>nullConstant(), null, GutterIconRenderer.Alignment.RIGHT); EditorColorsScheme scheme = myColorsManager.getGlobalScheme(); info.separatorColor = scheme.getColor(CodeInsightColors.METHOD_SEPARATORS_COLOR); info.separatorPlacement = SeparatorPlacement.TOP; return info; } } return null; }
private static PsiElement skipWhiteSpacesAndStopOnDoc(PsiElement element, boolean forward) { while (true) { element = forward ? element.getNextSibling() : element.getPrevSibling(); if (element == null) break; final ASTNode node = element.getNode(); if (node == null) break; if (GroovyDocElementTypes.GROOVY_DOC_COMMENT.equals(node.getElementType()) || !TokenSets.WHITE_SPACES_OR_COMMENTS.contains(node.getElementType())) { break; } } return element; }
@Override public void visitXmlToken(XmlToken token) { IElementType tokenType = token.getTokenType(); if (tokenType == XmlTokenType.XML_NAME || tokenType == XmlTokenType.XML_TAG_NAME) { PsiElement element = token.getPrevSibling(); while (element instanceof PsiWhiteSpace) element = element.getPrevSibling(); if (element instanceof XmlToken) { if (((XmlToken) element).getTokenType() == XmlTokenType.XML_START_TAG_START) { PsiElement parent = element.getParent(); if (parent instanceof XmlTag && !(token.getNextSibling() instanceof OuterLanguageElement)) { checkTag((XmlTag) parent); } } } else { PsiElement parent = token.getParent(); if (parent instanceof XmlAttribute && !(token.getNextSibling() instanceof OuterLanguageElement)) { checkAttribute((XmlAttribute) parent); } } } else if (tokenType == XmlTokenType.XML_DATA_CHARACTERS && token.getParent() instanceof XmlText) { if (token.textContains(']') && token.textContains('>')) { String s = token.getText(); String marker = "]]>"; int i = s.indexOf(marker); if (i != -1) { // TODO: fix TextRange textRange = token.getTextRange(); int start = textRange.getStartOffset() + i; HighlightInfoType type = PsiTreeUtil.getParentOfType(token, XmlTag.class) instanceof HtmlTag ? HighlightInfoType.WARNING : HighlightInfoType.ERROR; HighlightInfo info = HighlightInfo.createHighlightInfo( type, start, start + marker.length(), XmlErrorMessages.message( "cdata.end.should.not.appear.in.content.unless.to.mark.end.of.cdata.section")); addToResults(info); } } } }
@NotNull public static List<String> getLastCommentsInFile( @NotNull KtFile file, CommentType commentType, boolean assertMustExist) { PsiElement lastChild = file.getLastChild(); if (lastChild != null && lastChild.getNode().getElementType().equals(KtTokens.WHITE_SPACE)) { lastChild = lastChild.getPrevSibling(); } assert lastChild != null; List<String> comments = ContainerUtil.newArrayList(); while (true) { if (lastChild.getNode().getElementType().equals(KtTokens.BLOCK_COMMENT)) { if (commentType == CommentType.ALL || commentType == CommentType.BLOCK_COMMENT) { String lastChildText = lastChild.getText(); comments.add(lastChildText.substring(2, lastChildText.length() - 2).trim()); } } else if (lastChild.getNode().getElementType().equals(KtTokens.EOL_COMMENT)) { if (commentType == CommentType.ALL || commentType == CommentType.LINE_COMMENT) { comments.add(lastChild.getText().substring(2).trim()); } } else { break; } lastChild = lastChild.getPrevSibling(); } if (comments.isEmpty() && assertMustExist) { throw new AssertionError( String.format( "Test file '%s' should end in a comment of type %s; last node was: %s", file.getName(), commentType, lastChild)); } return comments; }
@NotNull public GrStatement addStatementBefore(@NotNull GrStatement element, @Nullable GrStatement anchor) throws IncorrectOperationException { if (anchor == null && getRBrace() == null) { throw new IncorrectOperationException(); } if (anchor != null && !this.equals(anchor.getParent())) { throw new IncorrectOperationException(); } final LeafElement nls = Factory.createSingleLeafElement(GroovyTokenTypes.mNLS, "\n", 0, 1, null, getManager()); PsiElement actualAnchor = anchor == null ? getRBrace() : anchor; if (mayUseNewLinesAsSeparators()) { PsiElement prev = actualAnchor.getPrevSibling(); if (prev instanceof GrParameterList && prev.getTextLength() == 0 && prev.getPrevSibling() != null) { prev = prev.getPrevSibling(); } if (!PsiUtil.isLineFeed(prev)) { addBefore(nls.getPsi(), actualAnchor); } } element = (GrStatement) addBefore(element, actualAnchor); if (mayUseNewLinesAsSeparators()) { addBefore(nls.getPsi(), actualAnchor); } else { addBefore( Factory.createSingleLeafElement(GroovyTokenTypes.mNLS, "\n", 0, 1, null, getManager()) .getPsi(), actualAnchor); } return element; }
@Nullable private static PsiElement getPreviousNonWsComment(@Nullable PsiElement element, int minOffset) { if (element == null) { return null; } for (PsiElement e = element; e != null && e.getTextRange().getStartOffset() >= minOffset; e = e.getPrevSibling()) { if (e instanceof PsiWhiteSpace || e instanceof PsiComment) { continue; } return e; } return null; }
@Nullable public static GrDocComment findDocComment(GrDocCommentOwner owner) { PsiElement element = owner.getPrevSibling(); while (true) { if (element == null) return null; final ASTNode node = element.getNode(); if (node == null) return null; if (GroovyElementTypes.GROOVY_DOC_COMMENT.equals(node.getElementType()) || !GroovyElementTypes.WHITE_SPACES_OR_COMMENTS.contains(node.getElementType())) { break; } element = element.getPrevSibling(); } if (element instanceof GrDocComment) return (GrDocComment) element; return null; }
// Delete given element and all the elements separating it from the neighboring elements of the // same class public static void deleteElementWithDelimiters(@NotNull PsiElement element) { PsiElement paramBefore = PsiTreeUtil.getPrevSiblingOfType(element, element.getClass()); PsiElement from; PsiElement to; if (paramBefore != null) { from = paramBefore.getNextSibling(); to = element; } else { PsiElement paramAfter = PsiTreeUtil.getNextSiblingOfType(element, element.getClass()); from = element; to = paramAfter != null ? paramAfter.getPrevSibling() : element; } PsiElement parent = element.getParent(); parent.deleteChildRange(from, to); }
public void moveCursorInsideMethod(final Editor editor, final PsiElement addedElement) { final PsiElement lastElement = PsiTreeUtil.getDeepestLast(addedElement); final PsiElement prevElement = lastElement.getPrevSibling(); final int offset = (prevElement != null ? prevElement : lastElement).getTextOffset(); final int offsetToNavigate = InjectedLanguageManager.getInstance(addedElement.getProject()) .injectedToHost(addedElement, offset); if (ApplicationManager.getApplication().isHeadlessEnvironment()) { editor.getCaretModel().moveToOffset(offsetToNavigate); } else { new OpenFileDescriptor( addedElement.getProject(), addedElement.getContainingFile().getVirtualFile(), offsetToNavigate) .navigate(true); // properly contributes to editing history editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } }
private Map<String, LfGlobalVariable> findGlobalVariablesBefore() { Map<String, LfGlobalVariable> globalVariablesBefore = new LinkedHashMap<String, LfGlobalVariable>(); PsiElement element = this; do { element = element.getPrevSibling(); if (element instanceof GlobalVariableBinder) { LfGlobalVariable declaration = ((GlobalVariableBinder) element).getDeclaration(); globalVariablesBefore.put(declaration.getName(), declaration); } if (element instanceof TwelfStatement) { // short circuiting for TwelfStatement as an optimization globalVariablesBefore.putAll(((TwelfStatement) element).getGlobalVariablesBefore()); return globalVariablesBefore; } } while (element != null); return globalVariablesBefore; }