Search in sources :

Example 1 with BidirectionalMap

use of com.intellij.util.containers.BidirectionalMap in project intellij-community by JetBrains.

the class InconsistentResourceBundleInspection method checkFile.

@Override
public void checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, @NotNull ProblemsHolder problemsHolder, @NotNull GlobalInspectionContext globalContext, @NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) {
    Set<ResourceBundle> visitedBundles = globalContext.getUserData(VISITED_BUNDLES_KEY);
    if (!(file instanceof PropertiesFile))
        return;
    final PropertiesFile propertiesFile = (PropertiesFile) file;
    ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
    assert visitedBundles != null;
    if (!visitedBundles.add(resourceBundle))
        return;
    List<PropertiesFile> files = resourceBundle.getPropertiesFiles();
    if (files.size() < 2)
        return;
    BidirectionalMap<PropertiesFile, PropertiesFile> parents = new BidirectionalMap<>();
    for (PropertiesFile f : files) {
        PropertiesFile parent = PropertiesUtil.getParent(f, files);
        if (parent != null) {
            parents.put(f, parent);
        }
    }
    final FactoryMap<PropertiesFile, Map<String, String>> propertiesFilesNamesMaps = new FactoryMap<PropertiesFile, Map<String, String>>() {

        @Nullable
        @Override
        protected Map<String, String> create(PropertiesFile key) {
            return key.getNamesMap();
        }
    };
    Map<PropertiesFile, Set<String>> keysUpToParent = new THashMap<>();
    for (PropertiesFile f : files) {
        Set<String> keys = new THashSet<>(propertiesFilesNamesMaps.get(f).keySet());
        PropertiesFile parent = parents.get(f);
        while (parent != null) {
            keys.addAll(propertiesFilesNamesMaps.get(parent).keySet());
            parent = parents.get(parent);
        }
        keysUpToParent.put(f, keys);
    }
    for (final InconsistentResourceBundleInspectionProvider provider : myInspectionProviders.getValue()) {
        if (isProviderEnabled(provider.getName())) {
            provider.check(parents, files, keysUpToParent, propertiesFilesNamesMaps, manager, globalContext.getRefManager(), problemDescriptionsProcessor);
        }
    }
}
Also used : FactoryMap(com.intellij.util.containers.FactoryMap) THashSet(gnu.trove.THashSet) THashSet(gnu.trove.THashSet) THashMap(gnu.trove.THashMap) ResourceBundle(com.intellij.lang.properties.ResourceBundle) PropertiesFile(com.intellij.lang.properties.psi.PropertiesFile) FactoryMap(com.intellij.util.containers.FactoryMap) THashMap(gnu.trove.THashMap) BidirectionalMap(com.intellij.util.containers.BidirectionalMap) BidirectionalMap(com.intellij.util.containers.BidirectionalMap)

Example 2 with BidirectionalMap

use of com.intellij.util.containers.BidirectionalMap in project intellij-plugins by JetBrains.

the class DartLibraryIndex method getSdkLibUriToRelativePathMap.

