mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
analysis modules introduced allowing to use inspection engine from the core
This commit is contained in:
Generated
+2
@@ -10,6 +10,8 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-xml.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-xml.iml" group="plugins/IntelliLang" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/IntentionPowerPak/IntentionPowerPackPlugin.iml" filepath="$PROJECT_DIR$/plugins/IntentionPowerPak/IntentionPowerPackPlugin.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" filepath="$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/analysis-api/analysis-api.iml" filepath="$PROJECT_DIR$/platform/analysis-api/analysis-api.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/analysis-impl/analysis-impl.iml" filepath="$PROJECT_DIR$/platform/analysis-impl/analysis-impl.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/android/android.iml" filepath="$PROJECT_DIR$/plugins/android/android.iml" group="plugins/Android" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/android/common/android-common.iml" filepath="$PROJECT_DIR$/plugins/android/common/android-common.iml" group="plugins/Android" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/android-designer/android-designer.iml" filepath="$PROJECT_DIR$/plugins/android-designer/android-designer.iml" group="plugins/Android" />
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="library" name="JDOM" level="project" />
|
||||
<orderEntry type="module" module-name="extensions" />
|
||||
<orderEntry type="module" module-name="core-api" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
+21
-8
@@ -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<IconCreator> 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) {
|
||||
-19
@@ -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
|
||||
/**
|
||||
+16
-13
@@ -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) {
|
||||
}
|
||||
+5
-2
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
+1
-1
@@ -47,4 +47,4 @@ public class LocalInspectionToolSession extends UserDataHolderBase {
|
||||
public int getEndOffset() {
|
||||
return myEndOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -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<HighlightSeverity>, JDOMExt
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final HighlightSeverity highlightSeverity) {
|
||||
public int compareTo(@NotNull final HighlightSeverity highlightSeverity) {
|
||||
return myVal - highlightSeverity.myVal;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="analysis-api" exported="" />
|
||||
<orderEntry type="module" module-name="core-api" />
|
||||
<orderEntry type="module" module-name="core-impl" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="module" module-name="extensions" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
+3
-4
@@ -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<PsiElement> inside,
|
||||
@NotNull List<PsiElement> outside,
|
||||
@NotNull HighlightLevelUtil.AnalysisLevel level,
|
||||
boolean includeParents) {
|
||||
boolean includeParents,
|
||||
@NotNull Condition<PsiFile> 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);
|
||||
}
|
||||
}
|
||||
@@ -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<PsiElement> elements,
|
||||
@Nullable Collection<String> 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<PsiElement> elements,
|
||||
@NotNull PsiElementVisitor elementVisitor,
|
||||
@Nullable Collection<String> 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<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionTool> 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<ProblemDescriptor> resultDescriptors = Collections.synchronizedList(new ArrayList<ProblemDescriptor>());
|
||||
final List<PsiElement> elements = new ArrayList<PsiElement>();
|
||||
|
||||
TextRange range = file.getTextRange();
|
||||
final LocalInspectionToolSession session = new LocalInspectionToolSession(file, range.getStartOffset(), range.getEndOffset());
|
||||
Divider.divideInsideAndOutside(file, range.getStartOffset(), range.getEndOffset(), range, elements, Collections.<PsiElement>emptyList(), true, Condition.TRUE);
|
||||
|
||||
boolean result = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(tools, indicator, failFastOnAcquireReadAction, new Processor<LocalInspectionTool>() {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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, "<code>", "'");
|
||||
message = StringUtil.replace(message, "</code>", "'");
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
<orderEntry type="module" module-name="projectModel-api" exported="" />
|
||||
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Mocks" level="project" />
|
||||
<orderEntry type="module" module-name="analysis-api" exported="" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
<orderEntry type="library" name="gson" level="project" />
|
||||
<orderEntry type="module" module-name="jps-model-impl" />
|
||||
<orderEntry type="module" module-name="analysis-impl" exported="" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
+7
-1
@@ -85,6 +85,12 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
|
||||
static final String PRESENTABLE_NAME = DaemonBundle.message("pass.syntax");
|
||||
private static final Key<Boolean> HAS_ERROR_ELEMENT = Key.create("HAS_ERROR_ELEMENT");
|
||||
private static final JobLauncher JobUtil = JobLauncher.getInstance();
|
||||
private static final Condition<PsiFile> FILE_FILTER = new Condition<PsiFile>() {
|
||||
@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()));
|
||||
|
||||
|
||||
+21
-51
@@ -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<PsiFile> FILE_FILTER = new Condition<PsiFile>() {
|
||||
@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<TextRange> editables = ilManager.intersectWithAllEditableFragments(file, ((ProblemDescriptorImpl)descriptor).getTextRange());
|
||||
List<TextRange> 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<PsiElement> inside = new ArrayList<PsiElement>();
|
||||
List<PsiElement> outside = new ArrayList<PsiElement>();
|
||||
Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, outside,
|
||||
HighlightLevelUtil.AnalysisLevel.HIGHLIGHT_AND_INSPECT,true);
|
||||
true, FILE_FILTER);
|
||||
|
||||
MultiMap<LocalInspectionToolWrapper, String> tools = getToolsForElements(toolWrappers, checkDumbAwareness, inside, outside);
|
||||
|
||||
@@ -216,7 +222,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
|
||||
|
||||
List<InspectionContext> 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<InspectionContext> visitPriorityElementsAndInit(@NotNull MultiMap<LocalInspectionToolWrapper, String> 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<PsiElement> elements,
|
||||
@Nullable Collection<String> 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<PsiElement> elements,
|
||||
@NotNull final LocalInspectionToolSession session,
|
||||
@NotNull List<InspectionContext> init,
|
||||
@NotNull List<LocalInspectionToolWrapper> wrappers,
|
||||
boolean checkDumbAwareness) {
|
||||
@NotNull List<InspectionContext> init) {
|
||||
Processor<InspectionContext> processor =
|
||||
new Processor<InspectionContext>() {
|
||||
@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<PsiElement> elements,
|
||||
@NotNull PsiElementVisitor elementVisitor,
|
||||
@Nullable Collection<String> 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<PsiElement> 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<Pair<TextRange, String>> 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<String> languages = pair.getValue();
|
||||
createVisitorAndAcceptElements(tool, holder, isOnTheFly, injSession, elements, languages);
|
||||
InspectionEngine.createVisitorAndAcceptElements(tool, holder, isOnTheFly, injSession, elements, languages);
|
||||
tool.inspectionFinished(injSession, holder);
|
||||
List<ProblemDescriptor> problems = holder.getResults();
|
||||
if (!problems.isEmpty()) {
|
||||
|
||||
@@ -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("</a>");
|
||||
}
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
@@ -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<ContentManager> myContentManager;
|
||||
|
||||
private final Set<GlobalInspectionContextImpl> myRunningContexts = new HashSet<GlobalInspectionContextImpl>();
|
||||
|
||||
public InspectionManagerEx(Project project) {
|
||||
myProject = project;
|
||||
public InspectionManagerEx(final Project project) {
|
||||
super(project);
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
|
||||
myContentManager = new NotNullLazyValue<ContentManager>() {
|
||||
@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<ContentManager> getContentManager() {
|
||||
return myContentManager;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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, "<code>", "'");
|
||||
message = StringUtil.replace(message, "</code>", "'");
|
||||
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("<[^>]*>", "")*/;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<orderEntry type="library" name="Netty" level="project" />
|
||||
<orderEntry type="library" name="proxy-vole" level="project" />
|
||||
<orderEntry type="library" name="miglayout-swing" level="project" />
|
||||
<orderEntry type="module" module-name="analysis-api" exported="" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@
|
||||
<orderEntry type="library" name="Sanselan" level="project" />
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
<orderEntry type="module" module-name="jps-model-impl" />
|
||||
<orderEntry type="module" module-name="analysis-impl" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -344,6 +344,8 @@
|
||||
<extensionPoint name="refactoring.moveHandler" interface="com.intellij.refactoring.move.MoveHandlerDelegate"/>
|
||||
<extensionPoint name="refactoring.moveDirectoryWithClassesHelper"
|
||||
interface="com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesHelper"/>
|
||||
<extensionPoint name="codeHighlighting.iconCreator"
|
||||
interface="com.intellij.codeHighlighting.HighlightDisplayLevel$IconCreator"/>
|
||||
|
||||
<extensionPoint name="refactoring.helper" interface="com.intellij.refactoring.RefactoringHelper"/>
|
||||
<extensionPoint name="refactoring.inlineHandler" beanClass="com.intellij.lang.LanguageExtensionPoint">
|
||||
|
||||
@@ -790,7 +790,7 @@
|
||||
|
||||
<refactoring.moveDirectoryWithClassesHelper
|
||||
implementation="com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesHelper$Default" order="last"/>
|
||||
<!--<codeHighlighting.iconCreator implementation="com.intellij.codeHighlighting.DefaultIconCreator"/>-->
|
||||
<codeHighlighting.iconCreator implementation="com.intellij.codeHighlighting.DefaultIconCreator"/>
|
||||
|
||||
<checkinHandlerFactory implementation="com.intellij.openapi.vcs.checkin.ReformatCheckinHandlerFactory"/>
|
||||
<checkinHandlerFactory implementation="com.intellij.openapi.vcs.checkin.OptimizeOptionsCheckinHandlerFactory"/>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user