diff --git a/.idea/modules.xml b/.idea/modules.xml
index 18f0a957bb5d..446556c1582b 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -10,6 +10,8 @@
+
+
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
index a806b2ba5ba9..c3d4806d3f6e 100644
--- a/build/scripts/layouts.gant
+++ b/build/scripts/layouts.gant
@@ -289,7 +289,7 @@ public def layoutCommunityPlugins(String home) {
}
fileset(dir: "$home/plugins/gradle/lib") { include(name: "*.jar") }
}
-
+
layoutPlugin("git4idea") {
jar("git4idea-rt.jar") {
module("git4idea-rt")
@@ -701,6 +701,8 @@ def layout_core_upsource(String home, String target) {
module("java-indexing-impl")
module("platform-resources")
module("platform-resources-en")
+ module("analysis-api")
+ module("analysis-impl")
}
jar("annotations.jar") {
diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant
index 19530671f1f1..f74f8a9b4ae0 100644
--- a/build/scripts/utils.gant
+++ b/build/scripts/utils.gant
@@ -181,7 +181,7 @@ def debugPort = System.getProperty("debug.port") ?: 5555
if (suspendUntilDebuggerConnect == 'y') {
println """\
------------->----------- This process is suspended until remote debugger connects to the port $debugPort ----<----
--------------------------------------------^------^------^------^------^------^------^-----------------------
+-------------------------------------------^------^------^------^------^------^------^-----------------------
"""
}
@@ -250,6 +250,7 @@ binding.setVariable("platformApiModules", [
"platform-api",
"lvcs-api",
"lang-api",
+ "analysis-api",
"vcs-api",
"usageView",
"xdebugger-api",
@@ -267,6 +268,7 @@ binding.setVariable("platformImplementationModules", [
"platform-impl",
"vcs-impl",
"lang-impl",
+ "analysis-impl",
"testRunner",
"smRunner",
"xdebugger-impl",
diff --git a/platform/analysis-api/analysis-api.iml b/platform/analysis-api/analysis-api.iml
new file mode 100644
index 000000000000..177ad6224f2a
--- /dev/null
+++ b/platform/analysis-api/analysis-api.iml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/platform-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java b/platform/analysis-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java
similarity index 83%
rename from platform/platform-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java
rename to platform/analysis-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java
index 9e21988cb552..34133f67d6de 100644
--- a/platform/platform-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java
+++ b/platform/analysis-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java
@@ -16,7 +16,10 @@
package com.intellij.codeHighlighting;
import com.intellij.lang.annotation.HighlightSeverity;
-import com.intellij.openapi.editor.colors.*;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.ImageLoader;
import com.intellij.util.containers.HashMap;
@@ -106,17 +109,27 @@ public class HighlightDisplayLevel {
@NotNull
private static Icon createIconByMask(@NotNull TextAttributesKey key) {
- final EditorColorsManager manager = EditorColorsManager.getInstance();
- if (manager != null) {
- final EditorColorsScheme globalScheme = manager.getGlobalScheme();
- return createIconByMask(globalScheme.getAttributes(key).getErrorStripeColor());
- }
-
+ Icon icon = createIconByMaskFromExtensions(key);
+ if (icon != null) return icon;
return createIconByMask(key.getDefaultAttributes().getErrorStripeColor());
}
+ public interface IconCreator {
+ ExtensionPointName EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.codeHighlighting.iconCreator");
+
+ Icon createIcon(@NotNull TextAttributesKey key);
+ }
+
+ public static Icon createIconByMaskFromExtensions(@NotNull TextAttributesKey key) {
+ for (IconCreator creator : Extensions.getExtensions(IconCreator.EXTENSION_POINT_NAME)) {
+ Icon icon = creator.createIcon(key);
+ if (icon != null) return icon;
+ }
+ return null;
+ }
+
@NotNull
- public static Icon createIconByMask(@NotNull final Color renderColor) {
+ public static Icon createIconByMask(final Color renderColor) {
return new Icon() {
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/EmptyResolveMessageProvider.java b/platform/analysis-api/src/com/intellij/codeInsight/daemon/EmptyResolveMessageProvider.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInsight/daemon/EmptyResolveMessageProvider.java
rename to platform/analysis-api/src/com/intellij/codeInsight/daemon/EmptyResolveMessageProvider.java
diff --git a/java/openapi/src/com/intellij/codeInsight/daemon/GroupNames.java b/platform/analysis-api/src/com/intellij/codeInsight/daemon/GroupNames.java
similarity index 100%
rename from java/openapi/src/com/intellij/codeInsight/daemon/GroupNames.java
rename to platform/analysis-api/src/com/intellij/codeInsight/daemon/GroupNames.java
diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/HighlightDisplayKey.java b/platform/analysis-api/src/com/intellij/codeInsight/daemon/HighlightDisplayKey.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInsight/daemon/HighlightDisplayKey.java
rename to platform/analysis-api/src/com/intellij/codeInsight/daemon/HighlightDisplayKey.java
diff --git a/platform/lang-api/src/com/intellij/codeInspection/CommonProblemDescriptor.java b/platform/analysis-api/src/com/intellij/codeInspection/CommonProblemDescriptor.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInspection/CommonProblemDescriptor.java
rename to platform/analysis-api/src/com/intellij/codeInspection/CommonProblemDescriptor.java
diff --git a/platform/lang-api/src/com/intellij/codeInspection/InspectionManager.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionManager.java
similarity index 87%
rename from platform/lang-api/src/com/intellij/codeInspection/InspectionManager.java
rename to platform/analysis-api/src/com/intellij/codeInspection/InspectionManager.java
index 19d55fefe055..2d5b03b07de3 100644
--- a/platform/lang-api/src/com/intellij/codeInspection/InspectionManager.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionManager.java
@@ -84,14 +84,6 @@ public abstract class InspectionManager {
boolean onTheFly,
LocalQuickFix... fixes);
- @NotNull
- public abstract ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
- @NotNull final String descriptionTemplate,
- @NotNull ProblemHighlightType highlightType,
- @Nullable final HintAction hintAction,
- boolean onTheFly,
- LocalQuickFix... fixes);
-
@NotNull
public abstract ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
@NotNull final String descriptionTemplate,
@@ -153,17 +145,6 @@ public abstract class InspectionManager {
@NotNull ProblemHighlightType highlightType,
final LocalQuickFix... fixes);
- @Deprecated
- @NotNull
- /**
- * use {@link #createProblemDescriptor(PsiElement, String, ProblemHighlightType, HintAction, boolean, LocalQuickFix...)} instead
- */
- public abstract ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
- @NotNull final String descriptionTemplate,
- @NotNull ProblemHighlightType highlightType,
- @Nullable final HintAction hintAction,
- final LocalQuickFix... fixes);
-
@Deprecated
@NotNull
/**
diff --git a/platform/lang-api/src/com/intellij/codeInspection/InspectionProfileEntry.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
similarity index 91%
rename from platform/lang-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
rename to platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
index 5d501b22c147..4e9e817178c5 100644
--- a/platform/lang-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
@@ -28,7 +28,10 @@ import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializationException;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Element;
-import org.jetbrains.annotations.*;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.BufferedReader;
@@ -61,9 +64,9 @@ public abstract class InspectionProfileEntry {
protected volatile DefaultNameProvider myNameProvider = null;
/**
- * @see InspectionEP#groupDisplayName
- * @see InspectionEP#groupKey
- * @see InspectionEP#groupBundle
+ * @see com.intellij.codeInspection.InspectionEP#groupDisplayName
+ * @see com.intellij.codeInspection.InspectionEP#groupKey
+ * @see com.intellij.codeInspection.InspectionEP#groupBundle
*/
@Nls
@NotNull
@@ -79,7 +82,7 @@ public abstract class InspectionProfileEntry {
}
/**
- * @see InspectionEP#groupPath
+ * @see com.intellij.codeInspection.InspectionEP#groupPath
*/
@NotNull
public String[] getGroupPath() {
@@ -91,9 +94,9 @@ public abstract class InspectionProfileEntry {
}
/**
- * @see InspectionEP#displayName
- * @see InspectionEP#key
- * @see InspectionEP#bundle
+ * @see com.intellij.codeInspection.InspectionEP#displayName
+ * @see com.intellij.codeInspection.InspectionEP#key
+ * @see com.intellij.codeInspection.InspectionEP#bundle
*/
@Nls
@NotNull
@@ -111,7 +114,7 @@ public abstract class InspectionProfileEntry {
/**
* DO NOT OVERRIDE this method.
*
- * @see InspectionEP#shortName
+ * @see com.intellij.codeInspection.InspectionEP#shortName
*/
@NonNls
@NotNull
@@ -133,7 +136,7 @@ public abstract class InspectionProfileEntry {
/**
* DO NOT OVERRIDE this method.
*
- * @see InspectionEP#level
+ * @see com.intellij.codeInspection.InspectionEP#level
*/
@NotNull
public HighlightDisplayLevel getDefaultLevel() {
@@ -143,7 +146,7 @@ public abstract class InspectionProfileEntry {
/**
* DO NOT OVERRIDE this method.
*
- * @see InspectionEP#enabledByDefault
+ * @see com.intellij.codeInspection.InspectionEP#enabledByDefault
*/
public boolean isEnabledByDefault() {
return false;
@@ -260,7 +263,7 @@ public abstract class InspectionProfileEntry {
* Initialize inspection with project. Is called on project opened for all profiles as well as on profile creation.
*
* @param project to be associated with this entry
- * @deprecated this won't work for inspections configured via {@link InspectionEP}
+ * @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP}
*/
public void projectOpened(Project project) {
}
@@ -269,7 +272,7 @@ public abstract class InspectionProfileEntry {
* Cleanup inspection settings corresponding to the project. Is called on project closed for all profiles as well as on profile deletion.
*
* @param project to be disassociated from this entry
- * @deprecated this won't work for inspections configured via {@link InspectionEP}
+ * @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP}
*/
public void projectClosed(Project project) {
}
diff --git a/platform/lang-api/src/com/intellij/codeInspection/InspectionsBundle.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionsBundle.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInspection/InspectionsBundle.java
rename to platform/analysis-api/src/com/intellij/codeInspection/InspectionsBundle.java
diff --git a/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionTool.java b/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java
similarity index 98%
rename from platform/lang-api/src/com/intellij/codeInspection/LocalInspectionTool.java
rename to platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java
index 4621faa8b70a..ef85342bfb84 100644
--- a/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionTool.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java
@@ -35,8 +35,11 @@ public abstract class LocalInspectionTool extends InspectionProfileEntry {
private static final Logger LOG = Logger.getInstance("#" + LocalInspectionTool.class.getName());
interface LocalDefaultNameProvider extends DefaultNameProvider {
- @Nullable String getDefaultID();
- @Nullable String getDefaultAlternativeID();
+ @Nullable
+ String getDefaultID();
+
+ @Nullable
+ String getDefaultAlternativeID();
}
/**
diff --git a/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionToolSession.java b/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionToolSession.java
similarity index 99%
rename from platform/lang-api/src/com/intellij/codeInspection/LocalInspectionToolSession.java
rename to platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionToolSession.java
index 50ab0b92e180..066e5c735127 100644
--- a/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionToolSession.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionToolSession.java
@@ -47,4 +47,4 @@ public class LocalInspectionToolSession extends UserDataHolderBase {
public int getEndOffset() {
return myEndOffset;
}
-}
\ No newline at end of file
+}
diff --git a/platform/lang-api/src/com/intellij/codeInspection/LocalQuickFix.java b/platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFix.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInspection/LocalQuickFix.java
rename to platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFix.java
diff --git a/platform/lang-api/src/com/intellij/codeInspection/LocalQuickFixBase.java b/platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFixBase.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInspection/LocalQuickFixBase.java
rename to platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFixBase.java
diff --git a/platform/lang-api/src/com/intellij/codeInspection/LocalQuickFixProvider.java b/platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFixProvider.java
similarity index 95%
rename from platform/lang-api/src/com/intellij/codeInspection/LocalQuickFixProvider.java
rename to platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFixProvider.java
index 4278e573808b..28176a396f1b 100644
--- a/platform/lang-api/src/com/intellij/codeInspection/LocalQuickFixProvider.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFixProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -26,4 +26,4 @@ import org.jetbrains.annotations.Nullable;
public interface LocalQuickFixProvider {
@Nullable
LocalQuickFix[] getQuickFixes();
-}
\ No newline at end of file
+}
diff --git a/platform/lang-api/src/com/intellij/codeInspection/ProblemDescriptor.java b/platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInspection/ProblemDescriptor.java
rename to platform/analysis-api/src/com/intellij/codeInspection/ProblemDescriptor.java
diff --git a/platform/lang-api/src/com/intellij/codeInspection/ProblemHighlightType.java b/platform/analysis-api/src/com/intellij/codeInspection/ProblemHighlightType.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInspection/ProblemHighlightType.java
rename to platform/analysis-api/src/com/intellij/codeInspection/ProblemHighlightType.java
diff --git a/platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java b/platform/analysis-api/src/com/intellij/codeInspection/ProblemsHolder.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java
rename to platform/analysis-api/src/com/intellij/codeInspection/ProblemsHolder.java
diff --git a/platform/lang-api/src/com/intellij/codeInspection/QuickFix.java b/platform/analysis-api/src/com/intellij/codeInspection/QuickFix.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/codeInspection/QuickFix.java
rename to platform/analysis-api/src/com/intellij/codeInspection/QuickFix.java
diff --git a/platform/platform-api/src/com/intellij/lang/annotation/HighlightSeverity.java b/platform/analysis-api/src/com/intellij/lang/annotation/HighlightSeverity.java
similarity index 96%
rename from platform/platform-api/src/com/intellij/lang/annotation/HighlightSeverity.java
rename to platform/analysis-api/src/com/intellij/lang/annotation/HighlightSeverity.java
index 3553925ff9a3..7e6ea0f3b5b4 100644
--- a/platform/platform-api/src/com/intellij/lang/annotation/HighlightSeverity.java
+++ b/platform/analysis-api/src/com/intellij/lang/annotation/HighlightSeverity.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
/**
* Defines a highlighting severity level for an annotation.
@@ -93,7 +94,7 @@ public class HighlightSeverity implements Comparable, JDOMExt
}
@Override
- public int compareTo(final HighlightSeverity highlightSeverity) {
+ public int compareTo(@NotNull final HighlightSeverity highlightSeverity) {
return myVal - highlightSeverity.myVal;
}
diff --git a/platform/analysis-impl/analysis-impl.iml b/platform/analysis-impl/analysis-impl.iml
new file mode 100644
index 000000000000..ad33ccfa85f0
--- /dev/null
+++ b/platform/analysis-impl/analysis-impl.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/Divider.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/Divider.java
similarity index 95%
rename from platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/Divider.java
rename to platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/Divider.java
index 401aab96e5df..e4425e1c247b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/Divider.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/Divider.java
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.daemon.impl;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightLevelUtil;
import com.intellij.lang.Language;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProgressManager;
@@ -43,12 +42,12 @@ public class Divider {
@NotNull TextRange range,
@NotNull List inside,
@NotNull List outside,
- @NotNull HighlightLevelUtil.AnalysisLevel level,
- boolean includeParents) {
+ boolean includeParents,
+ @NotNull Condition filter) {
final FileViewProvider viewProvider = file.getViewProvider();
for (Language language : viewProvider.getLanguages()) {
final PsiFile psiRoot = viewProvider.getPsi(language);
- if (HighlightLevelUtil.shouldAnalyse(psiRoot, level)) {
+ if (filter.value(psiRoot)) {
divideInsideAndOutside(psiRoot, startOffset, endOffset, range, inside, outside, includeParents);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/CommonProblemDescriptorImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/CommonProblemDescriptorImpl.java
similarity index 100%
rename from platform/lang-impl/src/com/intellij/codeInspection/CommonProblemDescriptorImpl.java
rename to platform/analysis-impl/src/com/intellij/codeInspection/CommonProblemDescriptorImpl.java
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
new file mode 100644
index 000000000000..e78fe4ea2406
--- /dev/null
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.impl.Divider;
+import com.intellij.concurrency.JobLauncher;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.*;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class InspectionEngine {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.InspectionEngine");
+
+ @NotNull
+ public static PsiElementVisitor createVisitorAndAcceptElements(@NotNull LocalInspectionTool tool,
+ @NotNull ProblemsHolder holder,
+ boolean isOnTheFly,
+ @NotNull LocalInspectionToolSession session,
+ @NotNull List elements,
+ @Nullable Collection languages) {
+ PsiElementVisitor visitor = tool.buildVisitor(holder, isOnTheFly, session);
+ //noinspection ConstantConditions
+ if(visitor == null) {
+ LOG.error("Tool " + tool + " must not return null from the buildVisitor() method");
+ }
+ assert !(visitor instanceof PsiRecursiveElementVisitor || visitor instanceof PsiRecursiveElementWalkingVisitor)
+ : "The visitor returned from LocalInspectionTool.buildVisitor() must not be recursive. "+tool;
+
+ tool.inspectionStarted(session, isOnTheFly);
+ acceptElements(elements, visitor, languages);
+ return visitor;
+ }
+
+ public static void acceptElements(@NotNull List elements,
+ @NotNull PsiElementVisitor elementVisitor,
+ @Nullable Collection languages) {
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0, elementsSize = elements.size(); i < elementsSize; i++) {
+ PsiElement element = elements.get(i);
+ if (languages == null || languages.contains(element.getLanguage().getID())) {
+ element.accept(elementVisitor);
+ }
+ ProgressManager.checkCanceled();
+ }
+ }
+
+ public List inspect(@NotNull final List tools,
+ @NotNull final PsiFile file,
+ @NotNull final InspectionManager iManager,
+ final boolean isOnTheFly,
+ boolean failFastOnAcquireReadAction,
+ @NotNull final ProgressIndicator indicator) {
+ if (tools.isEmpty()) return Collections.emptyList();
+ final List resultDescriptors = Collections.synchronizedList(new ArrayList());
+ final List elements = new ArrayList();
+
+ TextRange range = file.getTextRange();
+ final LocalInspectionToolSession session = new LocalInspectionToolSession(file, range.getStartOffset(), range.getEndOffset());
+ Divider.divideInsideAndOutside(file, range.getStartOffset(), range.getEndOffset(), range, elements, Collections.emptyList(), true, Condition.TRUE);
+
+ boolean result = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(tools, indicator, failFastOnAcquireReadAction, new Processor() {
+ @Override
+ public boolean process(LocalInspectionTool tool) {
+ ProblemsHolder holder = new ProblemsHolder(iManager, file, isOnTheFly);
+ createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, null);
+
+ tool.inspectionFinished(session, holder);
+
+ if (holder.hasResults()) {
+ resultDescriptors.addAll(holder.getResults());
+ }
+
+ return true;
+ }
+ });
+
+ return resultDescriptors;
+ }
+}
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionManagerBase.java b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionManagerBase.java
new file mode 100644
index 000000000000..526a1f8dbfc6
--- /dev/null
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionManagerBase.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2000-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+public class InspectionManagerBase extends InspectionManager {
+ private final Project myProject;
+
+ public InspectionManagerBase(Project project) {
+ myProject = project;
+ }
+
+ @Override
+ @NotNull
+ public Project getProject() {
+ return myProject;
+ }
+
+ @Override
+ @NotNull
+ public CommonProblemDescriptor createProblemDescriptor(@NotNull String descriptionTemplate, QuickFix... fixes) {
+ return new CommonProblemDescriptorImpl(fixes, descriptionTemplate);
+ }
+
+ @Override
+ @NotNull
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
+ @NotNull String descriptionTemplate,
+ LocalQuickFix fix,
+ @NotNull ProblemHighlightType highlightType,
+ boolean onTheFly) {
+ LocalQuickFix[] quickFixes = fix != null ? new LocalQuickFix[]{fix} : null;
+ return createProblemDescriptor(psiElement, descriptionTemplate, onTheFly, quickFixes, highlightType);
+ }
+
+ @Override
+ @NotNull
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
+ @NotNull String descriptionTemplate,
+ boolean onTheFly,
+ LocalQuickFix[] fixes,
+ @NotNull ProblemHighlightType highlightType) {
+ return createProblemDescriptor(psiElement, descriptionTemplate, fixes, highlightType, onTheFly, false);
+ }
+
+ @Override
+ @NotNull
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
+ @NotNull String descriptionTemplate,
+ LocalQuickFix[] fixes,
+ @NotNull ProblemHighlightType highlightType,
+ boolean onTheFly,
+ boolean isAfterEndOfLine) {
+ return new ProblemDescriptorBase(psiElement, psiElement, descriptionTemplate, fixes, highlightType, isAfterEndOfLine, null, true, onTheFly);
+ }
+
+ @Override
+ @NotNull
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement startElement,
+ @NotNull PsiElement endElement,
+ @NotNull String descriptionTemplate,
+ @NotNull ProblemHighlightType highlightType,
+ boolean onTheFly,
+ LocalQuickFix... fixes) {
+ return new ProblemDescriptorBase(startElement, endElement, descriptionTemplate, fixes, highlightType, false, null, true, onTheFly);
+ }
+
+ @NotNull
+ @Override
+ public ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
+ final TextRange rangeInElement,
+ @NotNull final String descriptionTemplate,
+ @NotNull final ProblemHighlightType highlightType,
+ boolean onTheFly,
+ final LocalQuickFix... fixes) {
+ return new ProblemDescriptorBase(psiElement, psiElement, descriptionTemplate, fixes, highlightType, false, rangeInElement, true, onTheFly);
+ }
+
+ @NotNull
+ @Override
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
+ @NotNull String descriptionTemplate,
+ boolean showTooltip,
+ @NotNull ProblemHighlightType highlightType,
+ boolean onTheFly,
+ LocalQuickFix... fixes) {
+ return new ProblemDescriptorBase(psiElement, psiElement, descriptionTemplate, fixes, highlightType, false, null, showTooltip, onTheFly);
+ }
+
+ @Override
+ @Deprecated
+ @NotNull
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
+ @NotNull String descriptionTemplate,
+ LocalQuickFix fix,
+ @NotNull ProblemHighlightType highlightType) {
+ LocalQuickFix[] quickFixes = fix != null ? new LocalQuickFix[]{fix} : null;
+ return createProblemDescriptor(psiElement, descriptionTemplate, false, quickFixes, highlightType);
+ }
+
+ @Override
+ @Deprecated
+ @NotNull
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
+ @NotNull String descriptionTemplate,
+ LocalQuickFix[] fixes,
+ @NotNull ProblemHighlightType highlightType) {
+ return createProblemDescriptor(psiElement, descriptionTemplate, fixes, highlightType, false, false);
+ }
+
+ @Override
+ @Deprecated
+ @NotNull
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
+ @NotNull String descriptionTemplate,
+ LocalQuickFix[] fixes,
+ @NotNull ProblemHighlightType highlightType,
+ boolean isAfterEndOfLine) {
+ return createProblemDescriptor(psiElement, descriptionTemplate, fixes, highlightType, true, isAfterEndOfLine);
+ }
+
+ @Override
+ @Deprecated
+ @NotNull
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement startElement,
+ @NotNull PsiElement endElement,
+ @NotNull String descriptionTemplate,
+ @NotNull ProblemHighlightType highlightType,
+ LocalQuickFix... fixes) {
+ return createProblemDescriptor(startElement, endElement, descriptionTemplate, highlightType, true, fixes);
+ }
+
+ @NotNull
+ @Override
+ @Deprecated
+ public ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
+ final TextRange rangeInElement,
+ @NotNull final String descriptionTemplate,
+ @NotNull final ProblemHighlightType highlightType,
+ final LocalQuickFix... fixes) {
+ return createProblemDescriptor(psiElement, rangeInElement, descriptionTemplate, highlightType, true, fixes);
+ }
+
+ @NotNull
+ @Deprecated
+ @Override
+ public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
+ @NotNull String descriptionTemplate,
+ boolean showTooltip,
+ @NotNull ProblemHighlightType highlightType,
+ LocalQuickFix... fixes) {
+ return createProblemDescriptor(psiElement, descriptionTemplate, showTooltip, highlightType, true, fixes);
+ }
+
+}
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
new file mode 100644
index 000000000000..ebb5a1c6b86e
--- /dev/null
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2000-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.lang.injection.InjectedLanguageManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.pom.Navigatable;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class ProblemDescriptorBase extends CommonProblemDescriptorImpl implements ProblemDescriptor {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.ProblemDescriptorImpl");
+
+ @NotNull private final SmartPsiElementPointer myStartSmartPointer;
+ @Nullable private final SmartPsiElementPointer myEndSmartPointer;
+
+ private final ProblemHighlightType myHighlightType;
+ private Navigatable myNavigatable;
+ private final boolean myAfterEndOfLine;
+ private final TextRange myTextRangeInElement;
+ private final boolean myShowTooltip;
+ private TextAttributesKey myEnforcedTextAttributes;
+ private int myLineNumber = -1;
+ private String myProblemGroup;
+
+ public ProblemDescriptorBase(@NotNull PsiElement startElement,
+ @NotNull PsiElement endElement,
+ String descriptionTemplate,
+ LocalQuickFix[] fixes,
+ @NotNull ProblemHighlightType highlightType,
+ boolean isAfterEndOfLine,
+ @Nullable TextRange rangeInElement,
+ final boolean tooltip,
+ boolean onTheFly) {
+ super(fixes, descriptionTemplate);
+ myShowTooltip = tooltip;
+ PsiFile startContainingFile = startElement.getContainingFile();
+ LOG.assertTrue(startContainingFile != null && startContainingFile.isValid() || startElement.isValid(), startElement);
+ PsiFile endContainingFile = startElement == endElement ? startContainingFile : endElement.getContainingFile();
+ LOG.assertTrue(startElement == endElement || endContainingFile != null && endContainingFile.isValid() || endElement.isValid(), endElement);
+ assertPhysical(startElement);
+ if (startElement != endElement) assertPhysical(endElement);
+
+ final TextRange startElementRange = startElement.getTextRange();
+ LOG.assertTrue(startElementRange != null, startElement);
+ final TextRange endElementRange = endElement.getTextRange();
+ LOG.assertTrue(endElementRange != null, endElement);
+ if (startElementRange.getStartOffset() >= endElementRange.getEndOffset()) {
+ if (!(startElement instanceof PsiFile && endElement instanceof PsiFile)) {
+ LOG.error("Empty PSI elements should not be passed to createDescriptor. Start: " + startElement + ", end: " + endElement);
+ }
+ }
+
+ myHighlightType = highlightType;
+ final Project project = startContainingFile == null ? startElement.getProject() : startContainingFile.getProject();
+ final SmartPointerManager manager = SmartPointerManager.getInstance(project);
+ myStartSmartPointer = manager.createSmartPsiElementPointer(startElement, startContainingFile);
+ myEndSmartPointer = startElement == endElement ? null : manager.createSmartPsiElementPointer(endElement, endContainingFile);
+
+ myAfterEndOfLine = isAfterEndOfLine;
+ myTextRangeInElement = rangeInElement;
+ }
+
+ protected void assertPhysical(final PsiElement element) {
+ if (!element.isPhysical()) {
+ LOG.error("Non-physical PsiElement. Physical element is required to be able to anchor the problem in the source tree: " +
+ element + "; file: " + element.getContainingFile());
+ }
+ }
+
+ @Override
+ public PsiElement getPsiElement() {
+ PsiElement startElement = getStartElement();
+ if (myEndSmartPointer == null) {
+ return startElement;
+ }
+ PsiElement endElement = getEndElement();
+ if (startElement == endElement) {
+ return startElement;
+ }
+ if (startElement == null || endElement == null) return null;
+ return PsiTreeUtil.findCommonParent(startElement, endElement);
+ }
+
+ @Override
+ public PsiElement getStartElement() {
+ return myStartSmartPointer.getElement();
+ }
+
+ @Override
+ public PsiElement getEndElement() {
+ return myEndSmartPointer == null ? getStartElement() : myEndSmartPointer.getElement();
+ }
+
+ @Override
+ public int getLineNumber() {
+ if (myLineNumber == -1) {
+ PsiElement psiElement = getPsiElement();
+ if (psiElement == null) return -1;
+ if (!psiElement.isValid()) return -1;
+ LOG.assertTrue(psiElement.isPhysical());
+ InjectedLanguageManager manager = InjectedLanguageManager.getInstance(psiElement.getProject());
+ PsiFile containingFile = manager.getTopLevelFile(psiElement);
+ Document document = PsiDocumentManager.getInstance(psiElement.getProject()).getDocument(containingFile);
+ if (document == null) return -1;
+ TextRange textRange = getTextRange();
+ if (textRange == null) return -1;
+ textRange = manager.injectedToHost(psiElement, textRange);
+ myLineNumber = document.getLineNumber(textRange.getStartOffset()) + 1;
+ }
+ return myLineNumber;
+ }
+
+ @NotNull
+ @Override
+ public ProblemHighlightType getHighlightType() {
+ return myHighlightType;
+ }
+
+ @Override
+ public boolean isAfterEndOfLine() {
+ return myAfterEndOfLine;
+ }
+
+ @Override
+ public void setTextAttributes(TextAttributesKey key) {
+ myEnforcedTextAttributes = key;
+ }
+
+ public TextAttributesKey getEnforcedTextAttributes() {
+ return myEnforcedTextAttributes;
+ }
+
+ public TextRange getTextRangeForNavigation() {
+ TextRange textRange = getTextRange();
+ if (textRange == null) return null;
+ PsiElement element = getPsiElement();
+ return InjectedLanguageManager.getInstance(element.getProject()).injectedToHost(element, textRange);
+ }
+
+ public TextRange getTextRange() {
+ PsiElement startElement = getStartElement();
+ PsiElement endElement = myEndSmartPointer == null ? startElement : getEndElement();
+ if (startElement == null || endElement == null) {
+ return null;
+ }
+
+ TextRange textRange = startElement.getTextRange();
+ if (startElement == endElement) {
+ if (isAfterEndOfLine()) return new TextRange(textRange.getEndOffset(), textRange.getEndOffset());
+ if (myTextRangeInElement != null) {
+ return new TextRange(textRange.getStartOffset() + myTextRangeInElement.getStartOffset(),
+ textRange.getStartOffset() + myTextRangeInElement.getEndOffset());
+ }
+ return textRange;
+ }
+ return new TextRange(textRange.getStartOffset(), endElement.getTextRange().getEndOffset());
+ }
+
+ public Navigatable getNavigatable() {
+ return myNavigatable;
+ }
+
+ public void setNavigatable(final Navigatable navigatable) {
+ myNavigatable = navigatable;
+ }
+
+ @Override
+ @Nullable
+ public String getProblemGroup() {
+ return myProblemGroup;
+ }
+
+ @Override
+ public void setProblemGroup(@Nullable String problemGroup) {
+ myProblemGroup = problemGroup;
+ }
+
+ @Override
+ public boolean showTooltip() {
+ return myShowTooltip;
+ }
+
+ @Override
+ public String toString() {
+ PsiElement element = getPsiElement();
+ return ProblemDescriptorUtil.renderDescriptionMessage(this, element);
+ }
+}
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java
new file mode 100644
index 000000000000..2f7742dd893c
--- /dev/null
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2000-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+public class ProblemDescriptorUtil {
+ public static String extractHighlightedText(@NotNull CommonProblemDescriptor descriptor, PsiElement psiElement) {
+ if (psiElement == null || !psiElement.isValid()) return "";
+ String ref = psiElement.getText();
+ if (descriptor instanceof ProblemDescriptorBase) {
+ TextRange textRange = ((ProblemDescriptorBase)descriptor).getTextRange();
+ final TextRange elementRange = psiElement.getTextRange();
+ if (textRange != null && elementRange != null) {
+ textRange = textRange.shiftRight(-elementRange.getStartOffset());
+ if (textRange.getStartOffset() >= 0 && textRange.getEndOffset() <= elementRange.getLength()) {
+ ref = textRange.substring(ref);
+ }
+ }
+ }
+ ref = StringUtil.replaceChar(ref, '\n', ' ').trim();
+ ref = StringUtil.first(ref, 100, true);
+ return ref;
+ }
+
+ @NotNull
+ public static String renderDescriptionMessage(@NotNull CommonProblemDescriptor descriptor, PsiElement element, boolean appendLineNumber) {
+ String message = descriptor.getDescriptionTemplate();
+
+ // no message. Should not be the case if inspection correctly implemented.
+ // noinspection ConstantConditions
+ if (message == null) return "";
+
+ if (appendLineNumber && descriptor instanceof ProblemDescriptor && !message.contains("#ref") && message.contains("#loc")) {
+ final int lineNumber = ((ProblemDescriptor)descriptor).getLineNumber();
+ if (lineNumber >= 0) {
+ message = StringUtil.replace(message, "#loc", "(" + InspectionsBundle.message("inspection.export.results.at.line") + " " + lineNumber + ")");
+ }
+ }
+ message = StringUtil.replace(message, "", "'");
+ message = StringUtil.replace(message, "", "'");
+ message = StringUtil.replace(message, "#loc ", "");
+ message = StringUtil.replace(message, " #loc", "");
+ message = StringUtil.replace(message, "#loc", "");
+ if (message.contains("#ref")) {
+ String ref = extractHighlightedText(descriptor, element);
+ message = StringUtil.replace(message, "#ref", ref);
+ }
+
+ final int endIndex = message.indexOf("#end");
+ if (endIndex > 0) {
+ message = message.substring(0, endIndex);
+ }
+
+ message = StringUtil.unescapeXml(message).trim();
+ return message;
+ }
+
+ @NotNull
+ public static String renderDescriptionMessage(@NotNull CommonProblemDescriptor descriptor, PsiElement element) {
+ return renderDescriptionMessage(descriptor, element, false);
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/PsiRecursiveElementVisitor.java b/platform/core-api/src/com/intellij/psi/PsiRecursiveElementVisitor.java
similarity index 100%
rename from platform/lang-api/src/com/intellij/psi/PsiRecursiveElementVisitor.java
rename to platform/core-api/src/com/intellij/psi/PsiRecursiveElementVisitor.java
diff --git a/platform/lang-api/lang-api.iml b/platform/lang-api/lang-api.iml
index b8ffb1cfee1c..b095734ee2d1 100644
--- a/platform/lang-api/lang-api.iml
+++ b/platform/lang-api/lang-api.iml
@@ -15,6 +15,7 @@
+
diff --git a/platform/lang-impl/lang-impl.iml b/platform/lang-impl/lang-impl.iml
index 654249b5ee81..d1580e0bc141 100644
--- a/platform/lang-impl/lang-impl.iml
+++ b/platform/lang-impl/lang-impl.iml
@@ -29,6 +29,7 @@
+
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
index 0564dec0c92a..fa49d34146de 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
@@ -85,6 +85,12 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
static final String PRESENTABLE_NAME = DaemonBundle.message("pass.syntax");
private static final Key HAS_ERROR_ELEMENT = Key.create("HAS_ERROR_ELEMENT");
private static final JobLauncher JobUtil = JobLauncher.getInstance();
+ private static final Condition FILE_FILTER = new Condition() {
+ @Override
+ public boolean value(PsiFile file) {
+ return HighlightLevelUtil.shouldHighlight(file);
+ }
+ };
private final int myStartOffset;
private final int myEndOffset;
@@ -195,7 +201,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
try {
final HighlightVisitor[] filteredVisitors = filterVisitors(highlightVisitors, myFile);
Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, outside,
- HighlightLevelUtil.AnalysisLevel.HIGHLIGHT,false);
+ false, FILE_FILTER);
setProgressLimit((long)(inside.size()+outside.size()));
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
index a30b8d03bec0..4406095b71c8 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
@@ -24,7 +24,6 @@ import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
import com.intellij.codeInsight.intention.EmptyIntentionAction;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.*;
-import com.intellij.codeInspection.ui.ProblemDescriptionNode;
import com.intellij.concurrency.JobLauncher;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.lang.Language;
@@ -47,6 +46,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.Trinity;
@@ -78,6 +78,12 @@ import java.util.concurrent.ConcurrentMap;
public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass implements DumbAware {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.LocalInspectionsPass");
public static final TextRange EMPTY_PRIORITY_RANGE = TextRange.EMPTY_RANGE;
+ private static final Condition FILE_FILTER = new Condition() {
+ @Override
+ public boolean value(PsiFile file) {
+ return HighlightLevelUtil.shouldInspect(file);
+ }
+ };
private final int myStartOffset;
private final int myEndOffset;
private final TextRange myPriorityRange;
@@ -174,7 +180,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
PsiElement psiElement = descriptor.getPsiElement();
if (psiElement == null) continue;
if (InspectionManagerEx.inspectionResultSuppressed(psiElement, tool.getTool())) continue;
- List editables = ilManager.intersectWithAllEditableFragments(file, ((ProblemDescriptorImpl)descriptor).getTextRange());
+ List editables = ilManager.intersectWithAllEditableFragments(file, ((ProblemDescriptorBase)descriptor).getTextRange());
for (TextRange editable : editables) {
TextRange hostRange = documentRange.injectedToHost(editable);
QuickFix[] fixes = descriptor.getFixes();
@@ -207,7 +213,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
List inside = new ArrayList();
List outside = new ArrayList();
Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, outside,
- HighlightLevelUtil.AnalysisLevel.HIGHLIGHT_AND_INSPECT,true);
+ true, FILE_FILTER);
MultiMap tools = getToolsForElements(toolWrappers, checkDumbAwareness, inside, outside);
@@ -216,7 +222,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
List init =
visitPriorityElementsAndInit(tools, iManager, isOnTheFly, indicator, inside, session, toolWrappers, checkDumbAwareness);
- visitRestElementsAndCleanup(iManager, isOnTheFly, indicator, outside, session, init, toolWrappers, checkDumbAwareness);
+ visitRestElementsAndCleanup(indicator, outside, session, init);
+ inspectInjectedPsi(outside, isOnTheFly, indicator, iManager, false, checkDumbAwareness, toolWrappers);
indicator.checkCanceled();
@@ -292,6 +299,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
return map;
}
+ @NotNull
private List visitPriorityElementsAndInit(@NotNull MultiMap tools,
@NotNull final InspectionManagerEx iManager,
final boolean isOnTheFly,
@@ -337,7 +345,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
}
}
};
- PsiElementVisitor visitor = createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, languages);
+ PsiElementVisitor visitor = InspectionEngine.createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, languages);
synchronized (init) {
init.add(new InspectionContext(toolWrapper, holder, visitor, languages));
@@ -351,41 +359,17 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
return true;
}
- @NotNull
- private static PsiElementVisitor createVisitorAndAcceptElements(@NotNull LocalInspectionTool tool,
- @NotNull ProblemsHolder holder,
- boolean isOnTheFly,
- @NotNull LocalInspectionToolSession session,
- @NotNull List elements,
- @Nullable Collection languages) {
- PsiElementVisitor visitor = tool.buildVisitor(holder, isOnTheFly, session);
- //noinspection ConstantConditions
- if(visitor == null) {
- LOG.error("Tool " + tool + " must not return null from the buildVisitor() method");
- }
- assert !(visitor instanceof PsiRecursiveElementVisitor || visitor instanceof PsiRecursiveElementWalkingVisitor)
- : "The visitor returned from LocalInspectionTool.buildVisitor() must not be recursive. "+tool;
-
- tool.inspectionStarted(session, isOnTheFly);
- acceptElements(elements, visitor, languages);
- return visitor;
- }
-
- private void visitRestElementsAndCleanup(@NotNull final InspectionManagerEx iManager,
- final boolean isOnTheFly,
- @NotNull final ProgressIndicator indicator,
+ private void visitRestElementsAndCleanup(@NotNull final ProgressIndicator indicator,
@NotNull final List elements,
@NotNull final LocalInspectionToolSession session,
- @NotNull List init,
- @NotNull List wrappers,
- boolean checkDumbAwareness) {
+ @NotNull List init) {
Processor processor =
new Processor() {
@Override
public boolean process(InspectionContext context) {
indicator.checkCanceled();
ApplicationManager.getApplication().assertReadAccessAllowed();
- acceptElements(elements, context.visitor, context.languageIds);
+ InspectionEngine.acceptElements(elements, context.visitor, context.languageIds);
advanceProgress(1);
context.tool.getTool().inspectionFinished(session, context.holder);
@@ -399,20 +383,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
if (!result) {
throw new ProcessCanceledException();
}
- inspectInjectedPsi(elements, isOnTheFly, indicator, iManager, false, checkDumbAwareness, wrappers);
- }
-
- private static void acceptElements(@NotNull List elements,
- @NotNull PsiElementVisitor elementVisitor,
- @Nullable Collection languages) {
- //noinspection ForLoopReplaceableByForEach
- for (int i = 0, elementsSize = elements.size(); i < elementsSize; i++) {
- PsiElement element = elements.get(i);
- if (languages == null || languages.contains(element.getLanguage().getID())) {
- element.accept(elementVisitor);
- }
- ProgressManager.checkCanceled();
- }
}
void inspectInjectedPsi(@NotNull final List elements,
@@ -451,7 +421,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
@NotNull String message,
String toolTip,
PsiElement psiElement) {
- TextRange textRange = ((ProblemDescriptorImpl)problemDescriptor).getTextRange();
+ TextRange textRange = ((ProblemDescriptorBase)problemDescriptor).getTextRange();
if (textRange == null || psiElement == null) return null;
boolean isFileLevel = psiElement instanceof PsiFile && textRange.equals(psiElement.getTextRange());
@@ -555,7 +525,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
case GENERIC_ERROR:
return HighlightInfoType.ERROR;
case INFORMATION:
- final TextAttributesKey attributes = ((ProblemDescriptorImpl)problemDescriptor).getEnforcedTextAttributes();
+ final TextAttributesKey attributes = ((ProblemDescriptorBase)problemDescriptor).getEnforcedTextAttributes();
if (attributes != null) {
return new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, attributes);
}
@@ -647,7 +617,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
@NotNull HighlightInfoType level,
@NotNull Set> emptyActionRegistered,
@NotNull PsiElement element) {
- @NonNls String message = ProblemDescriptionNode.renderDescriptionMessage(descriptor, element);
+ @NonNls String message = ProblemDescriptorUtil.renderDescriptionMessage(descriptor, element);
final HighlightDisplayKey key = HighlightDisplayKey.find(tool.getShortName());
final InspectionProfile inspectionProfile = myProfileWrapper.getInspectionProfile();
@@ -697,7 +667,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
QuickFixAction.registerQuickFixAction(highlightInfo, hintAction, key);
needEmptyAction = false;
}
- if (((ProblemDescriptorImpl)descriptor).getEnforcedTextAttributes() != null) {
+ if (((ProblemDescriptorBase)descriptor).getEnforcedTextAttributes() != null) {
needEmptyAction = false;
}
if (needEmptyAction && emptyActionRegistered.add(Pair.create(new TextRange(highlightInfo.fixStartOffset, highlightInfo.fixEndOffset), tool.getShortName()))) {
@@ -785,7 +755,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
LocalInspectionToolSession injSession = new LocalInspectionToolSession(injectedPsi, 0, injectedPsi.getTextLength());
Collection languages = pair.getValue();
- createVisitorAndAcceptElements(tool, holder, isOnTheFly, injSession, elements, languages);
+ InspectionEngine.createVisitorAndAcceptElements(tool, holder, isOnTheFly, injSession, elements, languages);
tool.inspectionFinished(injSession, holder);
List problems = holder.getResults();
if (!problems.isEmpty()) {
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorComposer.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorComposer.java
index abe4ca9e7e5d..4e983b91191b 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorComposer.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorComposer.java
@@ -16,13 +16,9 @@
package com.intellij.codeInspection.ex;
-import com.intellij.codeInspection.CommonProblemDescriptor;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.codeInspection.QuickFix;
+import com.intellij.codeInspection.*;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
-import com.intellij.codeInspection.ui.ProblemDescriptionNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -151,7 +147,7 @@ public class DescriptorComposer extends HTMLComposerImpl {
}
anchor.append("\">");
- anchor.append(ProblemDescriptionNode.extractHighlightedText(description, expression).replaceAll("\\$", "\\\\\\$"));
+ anchor.append(ProblemDescriptorUtil.extractHighlightedText(description, expression).replaceAll("\\$", "\\\\\\$"));
//noinspection HardCodedStringLiteral
anchor.append("");
}
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorProviderInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorProviderInspection.java
index 2914f1340600..8ef537d3460d 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorProviderInspection.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorProviderInspection.java
@@ -20,7 +20,6 @@ import com.intellij.codeInspection.*;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.reference.RefModule;
-import com.intellij.codeInspection.ui.ProblemDescriptionNode;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -278,7 +277,8 @@ public abstract class DescriptorProviderInspection extends InspectionTool implem
@NonNls final String template = description.getDescriptionTemplate();
int line = description instanceof ProblemDescriptor ? ((ProblemDescriptor)description).getLineNumber() : -1;
final PsiElement psiElement = description instanceof ProblemDescriptor ? ((ProblemDescriptor)description).getPsiElement() : null;
- @NonNls String problemText = StringUtil.replace(StringUtil.replace(template, "#ref", psiElement != null ? ProblemDescriptionNode.extractHighlightedText(description, psiElement): "") , " #loc ", " ");
+ @NonNls String problemText = StringUtil.replace(StringUtil.replace(template, "#ref", psiElement != null ? ProblemDescriptorUtil
+ .extractHighlightedText(description, psiElement): "") , " #loc ", " ");
Element element = refEntity.getRefManager().export(refEntity, parentNode, line);
if (element == null) return;
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java
index 11e980ef59b2..6615e3dc660e 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java
@@ -30,7 +30,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NotNullLazyValue;
-import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowId;
@@ -49,22 +48,20 @@ import org.jetbrains.annotations.TestOnly;
import java.util.HashSet;
import java.util.Set;
-public class InspectionManagerEx extends InspectionManager {
+public class InspectionManagerEx extends InspectionManagerBase {
private GlobalInspectionContextImpl myGlobalInspectionContext = null;
- private final Project myProject;
@NonNls private String myCurrentProfileName;
private final NotNullLazyValue myContentManager;
-
private final Set myRunningContexts = new HashSet();
- public InspectionManagerEx(Project project) {
- myProject = project;
+ public InspectionManagerEx(final Project project) {
+ super(project);
if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
myContentManager = new NotNullLazyValue() {
@NotNull
@Override
protected ContentManager compute() {
- return ContentFactory.SERVICE.getInstance().createContentManager(new TabbedPaneContentUI(), true, myProject);
+ return ContentFactory.SERVICE.getInstance().createContentManager(new TabbedPaneContentUI(), true, project);
}
};
}
@@ -73,9 +70,9 @@ public class InspectionManagerEx extends InspectionManager {
@NotNull
@Override
protected ContentManager compute() {
- ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
+ ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project);
ToolWindow toolWindow =
- toolWindowManager.registerToolWindow(ToolWindowId.INSPECTION, true, ToolWindowAnchor.BOTTOM, myProject);
+ toolWindowManager.registerToolWindow(ToolWindowId.INSPECTION, true, ToolWindowAnchor.BOTTOM, project);
ContentManager contentManager = toolWindow.getContentManager();
toolWindow.setIcon(AllIcons.Toolwindows.ToolWindowInspection);
new ContentManagerWatcher(toolWindow, contentManager);
@@ -85,103 +82,26 @@ public class InspectionManagerEx extends InspectionManager {
}
}
- @Override
- @NotNull
- public Project getProject() {
- return myProject;
- }
-
- @Override
- @NotNull
- public CommonProblemDescriptor createProblemDescriptor(@NotNull String descriptionTemplate, QuickFix... fixes) {
- return new CommonProblemDescriptorImpl(fixes, descriptionTemplate);
- }
-
- @Override
- @NotNull
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
- @NotNull String descriptionTemplate,
- LocalQuickFix fix,
- @NotNull ProblemHighlightType highlightType,
- boolean onTheFly) {
- LocalQuickFix[] quickFixes = fix != null ? new LocalQuickFix[]{fix} : null;
- return createProblemDescriptor(psiElement, descriptionTemplate, onTheFly, quickFixes, highlightType);
- }
-
- @Override
- @NotNull
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
- @NotNull String descriptionTemplate,
- boolean onTheFly,
- LocalQuickFix[] fixes,
- @NotNull ProblemHighlightType highlightType) {
- return createProblemDescriptor(psiElement, descriptionTemplate, fixes, highlightType, onTheFly, false);
- }
-
- @Override
- @NotNull
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
- @NotNull String descriptionTemplate,
- LocalQuickFix[] fixes,
- @NotNull ProblemHighlightType highlightType,
- boolean onTheFly,
- boolean isAfterEndOfLine) {
- return new ProblemDescriptorImpl(psiElement, psiElement, descriptionTemplate, fixes, highlightType, isAfterEndOfLine, null, onTheFly);
- }
-
- @Override
- @NotNull
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement startElement,
- @NotNull PsiElement endElement,
- @NotNull String descriptionTemplate,
- @NotNull ProblemHighlightType highlightType,
- boolean onTheFly,
- LocalQuickFix... fixes) {
- return new ProblemDescriptorImpl(startElement, endElement, descriptionTemplate, fixes, highlightType, false, null, onTheFly);
- }
@NotNull
- @Override
- public ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
- final TextRange rangeInElement,
- @NotNull final String descriptionTemplate,
- @NotNull final ProblemHighlightType highlightType,
- boolean onTheFly,
- final LocalQuickFix... fixes) {
- return new ProblemDescriptorImpl(psiElement, psiElement, descriptionTemplate, fixes, highlightType, false, rangeInElement, onTheFly);
- }
-
- @NotNull
- @Override
public ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
@NotNull final String descriptionTemplate,
@NotNull final ProblemHighlightType highlightType,
@Nullable final HintAction hintAction,
boolean onTheFly,
final LocalQuickFix... fixes) {
-
return new ProblemDescriptorImpl(psiElement, psiElement, descriptionTemplate, fixes, highlightType, false, null, hintAction, onTheFly);
}
- @NotNull
- @Override
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
- @NotNull String descriptionTemplate,
- boolean showTooltip,
- @NotNull ProblemHighlightType highlightType, boolean onTheFly, LocalQuickFix... fixes) {
- return new ProblemDescriptorImpl(psiElement, psiElement, descriptionTemplate, fixes, highlightType, false, null, showTooltip, null,
- onTheFly);
- }
-
public GlobalInspectionContextImpl createNewGlobalContext(boolean reuse) {
if (reuse) {
if (myGlobalInspectionContext == null) {
- myGlobalInspectionContext = new GlobalInspectionContextImpl(myProject, myContentManager);
+ myGlobalInspectionContext = new GlobalInspectionContextImpl(getProject(), myContentManager);
}
myRunningContexts.add(myGlobalInspectionContext);
return myGlobalInspectionContext;
}
- final GlobalInspectionContextImpl inspectionContext = new GlobalInspectionContextImpl(myProject, myContentManager);
+ final GlobalInspectionContextImpl inspectionContext = new GlobalInspectionContextImpl(getProject(), myContentManager);
myRunningContexts.add(inspectionContext);
return inspectionContext;
}
@@ -192,7 +112,7 @@ public class InspectionManagerEx extends InspectionManager {
public String getCurrentProfile() {
if (myCurrentProfileName == null) {
- final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(myProject);
+ final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(getProject());
myCurrentProfileName = profileManager.getProjectProfile();
if (myCurrentProfileName == null) {
myCurrentProfileName = InspectionProfileManager.getInstance().getRootProfile().getName();
@@ -241,62 +161,7 @@ public class InspectionManagerEx extends InspectionManager {
return false;
}
- @Override
- @Deprecated
@NotNull
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
- @NotNull String descriptionTemplate,
- LocalQuickFix fix,
- @NotNull ProblemHighlightType highlightType) {
- LocalQuickFix[] quickFixes = fix != null ? new LocalQuickFix[]{fix} : null;
- return createProblemDescriptor(psiElement, descriptionTemplate, false, quickFixes, highlightType);
- }
-
- @Override
- @Deprecated
- @NotNull
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
- @NotNull String descriptionTemplate,
- LocalQuickFix[] fixes,
- @NotNull ProblemHighlightType highlightType) {
- return createProblemDescriptor(psiElement, descriptionTemplate, fixes, highlightType, false, false);
- }
-
- @Override
- @Deprecated
- @NotNull
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
- @NotNull String descriptionTemplate,
- LocalQuickFix[] fixes,
- @NotNull ProblemHighlightType highlightType,
- boolean isAfterEndOfLine) {
- return new ProblemDescriptorImpl(psiElement, psiElement, descriptionTemplate, fixes, highlightType, isAfterEndOfLine, null, true);
- }
-
- @Override
- @Deprecated
- @NotNull
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement startElement,
- @NotNull PsiElement endElement,
- @NotNull String descriptionTemplate,
- @NotNull ProblemHighlightType highlightType,
- LocalQuickFix... fixes) {
- return new ProblemDescriptorImpl(startElement, endElement, descriptionTemplate, fixes, highlightType, false, null, true);
- }
-
- @NotNull
- @Override
- @Deprecated
- public ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
- final TextRange rangeInElement,
- @NotNull final String descriptionTemplate,
- @NotNull final ProblemHighlightType highlightType,
- final LocalQuickFix... fixes) {
- return new ProblemDescriptorImpl(psiElement, psiElement, descriptionTemplate, fixes, highlightType, false, rangeInElement, true);
- }
-
- @NotNull
- @Override
@Deprecated
public ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
@NotNull final String descriptionTemplate,
@@ -307,18 +172,6 @@ public class InspectionManagerEx extends InspectionManager {
return new ProblemDescriptorImpl(psiElement, psiElement, descriptionTemplate, fixes, highlightType, false, null, hintAction, true);
}
- @NotNull
- @Deprecated
- @Override
- public ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement,
- @NotNull String descriptionTemplate,
- boolean showTooltip,
- @NotNull ProblemHighlightType highlightType,
- LocalQuickFix... fixes) {
- return new ProblemDescriptorImpl(psiElement, psiElement, descriptionTemplate, fixes, highlightType, false, null, showTooltip, null,
- true);
- }
-
@TestOnly
public NotNullLazyValue getContentManager() {
return myContentManager;
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java
index 6011a97136b3..2955f369e108 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java
@@ -17,37 +17,16 @@
package com.intellij.codeInspection.ex;
import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.ui.ProblemDescriptionNode;
-import com.intellij.lang.injection.InjectedLanguageManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.colors.TextAttributesKey;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
-import com.intellij.pom.Navigatable;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author max
*/
-public class ProblemDescriptorImpl extends CommonProblemDescriptorImpl implements ProblemDescriptor {
- private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.ProblemDescriptorImpl");
-
- @NotNull private final SmartPsiElementPointer myStartSmartPointer;
- @Nullable private final SmartPsiElementPointer myEndSmartPointer;
-
- private final ProblemHighlightType myHighlightType;
- private Navigatable myNavigatable;
- private final boolean myAfterEndOfLine;
- private final TextRange myTextRangeInElement;
- private final boolean myShowTooltip;
+public class ProblemDescriptorImpl extends ProblemDescriptorBase implements ProblemDescriptor {
private final HintAction myHintAction;
- private TextAttributesKey myEnforcedTextAttributes;
- private int myLineNumber = -1;
- private String myProblemGroup;
public ProblemDescriptorImpl(@NotNull PsiElement startElement,
@NotNull PsiElement endElement,
@@ -83,163 +62,11 @@ public class ProblemDescriptorImpl extends CommonProblemDescriptorImpl implement
@Nullable HintAction hintAction,
boolean onTheFly) {
- super(fixes, descriptionTemplate);
- myShowTooltip = tooltip;
+ super(startElement, endElement, descriptionTemplate, fixes, highlightType, isAfterEndOfLine, rangeInElement, tooltip, onTheFly);
myHintAction = hintAction;
- PsiFile startContainingFile = startElement.getContainingFile();
- LOG.assertTrue(startContainingFile != null && startContainingFile.isValid() || startElement.isValid(), startElement);
- PsiFile endContainingFile = startElement == endElement ? startContainingFile : endElement.getContainingFile();
- LOG.assertTrue(startElement == endElement || endContainingFile != null && endContainingFile.isValid() || endElement.isValid(), endElement);
- assertPhysical(startElement);
- if (startElement != endElement) assertPhysical(endElement);
-
- final TextRange startElementRange = startElement.getTextRange();
- LOG.assertTrue(startElementRange != null, startElement);
- final TextRange endElementRange = endElement.getTextRange();
- LOG.assertTrue(endElementRange != null, endElement);
- if (startElementRange.getStartOffset() >= endElementRange.getEndOffset()) {
- if (!(startElement instanceof PsiFile && endElement instanceof PsiFile)) {
- LOG.error("Empty PSI elements should not be passed to createDescriptor. Start: " + startElement + ", end: " + endElement);
- }
- }
-
- myHighlightType = highlightType;
- final Project project = startContainingFile == null ? startElement.getProject() : startContainingFile.getProject();
- final SmartPointerManager manager = SmartPointerManager.getInstance(project);
- myStartSmartPointer = manager.createSmartPsiElementPointer(startElement, startContainingFile);
- myEndSmartPointer = startElement == endElement ? null : manager.createSmartPsiElementPointer(endElement, endContainingFile);
-
- myAfterEndOfLine = isAfterEndOfLine;
- myTextRangeInElement = rangeInElement;
- }
-
- protected void assertPhysical(final PsiElement element) {
- if (!element.isPhysical()) {
- LOG.error("Non-physical PsiElement. Physical element is required to be able to anchor the problem in the source tree: " +
- element + "; file: " + element.getContainingFile());
- }
- }
-
- @Override
- public PsiElement getPsiElement() {
- PsiElement startElement = getStartElement();
- if (myEndSmartPointer == null) {
- return startElement;
- }
- PsiElement endElement = getEndElement();
- if (startElement == endElement) {
- return startElement;
- }
- if (startElement == null || endElement == null) return null;
- return PsiTreeUtil.findCommonParent(startElement, endElement);
- }
-
- @Override
- public PsiElement getStartElement() {
- return myStartSmartPointer.getElement();
- }
-
- @Override
- public PsiElement getEndElement() {
- return myEndSmartPointer == null ? getStartElement() : myEndSmartPointer.getElement();
- }
-
- @Override
- public int getLineNumber() {
- if (myLineNumber == -1) {
- PsiElement psiElement = getPsiElement();
- if (psiElement == null) return -1;
- if (!psiElement.isValid()) return -1;
- LOG.assertTrue(psiElement.isPhysical());
- InjectedLanguageManager manager = InjectedLanguageManager.getInstance(psiElement.getProject());
- PsiFile containingFile = manager.getTopLevelFile(psiElement);
- Document document = PsiDocumentManager.getInstance(psiElement.getProject()).getDocument(containingFile);
- if (document == null) return -1;
- TextRange textRange = getTextRange();
- if (textRange == null) return -1;
- textRange = manager.injectedToHost(psiElement, textRange);
- myLineNumber = document.getLineNumber(textRange.getStartOffset()) + 1;
- }
- return myLineNumber;
- }
-
- @NotNull
- @Override
- public ProblemHighlightType getHighlightType() {
- return myHighlightType;
- }
-
- @Override
- public boolean isAfterEndOfLine() {
- return myAfterEndOfLine;
- }
-
- @Override
- public void setTextAttributes(TextAttributesKey key) {
- myEnforcedTextAttributes = key;
- }
-
- public TextAttributesKey getEnforcedTextAttributes() {
- return myEnforcedTextAttributes;
- }
-
- public TextRange getTextRangeForNavigation() {
- TextRange textRange = getTextRange();
- if (textRange == null) return null;
- PsiElement element = getPsiElement();
- return InjectedLanguageManager.getInstance(element.getProject()).injectedToHost(element, textRange);
- }
-
- public TextRange getTextRange() {
- PsiElement startElement = getStartElement();
- PsiElement endElement = myEndSmartPointer == null ? startElement : getEndElement();
- if (startElement == null || endElement == null) {
- return null;
- }
-
- TextRange textRange = startElement.getTextRange();
- if (startElement == endElement) {
- if (isAfterEndOfLine()) return new TextRange(textRange.getEndOffset(), textRange.getEndOffset());
- if (myTextRangeInElement != null) {
- return new TextRange(textRange.getStartOffset() + myTextRangeInElement.getStartOffset(),
- textRange.getStartOffset() + myTextRangeInElement.getEndOffset());
- }
- return textRange;
- }
- return new TextRange(textRange.getStartOffset(), endElement.getTextRange().getEndOffset());
- }
-
- public Navigatable getNavigatable() {
- return myNavigatable;
- }
-
- public void setNavigatable(final Navigatable navigatable) {
- myNavigatable = navigatable;
}
public HintAction getHintAction() {
return myHintAction;
}
-
- @Override
- @Nullable
- public String getProblemGroup() {
- return myProblemGroup;
- }
-
- @Override
- public void setProblemGroup(@Nullable String problemGroup) {
- myProblemGroup = problemGroup;
- }
-
- @Override
- public boolean showTooltip() {
- return myShowTooltip;
- }
-
- @Override
- public String toString() {
- PsiElement element = getPsiElement();
- return ProblemDescriptionNode.renderDescriptionMessage(this, element);
- }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java
index 264ea0b0933f..db9082e26bc2 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java
@@ -16,20 +16,13 @@
package com.intellij.codeInspection.ui;
-import com.intellij.codeInspection.CommonProblemDescriptor;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.codeInspection.ProblemHighlightType;
+import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.DescriptorProviderInspection;
-import com.intellij.codeInspection.ex.ProblemDescriptorImpl;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.icons.AllIcons;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.psi.PsiElement;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -69,8 +62,8 @@ public class ProblemDescriptionNode extends InspectionTreeNode {
@Override
public Icon getIcon(boolean expanded) {
- if (myDescriptor instanceof ProblemDescriptorImpl) {
- ProblemHighlightType problemHighlightType = ((ProblemDescriptorImpl)myDescriptor).getHighlightType();
+ if (myDescriptor instanceof ProblemDescriptorBase) {
+ ProblemHighlightType problemHighlightType = ((ProblemDescriptorBase)myDescriptor).getHighlightType();
if (problemHighlightType == ProblemHighlightType.ERROR) return AllIcons.General.Error;
if (problemHighlightType == ProblemHighlightType.GENERIC_ERROR_OR_WARNING) return AllIcons.General.Warning;
}
@@ -122,62 +115,6 @@ public class ProblemDescriptionNode extends InspectionTreeNode {
if (descriptor == null) return "";
PsiElement element = descriptor instanceof ProblemDescriptor ? ((ProblemDescriptor)descriptor).getPsiElement() : null;
- return renderDescriptionMessage(descriptor, element, true)/*.replaceAll("<[^>]*>", "")*/;
- }
-
- @NotNull
- public static String renderDescriptionMessage(@NotNull CommonProblemDescriptor descriptor, PsiElement element) {
- return renderDescriptionMessage(descriptor, element, false);
- }
-
- @NotNull
- public static String renderDescriptionMessage(@NotNull CommonProblemDescriptor descriptor, PsiElement element, boolean appendLineNumber) {
- String message = descriptor.getDescriptionTemplate();
-
- // no message. Should not be the case if inspection correctly implemented.
- // noinspection ConstantConditions
- if (message == null) return "";
-
- if (appendLineNumber && descriptor instanceof ProblemDescriptor && !message.contains("#ref") && message.contains("#loc")) {
- final int lineNumber = ((ProblemDescriptor)descriptor).getLineNumber();
- if (lineNumber >= 0) {
- message = StringUtil.replace(message, "#loc", "(" + InspectionsBundle.message("inspection.export.results.at.line") + " " + lineNumber + ")");
- }
- }
- message = StringUtil.replace(message, "", "'");
- message = StringUtil.replace(message, "", "'");
- message = StringUtil.replace(message, "#loc ", "");
- message = StringUtil.replace(message, " #loc", "");
- message = StringUtil.replace(message, "#loc", "");
- if (message.contains("#ref")) {
- String ref = extractHighlightedText(descriptor, element);
- message = StringUtil.replace(message, "#ref", ref);
- }
-
- final int endIndex = message.indexOf("#end");
- if (endIndex > 0) {
- message = message.substring(0, endIndex);
- }
-
- message = StringUtil.unescapeXml(message).trim();
- return message;
- }
-
- public static String extractHighlightedText(@NotNull CommonProblemDescriptor descriptor, PsiElement psiElement) {
- if (psiElement == null || !psiElement.isValid()) return "";
- String ref = psiElement.getText();
- if (descriptor instanceof ProblemDescriptorImpl) {
- TextRange textRange = ((ProblemDescriptorImpl)descriptor).getTextRange();
- final TextRange elementRange = psiElement.getTextRange();
- if (textRange != null && elementRange != null) {
- textRange = textRange.shiftRight(-elementRange.getStartOffset());
- if (textRange.getStartOffset() >= 0 && textRange.getEndOffset() <= elementRange.getLength()) {
- ref = textRange.substring(ref);
- }
- }
- }
- ref = StringUtil.replaceChar(ref, '\n', ' ').trim();
- ref = StringUtil.first(ref, 100, true);
- return ref;
+ return ProblemDescriptorUtil.renderDescriptionMessage(descriptor, element, true)/*.replaceAll("<[^>]*>", "")*/;
}
}
diff --git a/platform/platform-api/platform-api.iml b/platform/platform-api/platform-api.iml
index 93c9f0ebea70..480d221be4eb 100644
--- a/platform/platform-api/platform-api.iml
+++ b/platform/platform-api/platform-api.iml
@@ -31,6 +31,7 @@
+
diff --git a/platform/platform-api/src/com/intellij/codeHighlighting/DefaultIconCreator.java b/platform/platform-api/src/com/intellij/codeHighlighting/DefaultIconCreator.java
new file mode 100644
index 000000000000..e06f22325aa7
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/codeHighlighting/DefaultIconCreator.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeHighlighting;
+
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+public class DefaultIconCreator implements HighlightDisplayLevel.IconCreator {
+ @Override
+ public Icon createIcon(@NotNull TextAttributesKey key) {
+ final EditorColorsManager manager = EditorColorsManager.getInstance();
+ if (manager != null) {
+ final EditorColorsScheme globalScheme = manager.getGlobalScheme();
+ return HighlightDisplayLevel.createIconByMask(globalScheme.getAttributes(key).getErrorStripeColor());
+ }
+
+ return null;
+ }
+}
diff --git a/platform/platform-impl/platform-impl.iml b/platform/platform-impl/platform-impl.iml
index edd1c9c2d2f2..085849048137 100644
--- a/platform/platform-impl/platform-impl.iml
+++ b/platform/platform-impl/platform-impl.iml
@@ -36,6 +36,7 @@
+
diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
index 873b48d0ff6a..b56a6dd1a3fd 100644
--- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
@@ -344,6 +344,8 @@
+
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index ecbc500deb3e..45a262c8eda2 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -790,7 +790,7 @@
-
+
diff --git a/spellchecker/src/com/intellij/spellchecker/quickfixes/AcceptWordAsCorrect.java b/spellchecker/src/com/intellij/spellchecker/quickfixes/AcceptWordAsCorrect.java
index dd47b0c3d591..0409df133073 100644
--- a/spellchecker/src/com/intellij/spellchecker/quickfixes/AcceptWordAsCorrect.java
+++ b/spellchecker/src/com/intellij/spellchecker/quickfixes/AcceptWordAsCorrect.java
@@ -16,7 +16,7 @@
package com.intellij.spellchecker.quickfixes;
import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.codeInspection.ui.ProblemDescriptionNode;
+import com.intellij.codeInspection.ProblemDescriptorUtil;
import com.intellij.openapi.actionSystem.Anchor;
import com.intellij.openapi.project.Project;
import com.intellij.spellchecker.SpellCheckerManager;
@@ -57,7 +57,7 @@ public class AcceptWordAsCorrect implements SpellCheckerQuickFix {
if (myWord != null) {
spellCheckerManager.acceptWordAsCorrect(myWord, project);
} else {
- spellCheckerManager.acceptWordAsCorrect(ProblemDescriptionNode.extractHighlightedText(descriptor, descriptor.getPsiElement()), project);
+ spellCheckerManager.acceptWordAsCorrect(ProblemDescriptorUtil.extractHighlightedText(descriptor, descriptor.getPsiElement()), project);
}
}