Search in sources :

Example 81 with PsiWhiteSpace

use of com.intellij.psi.PsiWhiteSpace in project intellij-community by JetBrains.

the class Pep8ExternalAnnotator method apply.

@Override
public void apply(@NotNull PsiFile file, Results annotationResult, @NotNull AnnotationHolder holder) {
    if (annotationResult == null || !file.isValid())
        return;
    final String text = file.getText();
    Project project = file.getProject();
    final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
    for (Problem problem : annotationResult.problems) {
        final int line = problem.myLine - 1;
        final int column = problem.myColumn - 1;
        int offset;
        if (document != null) {
            offset = line >= document.getLineCount() ? document.getTextLength() - 1 : document.getLineStartOffset(line) + column;
        } else {
            offset = StringUtil.lineColToOffset(text, line, column);
        }
        PsiElement problemElement = file.findElementAt(offset);
        // E3xx - blank lines warnings
        if (!(problemElement instanceof PsiWhiteSpace) && problem.myCode.startsWith("E3")) {
            final PsiElement elementBefore = file.findElementAt(Math.max(0, offset - 1));
            if (elementBefore instanceof PsiWhiteSpace) {
                problemElement = elementBefore;
            }
        }
        // W292 no newline at end of file
        if (problemElement == null && document != null && offset == document.getTextLength() && problem.myCode.equals("W292")) {
            problemElement = file.findElementAt(Math.max(0, offset - 1));
        }
        if (ignoreDueToSettings(project, problem, problemElement) || ignoredDueToProblemSuppressors(problem, file, problemElement)) {
            continue;
        }
        if (problemElement != null) {
            // TODO Remove: a workaround until the bundled pycodestyle.py supports Python 3.6 variable annotations by itself
            if (problem.myCode.equals("E701") && problemElement.getNode().getElementType() == PyTokenTypes.COLON && problemElement.getParent() instanceof PyAnnotation) {
                continue;
            }
            TextRange problemRange = problemElement.getTextRange();
            // So we register it only on that line where pycodestyle.py found the problem originally.
            if (crossesLineBoundary(document, text, problemRange)) {
                final int lineEndOffset;
                if (document != null) {
                    lineEndOffset = line >= document.getLineCount() ? document.getTextLength() - 1 : document.getLineEndOffset(line);
                } else {
                    lineEndOffset = StringUtil.lineColToOffset(text, line + 1, 0) - 1;
                }
                if (offset > lineEndOffset) {
                    // PSI/document don't match, don't try to highlight random places
                    continue;
                }
                problemRange = new TextRange(offset, lineEndOffset);
            }
            final Annotation annotation;
            final boolean inInternalMode = ApplicationManager.getApplication().isInternal();
            final String message = "PEP 8: " + (inInternalMode ? problem.myCode + " " : "") + problem.myDescription;
            if (annotationResult.level == HighlightDisplayLevel.ERROR) {
                annotation = holder.createErrorAnnotation(problemRange, message);
            } else if (annotationResult.level == HighlightDisplayLevel.WARNING) {
                annotation = holder.createWarningAnnotation(problemRange, message);
            } else {
                annotation = holder.createWeakWarningAnnotation(problemRange, message);
            }
            if (problem.myCode.equals("E401")) {
                annotation.registerUniversalFix(new OptimizeImportsQuickFix(), null, null);
            } else if (problem.myCode.equals("W391")) {
                annotation.registerUniversalFix(new RemoveTrailingBlankLinesFix(), null, null);
            } else if (problem.myCode.equals("E501")) {
                annotation.registerFix(new PyFillParagraphFix());
            } else {
                annotation.registerUniversalFix(new ReformatFix(), null, null);
            }
            annotation.registerFix(new IgnoreErrorFix(problem.myCode));
            annotation.registerFix(new CustomEditInspectionToolsSettingsAction(HighlightDisplayKey.find(PyPep8Inspection.INSPECTION_SHORT_NAME), () -> "Edit inspection profile setting"));
        }
    }
}
Also used : TextRange(com.intellij.openapi.util.TextRange) Document(com.intellij.openapi.editor.Document) Annotation(com.intellij.lang.annotation.Annotation) RemoveTrailingBlankLinesFix(com.jetbrains.python.inspections.quickfix.RemoveTrailingBlankLinesFix) Project(com.intellij.openapi.project.Project) PyFillParagraphFix(com.jetbrains.python.inspections.quickfix.PyFillParagraphFix) OptimizeImportsQuickFix(com.jetbrains.python.codeInsight.imports.OptimizeImportsQuickFix) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace) ReformatFix(com.jetbrains.python.inspections.quickfix.ReformatFix) CustomEditInspectionToolsSettingsAction(com.intellij.codeInspection.ex.CustomEditInspectionToolsSettingsAction)

Example 82 with PsiWhiteSpace

use of com.intellij.psi.PsiWhiteSpace in project intellij-community by JetBrains.

the class Pep8ExternalAnnotator method ignoreDueToSettings.

