diff --git a/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java index f3433f373d6d..21e6574895fd 100644 --- a/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java @@ -123,7 +123,7 @@ public abstract class InspectionTestCase extends PsiTestCase { } } - protected void setupRootModel(final String testDir, final VirtualFile[] sourceDir, final String jdkName) { + protected void setupRootModel(final String testDir, final VirtualFile[] sourceDir, final String sdkName) { VirtualFile projectDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(testDir)); assertNotNull(projectDir); sourceDir[0] = projectDir.findChild("src"); @@ -143,18 +143,22 @@ public abstract class InspectionTestCase extends PsiTestCase { // IMPORTANT! The jdk must be obtained in a way it is obtained in the normal program! //ProjectJdkEx jdk = ProjectJdkTable.getInstance().getInternalJdk(); - Sdk jdk; - if ("java 1.5".equals(jdkName)) { - jdk = JavaSdkImpl.getMockJdk15(jdkName); + + rootModel.setSdk(getTestProjectSdk(sdkName)); + + rootModel.commit(); + } + + protected Sdk getTestProjectSdk(String sdkName) { + Sdk sdk; + if ("java 1.5".equals(sdkName)) { + sdk = JavaSdkImpl.getMockJdk15(sdkName); LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_5); } else { - jdk = JavaSdkImpl.getMockJdk(jdkName); + sdk = JavaSdkImpl.getMockJdk(sdkName); } - - rootModel.setSdk(jdk); - - rootModel.commit(); + return sdk; } @NonNls diff --git a/platform/lang-impl/src/com/intellij/codeInspection/AnnotatorBasedInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/AnnotatorBasedInspection.java new file mode 100644 index 000000000000..0c31851cd57c --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/AnnotatorBasedInspection.java @@ -0,0 +1,145 @@ +package com.intellij.codeInspection; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.lang.LanguageAnnotators; +import com.intellij.lang.annotation.Annotator; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotation; +import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiLanguageInjectionHost; +import com.intellij.psi.PsiRecursiveElementVisitor; +import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl; +import com.intellij.openapi.util.TextRange; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author yole + */ +public class AnnotatorBasedInspection extends GlobalInspectionTool { + @Override + public boolean isGraphNeeded() { + return false; + } + + @NotNull + @Override + public HighlightDisplayLevel getDefaultLevel() { + return HighlightDisplayLevel.ERROR; + } + + @Override + public void runInspection(AnalysisScope scope, + final InspectionManager manager, + final GlobalInspectionContext globalContext, + final ProblemDescriptionsProcessor problemDescriptionsProcessor) { + scope.accept(new MyPsiRecursiveElementVisitor(manager, globalContext, problemDescriptionsProcessor)); + } + + @Nls + @NotNull + @Override + public String getGroupDisplayName() { + return "General"; + } + + @Nls + @NotNull + @Override + public String getDisplayName() { + return "Annotator"; + } + + @NotNull + @Override + public String getShortName() { + return "Annotator"; + } + + private static class MyPsiRecursiveElementVisitor extends PsiRecursiveElementVisitor implements PsiLanguageInjectionHost.InjectedPsiVisitor { + private final InspectionManager manager; + private final GlobalInspectionContext globalContext; + private final ProblemDescriptionsProcessor problemDescriptionsProcessor; + private AnnotationHolder myHolder; + private List annotators; + + public MyPsiRecursiveElementVisitor(final InspectionManager manager, final GlobalInspectionContext globalContext, + final ProblemDescriptionsProcessor problemDescriptionsProcessor) { + this.manager = manager; + this.globalContext = globalContext; + this.problemDescriptionsProcessor = problemDescriptionsProcessor; + myHolder = new AnnotationHolderImpl() { + @Override + public Annotation createErrorAnnotation(@NotNull PsiElement elt, String message) { + return createProblem(elt, message, ProblemHighlightType.ERROR, HighlightSeverity.ERROR, null); + } + + @Override + public Annotation createWarningAnnotation(PsiElement elt, String message) { + return createProblem(elt, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, HighlightSeverity.WARNING, null); + } + + @Override + public Annotation createInfoAnnotation(PsiElement elt, String message) { + return createProblem(elt, message, ProblemHighlightType.INFO, HighlightSeverity.INFO, null); + } + + @Override + public Annotation createInformationAnnotation(PsiElement elt, String message) { + return createProblem(elt, message, ProblemHighlightType.INFORMATION, HighlightSeverity.INFORMATION, null); + } + + private Annotation createProblem(PsiElement elt, String message, ProblemHighlightType problemHighlightType, + HighlightSeverity severity, TextRange range) { + ProblemDescriptor descriptor = manager.createProblemDescriptor( + elt, + range, + GlobalInspectionUtil.createInspectionMessage(message), + problemHighlightType + ); + problemDescriptionsProcessor.addProblemElement( + GlobalInspectionUtil.retrieveRefElement(elt, globalContext), + descriptor + ); + return super.createAnnotation(elt.getTextRange(), severity, message); + } + + @Override + protected Annotation createAnnotation(TextRange range, HighlightSeverity severity, String message) { + assert false; + return super.createAnnotation(range, severity, message); + } + }; + } + + @Override + public void visitElement(PsiElement element) { + super.visitElement(element); + + List annotators = this.annotators != null ? + this.annotators:LanguageAnnotators.INSTANCE.allForLanguage(element.getLanguage()); + if (!annotators.isEmpty()) { + for(Annotator annotator:annotators) { + annotator.annotate(element, myHolder); + } + } + if (element instanceof PsiLanguageInjectionHost) { + ((PsiLanguageInjectionHost)element).processInjectedPsi(this); + } + } + + public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { + try { + annotators = LanguageAnnotators.INSTANCE.allForLanguage(injectedPsi.getLanguage()); + injectedPsi.acceptChildren(this); + } finally { + annotators = null; + } + } + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/GlobalInspectionUtil.java b/platform/lang-impl/src/com/intellij/codeInspection/GlobalInspectionUtil.java new file mode 100644 index 000000000000..b4161992fbc7 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/GlobalInspectionUtil.java @@ -0,0 +1,28 @@ +package com.intellij.codeInspection; + +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +/** + * User: Maxim.Mossienko + * Date: 16.09.2009 + * Time: 20:35:06 + */ +public class GlobalInspectionUtil { + private static final String LOC_MARKER = " #loc"; + + static RefElement retrieveRefElement(PsiElement element, GlobalInspectionContext globalContext) { + PsiFile elementFile = element.getContainingFile(); + RefElement refElement = globalContext.getRefManager().getReference(elementFile); + if (refElement == null) { + PsiElement context = elementFile.getContext(); + if (context != null) refElement = globalContext.getRefManager().getReference(context.getContainingFile()); + } + return refElement; + } + + public static String createInspectionMessage(String message) { + return message + LOC_MARKER; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/PlatformInspectionToolProvider.java b/platform/lang-impl/src/com/intellij/codeInspection/PlatformInspectionToolProvider.java index ba255e96926b..c298c88b7f1a 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/PlatformInspectionToolProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/PlatformInspectionToolProvider.java @@ -5,6 +5,6 @@ package com.intellij.codeInspection; */ public class PlatformInspectionToolProvider implements InspectionToolProvider { public Class[] getInspectionClasses() { - return new Class[] { SyntaxErrorInspection.class }; + return new Class[] { SyntaxErrorInspection.class, AnnotatorBasedInspection.class }; } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/SyntaxErrorInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/SyntaxErrorInspection.java index 760cd9a37c4d..dea5ba8aa27f 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/SyntaxErrorInspection.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/SyntaxErrorInspection.java @@ -2,7 +2,6 @@ package com.intellij.codeInspection; import com.intellij.analysis.AnalysisScope; import com.intellij.codeHighlighting.HighlightDisplayLevel; -import com.intellij.codeInspection.reference.RefElement; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.extensions.Extensions; import com.intellij.psi.*; @@ -88,7 +87,12 @@ public class SyntaxErrorInspection extends GlobalInspectionTool { CommonProblemDescriptor descriptor; final TextRange textRange = element.getTextRange(); if (textRange.getLength() > 0) { - descriptor = manager.createProblemDescriptor(element, element.getErrorDescription(), ProblemHighlightType.ERROR, null); + descriptor = manager.createProblemDescriptor( + element, + GlobalInspectionUtil.createInspectionMessage(element.getErrorDescription()), + ProblemHighlightType.ERROR, + null + ); } else { PsiElement parent = element; @@ -105,16 +109,11 @@ public class SyntaxErrorInspection extends GlobalInspectionTool { int offset = element.getTextRange().getStartOffset() - parent.getTextRange().getStartOffset(); descriptor = manager.createProblemDescriptor(parent, new TextRange(offset, offset+1), - element.getErrorDescription() + " #loc", ProblemHighlightType.ERROR); + GlobalInspectionUtil.createInspectionMessage(element.getErrorDescription()), + ProblemHighlightType.ERROR); } - PsiFile elementFile = element.getContainingFile(); - RefElement refElement = globalContext.getRefManager().getReference(elementFile); - if (refElement == null) { - PsiElement context = elementFile.getContext(); - if (context != null) refElement = globalContext.getRefManager().getReference(context.getContainingFile()); - } - problemDescriptionsProcessor.addProblemElement(refElement, descriptor); + problemDescriptionsProcessor.addProblemElement(GlobalInspectionUtil.retrieveRefElement(element, globalContext), descriptor); } public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java index 9797ff7e4e09..09055b0d0bb8 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -1,6 +1,7 @@ package com.intellij.codeInspection.ui; import com.intellij.CommonBundle; +import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.analysis.AnalysisScope; import com.intellij.analysis.AnalysisUIOptions; import com.intellij.codeHighlighting.HighlightDisplayLevel; @@ -621,12 +622,16 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } if (psiElement == null || !psiElement.isValid()) return null; PsiFile containingFile = psiElement.getContainingFile(); - final VirtualFile virtualFile = containingFile == null ? null : containingFile.getVirtualFile(); + VirtualFile virtualFile = containingFile == null ? null : containingFile.getVirtualFile(); + if (virtualFile != null) { int startOffset = psiElement.getTextOffset(); if (descriptor instanceof ProblemDescriptorImpl) { final TextRange textRange = ((ProblemDescriptorImpl)descriptor).getTextRangeForNavigation(); if (textRange != null) { + if (virtualFile instanceof VirtualFileWindow) { + virtualFile = ((VirtualFileWindow)virtualFile).getDelegate(); + } startOffset = textRange.getStartOffset(); } }