global inspections with no graph run concurrently per-file

This commit is contained in:
Alexey Kudravtsev
2011-04-05 17:54:01 +04:00
parent 16ef52c0b1
commit 9f9a4d213b
9 changed files with 223 additions and 146 deletions
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2011 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.analysis.AnalysisScope;
import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
/**
* Global inspection tool which doesn't need the graph and, therefore, can be run on per-file basis concurrently.
* Basically it is a local inspection tool which cannot be selected in the inspection profile to be run on-the-fly.
*/
public abstract class GlobalSimpleInspectionTool extends GlobalInspectionTool {
public abstract void checkFile(@NotNull PsiFile file,
@NotNull InspectionManager manager,
@NotNull ProblemsHolder problemsHolder,
@NotNull GlobalInspectionContext globalContext,
@NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor);
@Override
public final void runInspection(AnalysisScope scope,
InspectionManager manager,
GlobalInspectionContext globalContext,
ProblemDescriptionsProcessor problemDescriptionsProcessor) {
throw new IncorrectOperationException("You must override checkFile() instead");
}
@Override
public final boolean isGraphNeeded() {
return false;
}
}
@@ -16,7 +16,6 @@
package com.intellij.codeInspection;
import com.intellij.analysis.AnalysisScope;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.impl.*;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder;
@@ -35,7 +34,7 @@ import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class DefaultHighlightVisitorBasedInspection extends GlobalInspectionTool {
public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpleInspectionTool {
private static final JobDescriptor ANNOTATOR = new JobDescriptor(InspectionsBundle.message("inspection.processing.job.descriptor2"));
private final boolean highlightErrorElements;
private final boolean runAnnotators;
@@ -81,11 +80,6 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalInspe
}
}
@Override
public boolean isGraphNeeded() {
return false;
}
@Override
public JobDescriptor[] getAdditionalJobs() {
return new JobDescriptor[]{ANNOTATOR};
@@ -98,13 +92,13 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalInspe
}
@Override
public void runInspection(AnalysisScope scope,
InspectionManager manager,
GlobalInspectionContext globalContext,
ProblemDescriptionsProcessor problemDescriptionsProcessor) {
ANNOTATOR.setTotalAmount(scope.getFileCount());
public void checkFile(@NotNull PsiFile file,
@NotNull InspectionManager manager,
@NotNull ProblemsHolder problemsHolder,
@NotNull GlobalInspectionContext globalContext,
@NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) {
PsiElementVisitor visitor = new MyPsiElementVisitor(manager, globalContext, problemDescriptionsProcessor, highlightErrorElements,runAnnotators);
scope.accept(visitor);
file.accept(visitor);
}
@Nls
@@ -193,7 +193,7 @@ public class InspectionApplication {
if (myErrorCodeRequired) System.exit(1);
return;
}
inspectionContext.launchInspectionsOffline(scope, myOutPath, myRunWithEditorSettings, myRunGlobalToolsOnly, im);
inspectionContext.launchInspectionsOffline(scope, myOutPath, myRunGlobalToolsOnly, im);
logMessageLn(1, "\n" +
InspectionsBundle.message("inspection.capitalized.done") +
"\n");
@@ -238,7 +238,8 @@ public class InspectionApplication {
logMessageLn(2, text);
}
});
describeInspections(myOutPath + File.separatorChar + DESCRIPTIONS + XML_EXTENSION, !myRunWithEditorSettings ? inspectionProfile.getName() : null);
describeInspections(myOutPath + File.separatorChar + DESCRIPTIONS + XML_EXTENSION,
myRunWithEditorSettings ? null : inspectionProfile.getName());
}
catch (IOException e) {
LOG.error(e);
@@ -194,7 +194,7 @@ public class ViewOfflineResultsAction extends AnAction implements DumbAware {
final GlobalInspectionContextImpl inspectionContext = managerEx.createNewGlobalContext(false);
inspectionContext.setExternalProfile(inspectionProfile);
inspectionContext.setCurrentScope(scope);
inspectionContext.initializeTools(new ArrayList<Tools>(), new ArrayList<Tools>());
inspectionContext.initializeTools(new ArrayList<Tools>(), new ArrayList<Tools>(), new ArrayList<Tools>());
final InspectionResultsView view = new InspectionResultsView(project, inspectionProfile, scope, inspectionContext,
new OfflineInspectionRVContentProvider(resMap, project));
((RefManagerImpl)inspectionContext.getRefManager()).inspectionReadActionStarted();
@@ -25,6 +25,7 @@ import com.intellij.codeInspection.lang.GlobalInspectionContextExtension;
import com.intellij.codeInspection.lang.InspectionExtensionsFactory;
import com.intellij.codeInspection.reference.*;
import com.intellij.codeInspection.ui.InspectionResultsView;
import com.intellij.concurrency.JobUtil;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PathMacroManager;
@@ -45,6 +46,7 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
@@ -54,17 +56,25 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.content.*;
import com.intellij.util.Processor;
import com.intellij.util.TripleFunction;
import com.intellij.util.containers.HashMap;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jdom.Document;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class GlobalInspectionContextImpl implements GlobalInspectionContext {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.GlobalInspectionContextImpl");
@@ -238,7 +248,7 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
myCurrentScope = currentScope;
}
public void doInspections(final AnalysisScope scope, final InspectionManager manager) {
public void doInspections(@NotNull final AnalysisScope scope, @NotNull final InspectionManager manager) {
if (!InspectionManagerEx.canRunInspections(myProject, true)) return;
cleanup();
@@ -269,7 +279,6 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
public void launchInspectionsOffline(final AnalysisScope scope,
final String outputPath,
final boolean runWithEditorSettings,
final boolean runGlobalToolsOnly,
final InspectionManager manager) {
cleanup();
@@ -310,35 +319,21 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
if (!hasProblems) continue;
@NonNls final String isLocalToolAttribute = "is_local_tool";
root.setAttribute(isLocalToolAttribute, String.valueOf(isLocalTool));
OutputStream outStream = null;
try {
new File(outputPath).mkdirs();
final File file = new File(outputPath, toolName + ext);
if (isLocalTool) {
outStream = new BufferedOutputStream(new FileOutputStream(file, true));
outStream.write(("</" + InspectionsBundle.message("inspection.problems") + ">").getBytes());
FileUtil.writeToFile(file, "</" + InspectionsBundle.message("inspection.problems") + ">");
}
else {
PathMacroManager.getInstance(getProject()).collapsePaths(doc.getRootElement());
outStream = new BufferedOutputStream(new FileOutputStream(file));
JDOMUtil.writeDocument(doc, outStream, "\n");
JDOMUtil.writeDocument(doc, file, "\n");
}
}
catch (IOException e) {
LOG.error(e);
}
finally {
if (outStream != null) {
try {
outStream.close();
}
catch (IOException e) {
LOG.error(e);
}
}
}
}
}
});
}
@@ -349,23 +344,20 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
}
public boolean isToCheckMember(@NotNull RefElement owner, InspectionTool tool) {
public boolean isToCheckMember(@NotNull RefElement owner, InspectionProfileEntry tool) {
final PsiElement element = owner.getElement();
return isToCheckMember(element, tool) && !((RefElementImpl)owner).isSuppressed(tool.getShortName());
}
public boolean isToCheckMember(final PsiElement element, final InspectionTool tool) {
if (true) {
final Tools tools = myTools.get(tool.getShortName());
for (ScopeToolState state : tools.getTools()) {
final NamedScope namedScope = state.getScope(element.getProject());
if (namedScope == null || namedScope.getValue().contains(element.getContainingFile(), getCurrentProfile().getProfileManager().getScopesManager())) {
return state.isEnabled() && state.getTool() == tool;
}
public boolean isToCheckMember(final PsiElement element, final InspectionProfileEntry tool) {
final Tools tools = myTools.get(tool.getShortName());
for (ScopeToolState state : tools.getTools()) {
final NamedScope namedScope = state.getScope(element.getProject());
if (namedScope == null || namedScope.getValue().contains(element.getContainingFile(), getCurrentProfile().getProfileManager().getScopesManager())) {
return state.isEnabled() && state.getTool() == tool;
}
return false;
}
return true;
return false;
}
public void ignoreElement(final InspectionTool tool, final PsiElement element) {
@@ -436,7 +428,7 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
});
}
private void performInspectionsWithProgress(final AnalysisScope scope, final InspectionManager manager) {
private void performInspectionsWithProgress(@NotNull final AnalysisScope scope, @NotNull final InspectionManager manager) {
final PsiManager psiManager = PsiManager.getInstance(myProject);
myProgressIndicator = ProgressManager.getInstance().getProgressIndicator();
//init manager in read action
@@ -446,7 +438,8 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
refManager.inspectionReadActionStarted();
BUILD_GRAPH.setTotalAmount(scope.getFileCount());
LOCAL_ANALYSIS.setTotalAmount(scope.getFileCount());
((ProgressManagerImpl)ProgressManager.getInstance()).executeProcessUnderProgress(new Runnable() { //to override current progress in order to hide useless messages/%
//to override current progress in order to hide useless messages/%
((ProgressManagerImpl)ProgressManager.getInstance()).executeProcessUnderProgress(new Runnable() {
public void run() {
runTools(scope, manager);
}
@@ -470,11 +463,12 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
}
}
private void runTools(final AnalysisScope scope, final InspectionManager manager) {
private void runTools(@NotNull AnalysisScope scope, @NotNull final InspectionManager manager) {
final List<InspectionProfileEntry> needRepeatSearchRequest = new ArrayList<InspectionProfileEntry>();
final List<Tools> globalTools = new ArrayList<Tools>();
final List<Tools> localTools = new ArrayList<Tools>();
initializeTools(globalTools, localTools);
final List<Tools> globalSimpleTools = new ArrayList<Tools>();
initializeTools(globalTools, localTools,globalSimpleTools);
((RefManagerImpl)getRefManager()).initializeAnnotators();
for (Tools tools : globalTools) {
for (ScopeToolState state : tools.getTools()) {
@@ -516,10 +510,10 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
if (RUN_GLOBAL_TOOLS_ONLY) return;
final PsiManager psiManager = PsiManager.getInstance(myProject);
final Set<VirtualFile> localScopeFiles = scope.toSearchScope() instanceof LocalSearchScope ? new HashSet<VirtualFile>() : null;
final Set<VirtualFile> localScopeFiles = scope.toSearchScope() instanceof LocalSearchScope ? new THashSet<VirtualFile>() : null;
scope.accept(new PsiElementVisitor() {
@Override
public void visitFile(PsiFile file) {
public void visitFile(final PsiFile file) {
final VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile != null) {
incrementJobDoneAmount(LOCAL_ANALYSIS, ProjectUtil.calcRelativeToProjectPath(virtualFile, myProject));
@@ -541,6 +535,19 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
}
}
pass.doInspectInBatch((InspectionManagerEx)manager, lTools);
JobUtil.invokeConcurrentlyUnderProgress(globalSimpleTools, new Processor<Tools>() {
@Override
public boolean process(Tools tools) {
GlobalInspectionToolWrapper toolWrapper = (GlobalInspectionToolWrapper)tools.getTool();
GlobalSimpleInspectionTool tool = (GlobalSimpleInspectionTool)toolWrapper.getTool();
ProblemsHolder problemsHolder = new ProblemsHolder(manager, file, false);
tool.checkFile(file, manager, problemsHolder, GlobalInspectionContextImpl.this, toolWrapper);
LocalInspectionToolWrapper.addProblemDescriptors(problemsHolder.getResults(), false, GlobalInspectionContextImpl.this, null,
CONVERT, toolWrapper);
return true;
}
}, false, myProgressIndicator);
}
catch (ProcessCanceledException e) {
throw e;
@@ -557,8 +564,24 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
}
});
}
private static final TripleFunction<LocalInspectionTool,PsiElement,GlobalInspectionContext,RefElement> CONVERT =
new TripleFunction<LocalInspectionTool, PsiElement, GlobalInspectionContext, RefElement>() {
@Override
public RefElement fun(LocalInspectionTool tool,
PsiElement elt,
GlobalInspectionContext context) {
final PsiNamedElement problemElement = PsiTreeUtil.getNonStrictParentOfType(elt, PsiFile.class);
public void initializeTools(List<Tools> globalTools, List<Tools> localTools) {
RefElement refElement = context.getRefManager().getReference(problemElement);
if (refElement == null && problemElement != null) { // no need to lose collected results
refElement = GlobalInspectionUtil.retrieveRefElement(elt, context);
}
return refElement;
}
};
public void initializeTools(@NotNull List<Tools> outGlobalTools, @NotNull List<Tools> outLocalTools, @NotNull List<Tools> outGlobalSimpleTools) {
myJobDescriptors = new ArrayList<JobDescriptor>();
final InspectionProfileImpl profile = new InspectionProfileImpl((InspectionProfileImpl)getCurrentProfile());
final List<ToolsImpl> usedTools = profile.getAllEnabledInspectionTools();
@@ -567,11 +590,14 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
myTools.put(shortName, currentTools);
final InspectionTool tool = (InspectionTool)currentTools.getTool();
if (tool instanceof LocalInspectionToolWrapper) {
localTools.add(currentTools);
outLocalTools.add(currentTools);
appendJobDescriptor(LOCAL_ANALYSIS);
}
else if (tool instanceof GlobalInspectionToolWrapper && ((GlobalInspectionToolWrapper)tool).getTool() instanceof GlobalSimpleInspectionTool) {
outGlobalSimpleTools.add(currentTools);
}
else {
globalTools.add(currentTools);
outGlobalTools.add(currentTools);
JobDescriptor[] jobDescriptors = tool.getJobDescriptors();
for (JobDescriptor jobDescriptor : jobDescriptors) {
appendJobDescriptor(jobDescriptor);
@@ -583,7 +609,7 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
}
}
for (GlobalInspectionContextExtension extension : myExtensions.values()) {
extension.performPreRunActivities(globalTools, localTools, this);
extension.performPreRunActivities(outGlobalTools, outLocalTools, this);
}
}
@@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.*;
import com.intellij.util.TripleFunction;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -84,26 +85,45 @@ public final class LocalInspectionToolWrapper extends DescriptorProviderInspecti
}
public void addProblemDescriptors(List<ProblemDescriptor> descriptors, final boolean filterSuppressed) {
addProblemDescriptors(descriptors, filterSuppressed, getContext(), myTool, CONVERT, this);
}
private static final TripleFunction<LocalInspectionTool, PsiElement, GlobalInspectionContext,RefElement> CONVERT = new TripleFunction<LocalInspectionTool, PsiElement, GlobalInspectionContext,RefElement>() {
@Override
public RefElement fun(LocalInspectionTool tool, PsiElement elt, GlobalInspectionContext context) {
final PsiNamedElement problemElement = tool.getProblemElement(elt);
RefElement refElement = context.getRefManager().getReference(problemElement);
if (refElement == null && problemElement != null) { // no need to lose collected results
refElement = GlobalInspectionUtil.retrieveRefElement(elt, context);
}
return refElement;
}
};
public static void addProblemDescriptors(List<ProblemDescriptor> descriptors,
boolean filterSuppressed,
@NotNull GlobalInspectionContextImpl context,
LocalInspectionTool tool,
@NotNull TripleFunction<LocalInspectionTool, PsiElement, GlobalInspectionContext, RefElement> getProblemElementFunction,
@NotNull DescriptorProviderInspection dpi) {
if (descriptors == null || descriptors.isEmpty()) return;
Map<RefElement, List<ProblemDescriptor>> problems = new HashMap<RefElement, List<ProblemDescriptor>>();
final RefManagerImpl refManager = (RefManagerImpl)getContext().getRefManager();
final RefManagerImpl refManager = (RefManagerImpl)context.getRefManager();
for (ProblemDescriptor descriptor : descriptors) {
final PsiElement elt = descriptor.getPsiElement();
if (elt == null) continue;
if (filterSuppressed) {
if (refManager.isDeclarationsFound() && (getContext().isSuppressed(elt, myTool.getID()) || getContext().isSuppressed(elt, myTool.getAlternativeID()))) {
if (refManager.isDeclarationsFound()
&& (context.isSuppressed(elt, tool.getID()) || tool.getAlternativeID() != null && context.isSuppressed(elt, tool.getAlternativeID()))) {
continue;
}
if (InspectionManagerEx.inspectionResultSuppressed(elt, myTool)) continue;
if (InspectionManagerEx.inspectionResultSuppressed(elt, tool)) continue;
}
final PsiNamedElement problemElement = myTool.getProblemElement(elt);
RefElement refElement = refManager.getReference(problemElement);
if (refElement == null && problemElement != null) { // no need to loose collected results
refElement = GlobalInspectionUtil.retrieveRefElement(elt, getContext());
}
RefElement refElement = getProblemElementFunction.fun(tool, elt, context);
List<ProblemDescriptor> elementProblems = problems.get(refElement);
if (elementProblems == null) {
elementProblems = new ArrayList<ProblemDescriptor>();
@@ -114,13 +134,13 @@ public final class LocalInspectionToolWrapper extends DescriptorProviderInspecti
for (Map.Entry<RefElement, List<ProblemDescriptor>> entry : problems.entrySet()) {
final List<ProblemDescriptor> problemDescriptors = entry.getValue();
addProblemElement(entry.getKey(),
filterSuppressed,
problemDescriptors.toArray(new CommonProblemDescriptor[problemDescriptors.size()]));
dpi.addProblemElement(entry.getKey(),
filterSuppressed,
problemDescriptors.toArray(new CommonProblemDescriptor[problemDescriptors.size()]));
}
}
public void runInspection(AnalysisScope scope, final InspectionManager manager) {
public void runInspection(@NotNull AnalysisScope scope, @NotNull final InspectionManager manager) {
LOG.assertTrue(ApplicationManager.getApplication().isUnitTestMode());
scope.accept(new PsiRecursiveElementVisitor() {
@Override public void visitFile(PsiFile file) {
@@ -15,11 +15,9 @@
*/
package com.intellij.codeInspection.i18n;
import com.intellij.analysis.AnalysisScope;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.DescriptorProviderInspection;
import com.intellij.codeInspection.ex.JobDescriptor;
import com.intellij.codeInspection.reference.RefManager;
import com.intellij.lang.properties.PropertiesBundle;
import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.RemovePropertyLocalFix;
@@ -28,7 +26,6 @@ import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.psi.Property;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiRecursiveElementVisitor;
import com.intellij.util.containers.BidirectionalMap;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
@@ -45,7 +42,7 @@ import java.util.Set;
/**
* @author max
*/
public class InconsistentResourceBundleInspection extends DescriptorProviderInspection {
public class InconsistentResourceBundleInspection extends GlobalSimpleInspectionTool {
private JCheckBox myReportMissingTranslationsCheckBox;
private JCheckBox myReportInconsistentPropertiesCheckBox;
private JPanel myOptionsPanel;
@@ -88,10 +85,6 @@ public class InconsistentResourceBundleInspection extends DescriptorProviderInsp
return HighlightDisplayLevel.ERROR;
}
public boolean isEnabledByDefault() {
return true;
}
@Nullable
public JComponent createOptionsPanel() {
myReportInconsistentPropertiesCheckBox.setSelected(REPORT_INCONSISTENT_PROPERTIES);
@@ -101,21 +94,19 @@ public class InconsistentResourceBundleInspection extends DescriptorProviderInsp
}
public void runInspection(@NotNull AnalysisScope scope, @NotNull final InspectionManager manager) {
final Set<ResourceBundle> visitedBundles = new THashSet<ResourceBundle>();
scope.accept(new PsiRecursiveElementVisitor() {
@Override public void visitFile(PsiFile file) {
checkFile(file, manager, visitedBundles);
}
});
@Override
public void checkFile(@NotNull PsiFile file,
@NotNull InspectionManager manager,
@NotNull ProblemsHolder problemsHolder,
@NotNull GlobalInspectionContext globalContext,
@NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) {
checkFile(file, manager, new THashSet<ResourceBundle>(), globalContext.getRefManager(), problemDescriptionsProcessor);
}
@NotNull
public JobDescriptor[] getJobDescriptors() {
return JobDescriptor.EMPTY_ARRAY;
}
private void checkFile(@NotNull final PsiFile file, @NotNull final InspectionManager manager, final Set<ResourceBundle> visitedBundles) {
private void checkFile(@NotNull final PsiFile file,
@NotNull final InspectionManager manager,
final Set<ResourceBundle> visitedBundles,
RefManager refManager, ProblemDescriptionsProcessor processor) {
if (!(file instanceof PropertiesFile)) return;
final PropertiesFile propertiesFile = (PropertiesFile)file;
ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
@@ -140,18 +131,22 @@ public class InconsistentResourceBundleInspection extends DescriptorProviderInsp
keysUpToParent.put(f, keys);
}
if (REPORT_MISSING_TRANSLATIONS) {
checkMissingTranslations(parents, files, keysUpToParent, manager);
checkMissingTranslations(parents, files, keysUpToParent, manager, refManager, processor);
}
if (REPORT_INCONSISTENT_PROPERTIES) {
checkConsistency(parents, files, keysUpToParent, manager);
checkConsistency(parents, files, keysUpToParent, manager, refManager, processor);
}
if (REPORT_DUPLICATED_PROPERTIES) {
checkDuplicatedProperties(parents, files, keysUpToParent, manager);
checkDuplicatedProperties(parents, files, keysUpToParent, manager, refManager, processor);
}
}
private void checkDuplicatedProperties(final BidirectionalMap<PropertiesFile, PropertiesFile> parents, final List<PropertiesFile> files,
final Map<PropertiesFile, Set<String>> keysUpToParent, final InspectionManager manager) {
private static void checkDuplicatedProperties(final BidirectionalMap<PropertiesFile, PropertiesFile> parents,
final List<PropertiesFile> files,
final Map<PropertiesFile, Set<String>> keysUpToParent,
final InspectionManager manager,
RefManager refManager,
ProblemDescriptionsProcessor processor) {
for (PropertiesFile file : files) {
PropertiesFile parent = parents.get(file);
if (parent == null) continue;
@@ -168,7 +163,7 @@ public class InconsistentResourceBundleInspection extends DescriptorProviderInsp
ProblemDescriptor descriptor = manager.createProblemDescriptor(property, message,
RemovePropertyLocalFix.INSTANCE,
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false);
addProblemElement(getRefManager().getReference(file), descriptor);
processor.addProblemElement(refManager.getReference(file), descriptor);
}
parent = parents.get(parent);
}
@@ -176,8 +171,10 @@ public class InconsistentResourceBundleInspection extends DescriptorProviderInsp
}
}
private void checkConsistency(final BidirectionalMap<PropertiesFile, PropertiesFile> parents, final List<PropertiesFile> files,
final Map<PropertiesFile, Set<String>> keysUpToParent, final InspectionManager manager) {
private static void checkConsistency(final BidirectionalMap<PropertiesFile, PropertiesFile> parents, final List<PropertiesFile> files,
final Map<PropertiesFile, Set<String>> keysUpToParent,
final InspectionManager manager,
RefManager refManager, ProblemDescriptionsProcessor processor) {
for (PropertiesFile file : files) {
PropertiesFile parent = parents.get(file);
Set<String> parentKeys = keysUpToParent.get(parent);
@@ -199,13 +196,17 @@ public class InconsistentResourceBundleInspection extends DescriptorProviderInsp
String message = InspectionsBundle.message("inconsistent.bundle.property.error", inconsistentKey, parent.getName());
ProblemDescriptor descriptor = manager.createProblemDescriptor(property, message, false, LocalQuickFix.EMPTY_ARRAY,
ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
addProblemElement(getRefManager().getReference(file), descriptor);
processor.addProblemElement(refManager.getReference(file), descriptor);
}
}
}
private void checkMissingTranslations(final BidirectionalMap<PropertiesFile, PropertiesFile> parents, final List<PropertiesFile> files,
final Map<PropertiesFile, Set<String>> keysUpToParent, final InspectionManager manager) {
private static void checkMissingTranslations(final BidirectionalMap<PropertiesFile, PropertiesFile> parents,
final List<PropertiesFile> files,
final Map<PropertiesFile, Set<String>> keysUpToParent,
final InspectionManager manager,
RefManager refManager,
ProblemDescriptionsProcessor processor) {
for (PropertiesFile file : files) {
PropertiesFile parent = parents.get(file);
if (parent == null) continue;
@@ -235,7 +236,7 @@ public class InconsistentResourceBundleInspection extends DescriptorProviderInsp
String message = InspectionsBundle.message("inconsistent.bundle.untranslated.property.error", untranslatedKey, file.getName());
ProblemDescriptor descriptor = manager.createProblemDescriptor(untranslatedProperty, message, false, LocalQuickFix.EMPTY_ARRAY,
ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
addProblemElement(getRefManager().getReference(untranslatedFile), descriptor);
processor.addProblemElement(refManager.getReference(untranslatedFile), descriptor);
}
}
}
@@ -15,13 +15,10 @@
*/
package com.intellij.codeInspection.duplicatePropertyInspection;
import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.DescriptorComposer;
import com.intellij.codeInspection.ex.DescriptorProviderInspection;
import com.intellij.codeInspection.ex.HTMLComposerImpl;
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
import com.intellij.codeInspection.ex.JobDescriptor;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.reference.RefManager;
import com.intellij.concurrency.JobUtil;
import com.intellij.lang.properties.PropertiesBundle;
import com.intellij.lang.properties.psi.PropertiesFile;
@@ -40,7 +37,6 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiRecursiveElementVisitor;
import com.intellij.psi.impl.search.LowLevelSearchUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiSearchHelper;
@@ -49,7 +45,6 @@ import com.intellij.util.Processor;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.text.StringSearcher;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -59,7 +54,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
public class DuplicatePropertyInspection extends DescriptorProviderInspection {
public class DuplicatePropertyInspection extends GlobalSimpleInspectionTool {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.DuplicatePropertyInspection");
public boolean CURRENT_FILE = true;
@@ -69,25 +64,24 @@ public class DuplicatePropertyInspection extends DescriptorProviderInspection {
public boolean CHECK_DUPLICATE_KEYS = true;
public boolean CHECK_DUPLICATE_KEYS_WITH_DIFFERENT_VALUES = true;
public void runInspection(@NotNull AnalysisScope scope, @NotNull final InspectionManager manager) {
scope.accept(new PsiRecursiveElementVisitor() {
@Override
public void visitFile(PsiFile file) {
checkFile(file, manager);
}
});
@Override
public void checkFile(@NotNull PsiFile file,
@NotNull InspectionManager manager,
@NotNull ProblemsHolder problemsHolder,
@NotNull GlobalInspectionContext globalContext,
@NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) {
checkFile(file, manager, (GlobalInspectionContextImpl)globalContext, globalContext.getRefManager(), problemDescriptionsProcessor);
}
public HTMLComposerImpl getComposer() {
return new DescriptorComposer(this) {
protected void composeDescription(final CommonProblemDescriptor description, int i, StringBuffer buf, final RefEntity refElement) {
@NonNls String descriptionTemplate = description.getDescriptionTemplate();
descriptionTemplate = descriptionTemplate.replaceAll("#end", " ");
buf.append(descriptionTemplate);
}
};
}
//public HTMLComposerImpl getComposer() {
// return new DescriptorComposer(this) {
// protected void composeDescription(final CommonProblemDescriptor description, int i, StringBuffer buf, final RefEntity refElement) {
// @NonNls String descriptionTemplate = description.getDescriptionTemplate();
// descriptionTemplate = descriptionTemplate.replaceAll("#end", " ");
// buf.append(descriptionTemplate);
// }
// };
//}
@SuppressWarnings({"HardCodedStringLiteral"})
private static void surroundWithHref(StringBuffer anchor, PsiElement element, final boolean isValue) {
@@ -154,9 +148,9 @@ public class DuplicatePropertyInspection extends DescriptorProviderInspection {
return JobDescriptor.EMPTY_ARRAY;
}
private void checkFile(final PsiFile file, final InspectionManager manager) {
private void checkFile(final PsiFile file, final InspectionManager manager, GlobalInspectionContextImpl context, final RefManager refManager, final ProblemDescriptionsProcessor processor) {
if (!(file instanceof PropertiesFile)) return;
if (!getContext().isToCheckMember(file, this)) return;
if (!context.isToCheckMember(file, this)) return;
final PsiSearchHelper searchHelper = file.getManager().getSearchHelper();
final PropertiesFile propertiesFile = (PropertiesFile)file;
final List<Property> properties = propertiesFile.getProperties();
@@ -195,8 +189,8 @@ public class DuplicatePropertyInspection extends DescriptorProviderInspection {
processDuplicateKeysWithDifferentValues(keyToDifferentValues, processedKeyToFiles, problemDescriptors, manager, file, original);
}
if (!problemDescriptors.isEmpty()) {
addProblemElement(getRefManager().getReference(file),
problemDescriptors.toArray(new ProblemDescriptor[problemDescriptors.size()]));
processor.addProblemElement(refManager.getReference(file),
problemDescriptors.toArray(new ProblemDescriptor[problemDescriptors.size()]));
}
}
}, progress);
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.analysis.AnalysisScope;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter;
@@ -34,15 +33,10 @@ import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
public class XmlHighlightVisitorBasedInspection extends GlobalInspectionTool {
public class XmlHighlightVisitorBasedInspection extends GlobalSimpleInspectionTool {
private static final JobDescriptor XML_HIGHLIGHTER =
new JobDescriptor(InspectionsBundle.message("inspection.processing.job.descriptor2"));
@Override
public boolean isGraphNeeded() {
return false;
}
@NotNull
@Override
public HighlightDisplayLevel getDefaultLevel() {
@@ -55,12 +49,13 @@ public class XmlHighlightVisitorBasedInspection extends GlobalInspectionTool {
}
@Override
public void runInspection(AnalysisScope scope,
final InspectionManager manager,
final GlobalInspectionContext globalContext,
final ProblemDescriptionsProcessor problemDescriptionsProcessor) {
XML_HIGHLIGHTER.setTotalAmount(scope.getFileCount());
scope.accept(new XmlRecursiveElementVisitor() {
public void checkFile(@NotNull PsiFile file,
@NotNull final InspectionManager manager,
@NotNull ProblemsHolder problemsHolder,
@NotNull final GlobalInspectionContext globalContext,
@NotNull final ProblemDescriptionsProcessor problemDescriptionsProcessor) {
//XML_HIGHLIGHTER.setTotalAmount(scope.getFileCount());
file.accept(new XmlRecursiveElementVisitor() {
final XmlHighlightVisitor highlightVisitor = new XmlHighlightVisitor();
HighlightInfoHolder myHolder;
@@ -119,4 +114,4 @@ public class XmlHighlightVisitorBasedInspection extends GlobalInspectionTool {
public String getShortName() {
return "XmlHighlighting";
}
}
}