@NotNull
public static BidirectionalMap<String, String> getSdkLibUriToRelativePathMap(@NotNull final Project project, @NotNull final String sdkHomePath) {
    VirtualFile librariesDartFile = LocalFileSystem.getInstance().findFileByPath(sdkHomePath + "/lib/_internal/libraries.dart");
    if (librariesDartFile == null) {
        librariesDartFile = LocalFileSystem.getInstance().findFileByPath(sdkHomePath + "/lib/_internal/sdk_library_metadata/lib/libraries.dart");
    }
    if (librariesDartFile == null)
        return new BidirectionalMap<>();
    final Pair<Long, BidirectionalMap<String, String>> data = librariesDartFile.getUserData(LIBRARIES_TIME_AND_MAP_KEY);
    final Long cachedTimestamp = data == null ? null : data.first;
    final long modificationCount = librariesDartFile.getModificationCount();
    if (cachedTimestamp != null && cachedTimestamp.equals(modificationCount)) {
        return data.second;
    }
    final VirtualFile finalLibrariesDartFile = librariesDartFile;
    return ReadAction.compute(() -> {
        try {
            final String contents = StringUtil.convertLineSeparators(VfsUtilCore.loadText(finalLibrariesDartFile));
            final PsiFile psiFile = PsiFileFactory.getInstance(project).createFileFromText("libraries.dart", DartLanguage.INSTANCE, contents);
            if (!(psiFile instanceof DartFile)) {
                return new BidirectionalMap<>();
            }
            final Pair<Long, BidirectionalMap<String, String>> data1 = Pair.create(modificationCount, computeSdkLibUriToRelativePathMap((DartFile) psiFile));
            finalLibrariesDartFile.putUserData(LIBRARIES_TIME_AND_MAP_KEY, data1);
            return data1.second;
        } catch (IOException e) {
            return new BidirectionalMap<>();
        }
    });
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) PsiFile(com.intellij.psi.PsiFile) IOException(java.io.IOException) BidirectionalMap(com.intellij.util.containers.BidirectionalMap) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with BidirectionalMap

use of com.intellij.util.containers.BidirectionalMap in project android by JetBrains.

the class ResourceQualifierSwitcher method collectQualifiers.

private static BidirectionalMap<String, VirtualFile> collectQualifiers(VirtualFile resDirectory, VirtualFile file) {
    BidirectionalMap<String, VirtualFile> result = new BidirectionalMap<String, VirtualFile>();
    ResourceFolderType type = ResourceHelper.getFolderType(file);
    for (VirtualFile dir : resDirectory.getChildren()) {
        ResourceFolderType otherType = ResourceFolderType.getFolderType(dir.getName());
        if (otherType == type) {
            VirtualFile fileWithQualifier = dir.findChild(file.getName());
            if (fileWithQualifier != null) {
                String childName = dir.getName();
                int dashPos = childName.indexOf('-');
                String qualifier = dashPos > 0 ? childName.substring(dashPos + 1) : "<default>";
                result.put(qualifier, fileWithQualifier);
            }
        }
    }
    return result;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) ResourceFolderType(com.android.resources.ResourceFolderType) BidirectionalMap(com.intellij.util.containers.BidirectionalMap)

Example 4 with BidirectionalMap

use of com.intellij.util.containers.BidirectionalMap in project intellij-community by JetBrains.

the class RedundantSuppressInspectionBase method checkElement.

