private static boolean hasErrorElements(@NotNull final PsiElement element) { if (element instanceof PsiErrorElement) { HighlightErrorFilter[] errorFilters = Extensions.getExtensions(HighlightErrorFilter.EP_NAME, element.getProject()); for (HighlightErrorFilter errorFilter : errorFilters) { if (!errorFilter.shouldHighlightErrorElement((PsiErrorElement)element)) { return false; } } return true; } for (PsiElement child : element.getChildren()) { if (hasErrorElements(child)) { return true; } } return false; }
public String createReport() { StringBuilder builder = new StringBuilder("\n\n\n"); builder.append("Language: ") .append(myLang.getDisplayName()) .append(". Setting: ") .append(mySettingsType) .append(". Errors found: ") .append(myErrors.size()) .append('\n'); for (PsiErrorElement error : myErrors) { builder.append(" ") .append(error.getErrorDescription()) .append(". Previous sibling: ") .append(error.getPrevSibling()) .append('\n'); } builder.append("\nCode sample:\n") .append(myCode) .append('\n'); return builder.toString(); }
@Override public boolean hashCodesEqual(@NotNull final ASTNode n1, @NotNull final LighterASTNode n2) { if (n1 instanceof LeafElement && n2 instanceof Token) { boolean isForeign1 = n1 instanceof ForeignLeafPsiElement; boolean isForeign2 = n2.getTokenType() instanceof ForeignLeafType; if (isForeign1 != isForeign2) return false; if (isForeign1) { return n1.getText().equals(((ForeignLeafType)n2.getTokenType()).getValue()); } return ((LeafElement)n1).textMatches(((Token)n2).getText()); } if (n1 instanceof PsiErrorElement && n2.getTokenType() == TokenType.ERROR_ELEMENT) { final PsiErrorElement e1 = (PsiErrorElement)n1; if (!Comparing.equal(e1.getErrorDescription(), getErrorMessage(n2))) return false; } return ((TreeElement)n1).hc() == ((Node)n2).hc(); }
@Override public int getNodeHash(PsiElement node) { if (node == null) { return 0; } if (node instanceof PsiWhiteSpace || node instanceof PsiErrorElement) { return 0; } else if (node instanceof LeafElement) { if (isToSkipAsLiteral(node)) { return 0; } return node.getText().hashCode(); } return node.getClass().getName().hashCode(); }
public static boolean isIgnoredNode(PsiElement element) { // ex. "var i = 0" in AS: empty JSAttributeList should be skipped /*if (element.getText().length() == 0) { return true; }*/ if (element instanceof PsiWhiteSpace || element instanceof PsiErrorElement || element instanceof PsiComment) { return true; } if (!(element instanceof LeafElement)) { return false; } if (CharArrayUtil.containsOnlyWhiteSpaces(element.getText())) { return true; } EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(element); if (descriptorProvider == null) { return false; } final IElementType elementType = ((LeafElement)element).getElementType(); return descriptorProvider.getIgnoredTokens().contains(elementType); }
@Override public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) { TextRange stringRange = e.getTextRange(); PsiElement firstChild = e.getFirstChild().getNextSibling(); if (firstChild instanceof PsiErrorElement) { return Collections.emptyList(); } int startShift = 1; if (firstChild instanceof PsiWhiteSpace) startShift += firstChild.getTextLength(); PsiElement lastChild = e.getLastChild().getPrevSibling(); int endShift = 1; if (lastChild instanceof PsiWhiteSpace && lastChild != firstChild) endShift += lastChild.getTextLength(); final TextRange offsetRange = new TextRange(stringRange.getStartOffset() + startShift, stringRange.getEndOffset() - endShift); if (offsetRange.contains(cursorOffset) && offsetRange.getLength() > 1) { return Collections.singletonList(offsetRange); } return Collections.emptyList(); }
private static void doFix(@NotNull final PsiElement element) throws IncorrectOperationException { final XmlToken endNameToken = (XmlToken)element; final PsiElement tagElement = endNameToken.getParent(); if (!(tagElement instanceof XmlTag) && !(tagElement instanceof PsiErrorElement)) return; if (tagElement instanceof PsiErrorElement) { tagElement.delete(); } else { final ASTNode astNode = tagElement.getNode(); if (astNode != null) { final ASTNode endTagStart = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(astNode); if (endTagStart != null) { final Document document = PsiDocumentManager.getInstance(element.getProject()).getDocument(tagElement.getContainingFile()); if (document != null) { document.deleteString(endTagStart.getStartOffset(), tagElement.getLastChild().getTextRange().getEndOffset()); } } } } }
@Nullable static XmlToken findEndTagName(@Nullable final PsiErrorElement element) { if (element == null) return null; final ASTNode astNode = element.getNode(); if (astNode == null) return null; ASTNode current = astNode.getLastChildNode(); ASTNode prev = current; while (current != null) { final IElementType elementType = prev.getElementType(); if ((elementType == XmlTokenType.XML_NAME || elementType == XmlTokenType.XML_TAG_NAME) && current.getElementType() == XmlTokenType.XML_END_TAG_START) { return (XmlToken)prev.getPsi(); } prev = current; current = current.getTreePrev(); } return null; }
@Override public boolean shouldHighlightErrorElement(@NotNull final PsiErrorElement element) { final PsiFile psiFile = element.getContainingFile(); if (psiFile == null || psiFile.getViewProvider().getBaseLanguage() != HTMLLanguage.INSTANCE && HTMLLanguage.INSTANCE != element.getLanguage()) return true; final PsiElement[] children = element.getChildren(); if (children.length > 0) { if (children[0] instanceof XmlToken && XmlTokenType.XML_END_TAG_START == ((XmlToken)children[0]).getTokenType()) { if (XmlErrorMessages.message("xml.parsing.closing.tag.matches.nothing").equals(element.getErrorDescription())) { return false; } } } return true; }
public static boolean isInContext(@NotNull PsiElement element) { if (PsiTreeUtil.getParentOfType(element, XmlComment.class) != null) { return false; } if (PsiTreeUtil.getParentOfType(element, XmlText.class) != null) { return true; } if (element.getNode().getElementType() == XmlTokenType.XML_START_TAG_START) { return true; } PsiElement parent = element.getParent(); if (parent instanceof PsiErrorElement) { parent = parent.getParent(); } return parent instanceof XmlDocument; }
@Override public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement error) { final Project project = error.getProject(); final Language language = error.getLanguage(); // if ("CSS".equals(language.getID()) && PsiTreeUtil.getParentOfType(error, XmlAttribute.class) != null && // AngularIndexUtil.hasAngularJS(project)) { // final PsiFile file = error.getContainingFile(); // // PsiErrorElement nextError = error; // while (nextError != null) { // if (hasAngularInjectionAt(project, file, nextError.getTextOffset())) return false; // nextError = PsiTreeUtil.getNextSiblingOfType(nextError, PsiErrorElement.class); // } // } if (HTMLLanguage.INSTANCE.is(language) && error.getErrorDescription().endsWith("not closed")) { System.out.println(error.getErrorDescription()); final PsiElement parent = error.getParent(); final XmlElementDescriptor descriptor = parent instanceof XmlTag ? ((XmlTag) parent).getDescriptor() : null; return !(descriptor instanceof RTRequireTagDescriptor); } return true; }
@NotNull public GLSLDeclaration[] getDeclarations() { // convert the list of children to a list of GLSLStatement objects while performing sanity check. PsiElement[] children = getChildren(); List<GLSLDeclaration> result = new ArrayList<GLSLDeclaration>(children.length); for (PsiElement child : children) { if (child instanceof GLSLDeclaration) { result.add((GLSLDeclaration) child); } else if (!(child instanceof PsiErrorElement)) { final ASTNode node = child.getNode(); if (node != null) { final IElementType type = node.getElementType(); if (!GLSLTokenTypes.COMMENTS.contains(type)) { Logger.getLogger("GLSLDeclarationList").warning("Parameter declaration list contains non-comment, non-expression element. ("+type+")"); } } } } return result.toArray(new GLSLDeclaration[result.size()]); }
@Override public boolean hashCodesEqual(final ASTNode n1, final LighterASTNode n2) { if (n1 instanceof LeafElement && n2 instanceof Token) { boolean isForeign1 = n1 instanceof ForeignLeafPsiElement; boolean isForeign2 = n2.getTokenType() instanceof ForeignLeafType; if (isForeign1 != isForeign2) return false; if (isForeign1) { return n1.getText().equals(((ForeignLeafType)n2.getTokenType()).getValue()); } return ((LeafElement)n1).textMatches(((Token)n2).getText()); } if (n1 instanceof PsiErrorElement && n2.getTokenType() == TokenType.ERROR_ELEMENT) { final PsiErrorElement e1 = (PsiErrorElement)n1; if (!Comparing.equal(e1.getErrorDescription(), getErrorMessage(n2))) return false; } return ((TreeElement)n1).hc() == ((Node)n2).hc(); }
@Nullable static XmlToken findEndTagName(@Nullable final PsiErrorElement element) { if (element == null) return null; final ASTNode astNode = element.getNode(); if (astNode == null) return null; ASTNode current = astNode.getLastChildNode(); ASTNode prev = current; while (current != null) { final IElementType elementType = prev.getElementType(); if ((elementType == XmlElementType.XML_NAME || elementType == XmlElementType.XML_TAG_NAME) && current.getElementType() == XmlElementType.XML_END_TAG_START) { return (XmlToken)prev.getPsi(); } prev = current; current = current.getTreePrev(); } return null; }
public boolean shouldHighlightErrorElement(@NotNull final PsiErrorElement element) { final PsiFile psiFile = element.getContainingFile(); if (psiFile == null || (psiFile.getViewProvider().getBaseLanguage() != HTMLLanguage.INSTANCE && HTMLLanguage.INSTANCE != element.getLanguage())) return true; final PsiElement[] children = element.getChildren(); if (children.length > 0) { if (children[0] instanceof XmlToken && XmlTokenType.XML_END_TAG_START == ((XmlToken)children[0]).getTokenType()) { if (XmlErrorMessages.message("xml.parsing.closing.tag.matches.nothing").equals(element.getErrorDescription())) { return false; } } } return true; }
public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement element) { PsiFile templateLanguageFile = PsiUtilCore.getTemplateLanguageFile(element.getContainingFile()); if (templateLanguageFile == null) { return true; } Language language = templateLanguageFile.getLanguage(); if (language != LatteLanguage.INSTANCE) { return true; } if (element.getParent() instanceof XmlElement || element.getParent() instanceof CssElement) { return false; } if (element.getParent().getLanguage() == LatteLanguage.INSTANCE) { return true; } PsiElement nextSibling; for (nextSibling = PsiTreeUtil.nextLeaf(element); nextSibling instanceof PsiWhiteSpace; nextSibling = nextSibling.getNextSibling()); PsiElement psiElement = nextSibling == null ? null : PsiTreeUtil.findCommonParent(nextSibling, element); boolean nextIsOuterLanguageElement = nextSibling instanceof OuterLanguageElement || nextSibling instanceof LatteMacroClassic; return !nextIsOuterLanguageElement || psiElement == null || psiElement instanceof PsiFile; }
@NotNull @Override public ASTNode getTreeBuilt() { ASTNode built = super.getTreeBuilt(); if (LOG.isDebugEnabled() && !ApplicationManager.getApplication().isUnitTestMode()) { // Walk the tree, depth first and print out all remaining error elements. new ASTNodeWalker().walk(built, new Lambda<ASTNode>() { @Override public boolean process(ASTNode node) { if (node instanceof PsiErrorElement) { PsiErrorElement err = (PsiErrorElement)node; printErrorInfo(err.getTextRange().getStartOffset(), err.getText(), err.getErrorDescription()); } return true; } }); } return built; }
@Override public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement error) { final Project project = error.getProject(); final Language language = error.getLanguage(); if ("CSS".equals(language.getID()) && PsiTreeUtil.getParentOfType(error, XmlAttribute.class) != null && EmberIndexUtil.hasEmberJS(project)) { final PsiFile file = error.getContainingFile(); PsiErrorElement nextError = error; while (nextError != null) { nextError = PsiTreeUtil.getNextSiblingOfType(nextError, PsiErrorElement.class); } } if (HTMLLanguage.INSTANCE.is(language) && error.getErrorDescription().endsWith("not closed")) { final PsiElement parent = error.getParent(); final XmlElementDescriptor descriptor = parent instanceof XmlTag ? ((XmlTag)parent).getDescriptor() : null; return !(descriptor instanceof EmberJSTagDescriptor); } return true; }
/** * Twig tag pattern with some hack * because we have invalid psi elements after STATEMENT_BLOCK_START * * {% <caret> %} */ public static ElementPattern<PsiElement> getTagTokenParserPattern() { //noinspection unchecked return PlatformPatterns .psiElement() .afterLeafSkipping( PlatformPatterns.or( PlatformPatterns.psiElement(PsiWhiteSpace.class), PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE) ), PlatformPatterns.or( PlatformPatterns.psiElement(TwigTokenTypes.STATEMENT_BLOCK_START), PlatformPatterns.psiElement(PsiErrorElement.class) ) ) .beforeLeafSkipping( PlatformPatterns.or( PlatformPatterns.psiElement(PsiWhiteSpace.class), PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE) ), PlatformPatterns.psiElement(TwigTokenTypes.STATEMENT_BLOCK_END) ) .withLanguage(TwigLanguage.INSTANCE); }
@Override public void visit(@Nonnull PsiElement element) { if (element instanceof PsiErrorElement) { if (myHighlightErrorElements) visitErrorElement((PsiErrorElement)element); } else { if (myRunAnnotators) runAnnotators(element); } if (myAnnotationHolder.hasAnnotations()) { for (Annotation annotation : myAnnotationHolder) { myHolder.add(HighlightInfo.fromAnnotation(annotation, null, myBatchMode)); } myAnnotationHolder.clear(); } }
private static boolean hasErrorElements(@Nonnull final PsiElement element) { if (element instanceof PsiErrorElement) { HighlightErrorFilter[] errorFilters = Extensions.getExtensions(HighlightErrorFilter.EP_NAME, element.getProject()); for (HighlightErrorFilter errorFilter : errorFilters) { if (!errorFilter.shouldHighlightErrorElement((PsiErrorElement)element)) { return false; } } return true; } for (PsiElement child : element.getChildren()) { if (hasErrorElements(child)) { return true; } } return false; }
@Override public boolean hashCodesEqual(@Nonnull final ASTNode n1, @Nonnull final LighterASTNode n2) { if (n1 instanceof LeafElement && n2 instanceof Token) { boolean isForeign1 = n1 instanceof ForeignLeafPsiElement; boolean isForeign2 = n2.getTokenType() instanceof ForeignLeafType; if (isForeign1 != isForeign2) return false; if (isForeign1) { return n1.getText().equals(((ForeignLeafType)n2.getTokenType()).getValue()); } return ((LeafElement)n1).textMatches(((Token)n2).getText()); } if (n1 instanceof PsiErrorElement && n2.getTokenType() == TokenType.ERROR_ELEMENT) { final PsiErrorElement e1 = (PsiErrorElement)n1; if (!Comparing.equal(e1.getErrorDescription(), getErrorMessage(n2))) return false; } return ((TreeElement)n1).hc() == ((Node)n2).hc(); }
public static boolean isWithinTag(Lookup lookup) { if(isInXmlContext(lookup)) { PsiElement psiElement = lookup.getPsiElement(); final PsiElement parentElement = psiElement != null ? psiElement.getParent() : null; if(parentElement instanceof XmlTag) { return true; } if(parentElement instanceof PsiErrorElement && parentElement.getParent() instanceof XmlDocument) { return true; } return (parentElement instanceof XmlDocument || parentElement instanceof XmlText) && (psiElement.textMatches("<") || psiElement.textMatches("\"")); } return false; }
private boolean isIncomplete(ASTNode node) { node.getPsi().getFirstChild(); // expand chameleon ASTNode lastChild = node.getLastChildNode(); while(lastChild != null && lastChild.getPsi() instanceof PsiWhiteSpace) { lastChild = lastChild.getTreePrev(); } if(lastChild == null) { return false; } if(lastChild.getPsi() instanceof PsiErrorElement) { return true; } return isIncomplete(lastChild); }
/** * TODO if/when we implement alignment, update this method to do alignment properly * * This method handles indent and alignment on Enter. */ @NotNull @Override public ChildAttributes getChildAttributes(int newChildIndex) { /** * We indent if we're in a TAG_BLOCK (note that this works nicely since Enter can only be invoked * INSIDE a block (i.e. after the open block). * * Also indent if we are wrapped in a block created by the templated language */ if (myNode.getElementType() == DustTypes.TAG_BLOCK || (getParent() instanceof DataLanguageBlockWrapper && (myNode.getElementType() != DustTypes.STATEMENTS || myNode.getTreeNext() instanceof PsiErrorElement))) { return new ChildAttributes(Indent.getNormalIndent(), null); } else { return new ChildAttributes(Indent.getNoneIndent(), null); } }
@Override public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement element) { PsiFile file = element.getContainingFile(); if (file == null) { return true; } VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile == null) { return true; } TaskFile taskFile = StudyUtils.getTaskFile(element.getProject(), virtualFile); return taskFile == null || taskFile.isHighlightErrors(); }
@Override public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement element) { PsiFile file = element.getContainingFile(); if (file == null) { return true; } VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile == null) { return true; } if (virtualFile.getPath().contains(CCUtils.GENERATED_FILES_FOLDER)) { return false; } return true; }
/** * @param node Tree node * @return true if node is incomplete */ public boolean isIncomplete(@NotNull final ASTNode node) { if (node.getElementType() instanceof ILazyParseableElementType) return false; ASTNode lastChild = node.getLastChildNode(); while (lastChild != null && !(lastChild.getElementType() instanceof ILazyParseableElementType) && (lastChild.getPsi() instanceof PsiWhiteSpace || lastChild.getPsi() instanceof PsiComment)) { lastChild = lastChild.getTreePrev(); } return lastChild != null && (lastChild.getPsi() instanceof PsiErrorElement || isIncomplete(lastChild)); }
/** * Is the element have expected position in method parameters list * and all previous parameters is valid */ private static boolean isParameterDepth(Object o, int depth) { PsiElement[] parameters = ((ParameterList) ((PsiElement) o).getParent()).getParameters(); /* Если параметров меньше, чем необходимо - облом */ if (parameters.length < depth) return false; /* Все предыдущие параметры должны быть корректными */ if (depth > 1) for (int i = 0; i < depth; i++) { if (parameters[i] instanceof PsiErrorElement) return false; } /* Проверяем, что указанный параметр имеет правильную глубину вложенности */ return parameters[depth - 1].equals(o); }
@Override public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException { if (!(psiElement instanceof PsiArrayInitializerExpression)) return; PsiArrayInitializerExpression expr = (PsiArrayInitializerExpression)psiElement; if (!expr.getText().endsWith("}")) { PsiErrorElement err = ContainerUtil.findInstance(expr.getChildren(), PsiErrorElement.class); int endOffset = (err != null ? err : expr).getTextRange().getEndOffset(); editor.getDocument().insertString(endOffset, "}"); } }
@Override public void visit(@NotNull PsiElement element) { if (element instanceof PsiErrorElement) { if (myHighlightErrorElements) visitErrorElement((PsiErrorElement)element); } else { if (myRunAnnotators) runAnnotators(element); } if (myAnnotationHolder.hasAnnotations()) { for (Annotation annotation : myAnnotationHolder) { myHolder.add(HighlightInfo.fromAnnotation(annotation, null, myBatchMode)); } myAnnotationHolder.clear(); } }
private void visitErrorElement(final PsiErrorElement element) { for(HighlightErrorFilter errorFilter: myErrorFilters) { if (!errorFilter.shouldHighlightErrorElement(element)) { return; } } HighlightInfo info = createErrorElementInfo(element); myHolder.add(info); }
private void processCodeSamples(@NotNull LanguageCodeStyleSettingsProvider provider, @NotNull List<CodeSampleInfo> samples) { for (CodeSampleInfo sample : samples) { Collection<PsiErrorElement> errorReports = getErrorsForText(provider, sample.codeSample); if (errorReports.isEmpty()) { continue; } CodeErrorReport report = new CodeErrorReport(sample, provider.getLanguage(), errorReports); myErrorReports.add(report); } }