private static boolean ignoreDueToSettings(Project project, Problem problem, @Nullable PsiElement element) {
    final EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance();
    if (!editorSettings.getStripTrailingSpaces().equals(EditorSettingsExternalizable.STRIP_TRAILING_SPACES_NONE)) {
        // ignore trailing spaces errors if they're going to disappear after save
        if (problem.myCode.equals("W291") || problem.myCode.equals("W293")) {
            return true;
        }
    }
    final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
    final CommonCodeStyleSettings commonSettings = codeStyleSettings.getCommonSettings(PythonLanguage.getInstance());
    final PyCodeStyleSettings pySettings = codeStyleSettings.getCustomSettings(PyCodeStyleSettings.class);
    if (element instanceof PsiWhiteSpace) {
        // E303 too many blank lines (num)
        if (problem.myCode.equals("E303")) {
            final Matcher matcher = E303_LINE_COUNT_PATTERN.matcher(problem.myDescription);
            if (matcher.matches()) {
                final int reportedBlanks = Integer.parseInt(matcher.group(1));
                final PsiElement nonWhitespaceAfter = PyPsiUtils.getNextNonWhitespaceSibling(element);
                final PsiElement nonWhitespaceBefore = PyPsiUtils.getPrevNonWhitespaceSibling(element);
                final boolean classNearby = nonWhitespaceBefore instanceof PyClass || nonWhitespaceAfter instanceof PyClass;
                final boolean functionNearby = nonWhitespaceBefore instanceof PyFunction || nonWhitespaceAfter instanceof PyFunction;
                if (functionNearby || classNearby) {
                    if (PyUtil.isTopLevel(element)) {
                        if (reportedBlanks <= pySettings.BLANK_LINES_AROUND_TOP_LEVEL_CLASSES_FUNCTIONS) {
                            return true;
                        }
                    } else {
                        // Blanks around classes have priority over blanks around functions as defined in Python spacing builder
                        if (classNearby && reportedBlanks <= commonSettings.BLANK_LINES_AROUND_CLASS || functionNearby && reportedBlanks <= commonSettings.BLANK_LINES_AROUND_METHOD) {
                            return true;
                        }
                    }
                }
            }
        }
        // Note that E222 (multiple spaces after operator) is not suppressed, though. 
        if (problem.myCode.equals("E251") && (element.getParent() instanceof PyParameter && pySettings.SPACE_AROUND_EQ_IN_NAMED_PARAMETER || element.getParent() instanceof PyKeywordArgument && pySettings.SPACE_AROUND_EQ_IN_KEYWORD_ARGUMENT)) {
            return true;
        }
    }
    // thus underlying PSI element is not necessarily a whitespace
    if (problem.myCode.equals("W191") && codeStyleSettings.useTabCharacter(PythonFileType.INSTANCE)) {
        return true;
    }
    return false;
}
Also used : Matcher(java.util.regex.Matcher) EditorSettingsExternalizable(com.intellij.openapi.editor.ex.EditorSettingsExternalizable) CodeStyleSettings(com.intellij.psi.codeStyle.CodeStyleSettings) CommonCodeStyleSettings(com.intellij.psi.codeStyle.CommonCodeStyleSettings) PyCodeStyleSettings(com.jetbrains.python.formatter.PyCodeStyleSettings) CommonCodeStyleSettings(com.intellij.psi.codeStyle.CommonCodeStyleSettings) PyCodeStyleSettings(com.jetbrains.python.formatter.PyCodeStyleSettings) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace)

Example 83 with PsiWhiteSpace

use of com.intellij.psi.PsiWhiteSpace in project intellij-community by JetBrains.

the class GenerateDTDAction method getHandler.

@Override
@NotNull
protected CodeInsightActionHandler getHandler() {
    return new CodeInsightActionHandler() {

        @Override
        public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
            final XmlDocument document = findSuitableXmlDocument(file);
            if (document != null) {
                @NonNls final StringBuilder buffer = new StringBuilder();
                buffer.append("<!DOCTYPE " + document.getRootTag().getName() + " [\n");
                buffer.append(XmlUtil.generateDocumentDTD(document, true));
                buffer.append("]>\n");
                XmlFile tempFile;
                try {
                    final XmlProlog prolog = document.getProlog();
                    final PsiElement childOfType = PsiTreeUtil.getChildOfType(prolog, XmlProcessingInstruction.class);
                    if (childOfType != null) {
                        final String text = childOfType.getText();
                        buffer.insert(0, text);
                        final PsiElement nextSibling = childOfType.getNextSibling();
                        if (nextSibling instanceof PsiWhiteSpace) {
                            buffer.insert(text.length(), nextSibling.getText());
                        }
                    }
                    tempFile = (XmlFile) PsiFileFactory.getInstance(file.getProject()).createFileFromText("dummy.xml", buffer.toString());
                    prolog.replace(tempFile.getDocument().getProlog());
                } catch (IncorrectOperationException e) {
                    LOG.error(e);
                }
            }
        }
    };
}
Also used : NonNls(org.jetbrains.annotations.NonNls) XmlFile(com.intellij.psi.xml.XmlFile) CodeInsightActionHandler(com.intellij.codeInsight.CodeInsightActionHandler) XmlDocument(com.intellij.psi.xml.XmlDocument) XmlProlog(com.intellij.psi.xml.XmlProlog) NotNull(org.jetbrains.annotations.NotNull) Project(com.intellij.openapi.project.Project) PsiFile(com.intellij.psi.PsiFile) IncorrectOperationException(com.intellij.util.IncorrectOperationException) Editor(com.intellij.openapi.editor.Editor) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace) NotNull(org.jetbrains.annotations.NotNull)