@NotNull
public ProblemDescriptor[] checkElement(@NotNull final PsiElement psiElement, @NotNull final InspectionManager manager) {
    final Map<PsiElement, Collection<String>> suppressedScopes = new THashMap<>();
    psiElement.accept(new JavaRecursiveElementWalkingVisitor() {

        @Override
        public void visitModifierList(PsiModifierList list) {
            super.visitModifierList(list);
            final PsiElement parent = list.getParent();
            if (parent instanceof PsiModifierListOwner && !(parent instanceof PsiClass)) {
                checkElement(parent);
            }
        }

        @Override
        public void visitComment(PsiComment comment) {
            checkElement(comment);
        }

        @Override
        public void visitClass(PsiClass aClass) {
            if (aClass == psiElement) {
                super.visitClass(aClass);
                checkElement(aClass);
            }
        }

        private void checkElement(final PsiElement owner) {
            String idsString = JavaSuppressionUtil.getSuppressedInspectionIdsIn(owner);
            if (idsString != null && !idsString.isEmpty()) {
                List<String> ids = StringUtil.split(idsString, ",");
                if (IGNORE_ALL && (ids.contains(SuppressionUtil.ALL) || ids.contains(SuppressionUtil.ALL.toLowerCase())))
                    return;
                Collection<String> suppressed = suppressedScopes.get(owner);
                if (suppressed == null) {
                    suppressed = ids;
                } else {
                    for (String id : ids) {
                        if (!suppressed.contains(id)) {
                            suppressed.add(id);
                        }
                    }
                }
                suppressedScopes.put(owner, suppressed);
            }
        }
    });
    if (suppressedScopes.values().isEmpty())
        return ProblemDescriptor.EMPTY_ARRAY;
    // have to visit all file from scratch since inspections can be written in any pervasive way including checkFile() overriding
    Map<InspectionToolWrapper, String> suppressedTools = new THashMap<>();
    InspectionToolWrapper[] toolWrappers = getInspectionTools(psiElement, manager);
    for (Collection<String> ids : suppressedScopes.values()) {
        for (Iterator<String> iterator = ids.iterator(); iterator.hasNext(); ) {
            final String shortName = iterator.next().trim();
            for (InspectionToolWrapper toolWrapper : toolWrappers) {
                if (toolWrapper instanceof LocalInspectionToolWrapper && (((LocalInspectionToolWrapper) toolWrapper).getTool().getID().equals(shortName) || shortName.equals(((LocalInspectionToolWrapper) toolWrapper).getTool().getAlternativeID()))) {
                    if (((LocalInspectionToolWrapper) toolWrapper).isUnfair()) {
                        iterator.remove();
                        break;
                    } else {
                        suppressedTools.put(toolWrapper, shortName);
                    }
                } else if (toolWrapper.getShortName().equals(shortName)) {
                    //ignore global unused as it won't be checked anyway
                    if (toolWrapper instanceof LocalInspectionToolWrapper || toolWrapper instanceof GlobalInspectionToolWrapper && !((GlobalInspectionToolWrapper) toolWrapper).getTool().isGraphNeeded()) {
                        suppressedTools.put(toolWrapper, shortName);
                    } else {
                        iterator.remove();
                        break;
                    }
                }
            }
        }
    }
    PsiFile file = psiElement.getContainingFile();
    final AnalysisScope scope = new AnalysisScope(file);
    final GlobalInspectionContextBase globalContext = createContext(file);
    globalContext.setCurrentScope(scope);
    final RefManagerImpl refManager = (RefManagerImpl) globalContext.getRefManager();
    refManager.inspectionReadActionStarted();
    final List<ProblemDescriptor> result;
    try {
        result = new ArrayList<>();
        for (InspectionToolWrapper toolWrapper : suppressedTools.keySet()) {
            String toolId = suppressedTools.get(toolWrapper);
            toolWrapper.initialize(globalContext);
            final Collection<CommonProblemDescriptor> descriptors;
            if (toolWrapper instanceof LocalInspectionToolWrapper) {
                LocalInspectionToolWrapper local = (LocalInspectionToolWrapper) toolWrapper;
                //cant't work with passes other than LocalInspectionPass
                if (local.isUnfair())
                    continue;
                List<ProblemDescriptor> results = local.getTool().processFile(file, manager);
                descriptors = new ArrayList<>(results);
            } else if (toolWrapper instanceof GlobalInspectionToolWrapper) {
                final GlobalInspectionToolWrapper global = (GlobalInspectionToolWrapper) toolWrapper;
                GlobalInspectionTool globalTool = global.getTool();
                //when graph is needed, results probably depend on outer files so absence of results on one file (in current context) doesn't guarantee anything
                if (globalTool.isGraphNeeded())
                    continue;
                descriptors = new ArrayList<>();
                globalContext.getRefManager().iterate(new RefVisitor() {

                    @Override
                    public void visitElement(@NotNull RefEntity refEntity) {
                        CommonProblemDescriptor[] descriptors1 = global.getTool().checkElement(refEntity, scope, manager, globalContext, new ProblemDescriptionsProcessor() {
                        });
                        if (descriptors1 != null) {
                            ContainerUtil.addAll(descriptors, descriptors1);
                        }
                    }
                });
            } else {
                continue;
            }
            for (PsiElement suppressedScope : suppressedScopes.keySet()) {
                Collection<String> suppressedIds = suppressedScopes.get(suppressedScope);
                if (!suppressedIds.contains(toolId))
                    continue;
                for (CommonProblemDescriptor descriptor : descriptors) {
                    if (!(descriptor instanceof ProblemDescriptor))
                        continue;
                    PsiElement element = ((ProblemDescriptor) descriptor).getPsiElement();
                    if (element == null)
                        continue;
                    PsiElement annotation = JavaSuppressionUtil.getElementToolSuppressedIn(element, toolId);
                    if (annotation != null && PsiTreeUtil.isAncestor(suppressedScope, annotation, false) || annotation == null && !PsiTreeUtil.isAncestor(suppressedScope, element, false)) {
                        suppressedIds.remove(toolId);
                        break;
                    }
                }
            }
        }
        for (PsiElement suppressedScope : suppressedScopes.keySet()) {
            Collection<String> suppressedIds = suppressedScopes.get(suppressedScope);
            for (String toolId : suppressedIds) {
                PsiJavaDocumentedElement psiMember;
                String problemLine = null;
                if (suppressedScope instanceof PsiJavaDocumentedElement) {
                    psiMember = (PsiJavaDocumentedElement) suppressedScope;
                } else {
                    psiMember = PsiTreeUtil.getParentOfType(suppressedScope, PsiJavaDocumentedElement.class);
                    final PsiStatement statement = PsiTreeUtil.getNextSiblingOfType(suppressedScope, PsiStatement.class);
                    problemLine = statement != null ? statement.getText() : null;
                }
                if (psiMember != null && psiMember.isValid()) {
                    String description = InspectionsBundle.message("inspection.redundant.suppression.description");
                    if (myQuickFixes == null)
                        myQuickFixes = new BidirectionalMap<>();
                    final String key = toolId + (problemLine != null ? ";" + problemLine : "");
                    QuickFix fix = myQuickFixes.get(key);
                    if (fix == null) {
                        fix = new RemoveSuppressWarningAction(toolId, problemLine);
                        myQuickFixes.put(key, fix);
                    }
                    PsiElement identifier;
                    if (!(suppressedScope instanceof PsiJavaDocumentedElement)) {
                        identifier = suppressedScope;
                    } else {
                        identifier = psiMember.getNameIdentifier();
                    }
                    if (identifier == null) {
                        identifier = psiMember;
                    }
                    result.add(manager.createProblemDescriptor(identifier, description, (LocalQuickFix) fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false));
                }
            }
        }
    } finally {
        refManager.inspectionReadActionFinished();
        globalContext.close(true);
    }
    return result.toArray(new ProblemDescriptor[result.size()]);
}
Also used : NotNull(org.jetbrains.annotations.NotNull) AnalysisScope(com.intellij.analysis.AnalysisScope) RemoveSuppressWarningAction(com.intellij.codeInsight.daemon.impl.RemoveSuppressWarningAction) THashMap(gnu.trove.THashMap) BidirectionalMap(com.intellij.util.containers.BidirectionalMap) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

BidirectionalMap (com.intellij.util.containers.BidirectionalMap)4 VirtualFile (com.intellij.openapi.vfs.VirtualFile)2 THashMap (gnu.trove.THashMap)2 NotNull (org.jetbrains.annotations.NotNull)2 ResourceFolderType (com.android.resources.ResourceFolderType)1 AnalysisScope (com.intellij.analysis.AnalysisScope)1 RemoveSuppressWarningAction (com.intellij.codeInsight.daemon.impl.RemoveSuppressWarningAction)1 ResourceBundle (com.intellij.lang.properties.ResourceBundle)1 PropertiesFile (com.intellij.lang.properties.psi.PropertiesFile)1 PsiFile (com.intellij.psi.PsiFile)1 FactoryMap (com.intellij.util.containers.FactoryMap)1 THashSet (gnu.trove.THashSet)1 IOException (java.io.IOException)1