diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AnnotatorWorksWithFileLevel.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AnnotatorWorksWithFileLevel.java new file mode 100644 index 000000000000..516f26608eb2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AnnotatorWorksWithFileLevel.java @@ -0,0 +1,3 @@ +class X { + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java index ba6e5fa4f8a2..2ae666ffe803 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.codeInsight.daemon; import com.intellij.ToolExtensionPoints; +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.accessStaticViaInstance.AccessStaticViaInstance; @@ -31,11 +32,13 @@ import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import com.intellij.lang.Language; import com.intellij.lang.LanguageAnnotators; +import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.StdFileTypes; @@ -54,6 +57,7 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import java.awt.*; import java.io.IOException; import java.util.List; @@ -393,4 +397,44 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase { List infos = highlightErrors(); assertTrue(!infos.isEmpty()); } + + public static class MyTopFileAnnotator implements Annotator { + @Override + public void annotate(@NotNull PsiElement psiElement, @NotNull final AnnotationHolder holder) { + if (psiElement instanceof PsiFile && !psiElement.getText().contains("xxx")) { + Annotation annotation = holder.createWarningAnnotation(psiElement, "top level"); + annotation.setFileLevelAnnotation(true); + } + } + } + + public void testAnnotatorWorksWithFileLevel() { + Annotator annotator = new MyTopFileAnnotator(); + Language java = StdFileTypes.JAVA.getLanguage(); + LanguageAnnotators.INSTANCE.addExplicitExtension(java, annotator); + try { + List list = LanguageAnnotators.INSTANCE.allForLanguage(java); + assertTrue(list.toString(), list.contains(annotator)); + configureByFile(BASE_PATH + "/" + getTestName(false) + ".java"); + ((EditorEx)getEditor()).getScrollPane().getViewport().setSize(new Dimension(1000,1000)); // whole file fit onscreen + doHighlighting(); + List fileLevel = + ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(ourProject)).getFileLevelHighlights(getProject(), getFile()); + HighlightInfo info = assertOneElement(fileLevel); + assertEquals("top level", info.getDescription()); + + type("//xxx"); //disable top level annotation + List warnings = doHighlighting(HighlightSeverity.WARNING); + assertEmpty(warnings); + fileLevel = ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(ourProject)).getFileLevelHighlights(getProject(), getFile()); + assertEmpty(fileLevel); + } + finally { + LanguageAnnotators.INSTANCE.removeExplicitExtension(java, annotator); + } + + List list = LanguageAnnotators.INSTANCE.allForLanguage(java); + assertFalse(list.toString(), list.contains(annotator)); + } + } diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java index b27570da95e0..eb082a163875 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java @@ -199,6 +199,13 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP List outsideRanges = new ArrayList(); Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, insideElements, insideRanges, outsideElements, outsideRanges, false, FILE_FILTER); + // put file element always in outsideElements + if (!insideElements.isEmpty() && insideElements.get(insideElements.size()-1) instanceof PsiFile) { + PsiElement file = insideElements.remove(insideElements.size() - 1); + outsideElements.add(file); + ProperTextRange range = insideRanges.remove(insideRanges.size() - 1); + outsideRanges.add(range); + } setProgressLimit((long)(insideElements.size()+outsideElements.size())); @@ -330,7 +337,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP assert info != null; if (!myRestrictRange.containsRange(info.getStartOffset(), info.getEndOffset())) continue; - List result = myPriorityRange.containsRange(info.getStartOffset(), info.getEndOffset()) ? insideResult : outsideResult; + List result = myPriorityRange.containsRange(info.getStartOffset(), info.getEndOffset()) && !(element instanceof PsiFile) ? insideResult : outsideResult; // have to filter out already obtained highlights if (!result.add(info)) continue; boolean isError = info.getSeverity() == HighlightSeverity.ERROR; @@ -345,7 +352,6 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP info.setBijective(elementRange.equalsToRange(info.startOffset, info.endOffset)); myHighlightInfoProcessor.infoIsAvailable(myHighlightingSession, info); - //myTransferToEDTQueue.offer(info); infosForThisRange.add(info); } // include infos which we got while visiting nested elements with the same range @@ -368,7 +374,6 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP nested.push(Pair.create(elementRange, infosForThisRange)); if (parent == null || !Comparing.equal(elementRange, parent.getTextRange())) { myHighlightInfoProcessor.allHighlightsForRangeAreProduced(myHighlightingSession, elementRange, infosForThisRange); - //killAbandonedHighlightsUnder(elementRange, infosForThisRange, progress); } } advanceProgress(elements.size() - (nextLimit-chunkSize));