Example 84 with PsiWhiteSpace

use of com.intellij.psi.PsiWhiteSpace in project intellij-community by JetBrains.

the class XmlCharFilter method isInXmlContext.

public static boolean isInXmlContext(Lookup lookup) {
    if (!lookup.isCompletion())
        return false;
    PsiElement psiElement = lookup.getPsiElement();
    PsiFile file = lookup.getPsiFile();
    if (!(file instanceof XmlFile) && psiElement != null) {
        file = psiElement.getContainingFile();
    }
    if (file instanceof XmlFile) {
        if (psiElement != null) {
            PsiElement elementToTest = psiElement;
            if (elementToTest instanceof PsiWhiteSpace) {
                // JSPX has whitespace with language Java
                elementToTest = elementToTest.getParent();
            }
            final Language language = elementToTest.getLanguage();
            if (!(language instanceof XMLLanguage)) {
                return false;
            }
        }
        return true;
    }
    return false;
}
Also used : XmlFile(com.intellij.psi.xml.XmlFile) Language(com.intellij.lang.Language) XMLLanguage(com.intellij.lang.xml.XMLLanguage) PsiFile(com.intellij.psi.PsiFile) XMLLanguage(com.intellij.lang.xml.XMLLanguage) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace)

Example 85 with PsiWhiteSpace

use of com.intellij.psi.PsiWhiteSpace in project intellij-community by JetBrains.

the class PyCommaSelectionHandler method addPreviousComma.

/**
   * adds previous comma and whitespace to result text range
   * @param e is current element
   * @param cursorOffset is current cursor offset
   * @return result selection textRange
   */
private static List<TextRange> addPreviousComma(PsiElement e, int cursorOffset) {
    PsiElement prevSibling = e.getPrevSibling();
    TextRange textRange = e.getTextRange();
    TextRange offsetRange = null;
    if (prevSibling != null) {
        if (prevSibling instanceof PsiWhiteSpace) {
            PsiElement prevCommaSibling = prevSibling.getPrevSibling();
            if (prevCommaSibling != null) {
                ASTNode node = prevCommaSibling.getNode();
                if (node != null) {
                    IElementType commaType = node.getElementType();
                    if (commaType == PyTokenTypes.COMMA) {
                        offsetRange = new TextRange(textRange.getStartOffset() - 2, textRange.getEndOffset());
                        if (offsetRange.contains(cursorOffset) && offsetRange.getLength() > 1) {
                            return Collections.singletonList(offsetRange);
                        }
                    }
                }
            }
        } else {
            ASTNode node = prevSibling.getNode();
            if (node != null) {
                IElementType commaType = node.getElementType();
                if (commaType == PyTokenTypes.COMMA) {
                    offsetRange = new TextRange(textRange.getStartOffset() - 1, textRange.getEndOffset());
                }
            }
        }
        if (offsetRange != null) {
            if (offsetRange.contains(cursorOffset) && offsetRange.getLength() > 1) {
                return Collections.singletonList(offsetRange);
            }
        }
    }
    return Collections.emptyList();
}
Also used : IElementType(com.intellij.psi.tree.IElementType) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace)

Aggregations

PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)90 PsiElement (com.intellij.psi.PsiElement)82 TextRange (com.intellij.openapi.util.TextRange)23 ASTNode (com.intellij.lang.ASTNode)15 PsiFile (com.intellij.psi.PsiFile)15 NotNull (org.jetbrains.annotations.NotNull)15 Nullable (org.jetbrains.annotations.Nullable)14 PsiComment (com.intellij.psi.PsiComment)13 IElementType (com.intellij.psi.tree.IElementType)13 Document (com.intellij.openapi.editor.Document)12 Project (com.intellij.openapi.project.Project)7 ArrayList (java.util.ArrayList)6 FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)5 Editor (com.intellij.openapi.editor.Editor)5 Language (com.intellij.lang.Language)4 UnfairTextRange (com.intellij.openapi.util.UnfairTextRange)4 XmlTag (com.intellij.psi.xml.XmlTag)4 XMLLanguage (com.intellij.lang.xml.XMLLanguage)3 PsiDocumentManager (com.intellij.psi.PsiDocumentManager)3 XmlFile (com.intellij.psi.xml.XmlFile)3