dde1c52293db5965af151626af69cff97fc8c36f
[idea/community.git] / platform / lang-impl / src / com / intellij / codeInspection / ex / InspectionRVContentProviderImpl.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * User: anna
19  * Date: 10-Jan-2007
20  */
21 package com.intellij.codeInspection.ex;
22
23 import com.intellij.codeInspection.CommonProblemDescriptor;
24 import com.intellij.codeInspection.reference.*;
25 import com.intellij.codeInspection.ui.*;
26 import com.intellij.openapi.project.Project;
27 import com.intellij.openapi.util.Comparing;
28 import com.intellij.openapi.util.TextRange;
29 import com.intellij.psi.PsiElement;
30 import com.intellij.psi.search.LocalSearchScope;
31 import com.intellij.psi.search.SearchScope;
32 import com.intellij.util.containers.HashSet;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
35
36 import java.util.Iterator;
37 import java.util.Map;
38 import java.util.Set;
39
40 public class InspectionRVContentProviderImpl extends InspectionRVContentProvider {
41   public InspectionRVContentProviderImpl(final Project project) {
42     super(project);
43   }
44
45   @Override
46   public boolean checkReportedProblems(@NotNull GlobalInspectionContextImpl context,
47                                        @NotNull final InspectionToolWrapper toolWrapper) {
48     InspectionToolPresentation presentation = context.getPresentation(toolWrapper);
49     presentation.updateContent();
50
51     final SearchScope searchScope = context.getCurrentScope().toSearchScope();
52     if (searchScope instanceof LocalSearchScope) {
53       final Map<String, Set<RefEntity>> contents = presentation.getContent();
54       final Map<RefEntity, CommonProblemDescriptor[]> problemElements = presentation.getProblemElements();
55       for (Set<RefEntity> entities : contents.values()) {
56         for (Iterator<RefEntity> iterator = entities.iterator(); iterator.hasNext(); ) {
57           RefEntity entity = iterator.next();
58           if (entity instanceof RefElement) {
59             final PsiElement element = ((RefElement)entity).getElement();
60             if (element != null) {
61               final TextRange range = element.getTextRange();
62               if (range != null && ((LocalSearchScope)searchScope).containsRange(element.getContainingFile(), range)) {
63                 continue;
64               }
65             }
66           }
67           problemElements.remove(entity);
68           iterator.remove();
69         }
70       }
71     }
72
73     return presentation.hasReportedProblems();
74   }
75
76   @Override
77   @Nullable
78   public QuickFixAction[] getQuickFixes(@NotNull final InspectionToolWrapper toolWrapper, @NotNull final InspectionTree tree) {
79     final RefEntity[] refEntities = tree.getSelectedElements();
80     InspectionToolPresentation presentation = tree.getContext().getPresentation(toolWrapper);
81     return refEntities.length == 0 ? null : presentation.getQuickFixes(refEntities, tree.getSelectedDescriptors());
82   }
83
84
85   @Override
86   public void appendToolNodeContent(@NotNull GlobalInspectionContextImpl context,
87                                     @NotNull final InspectionNode toolNode,
88                                     @NotNull final InspectionTreeNode parentNode,
89                                     final boolean showStructure,
90                                     @NotNull final Map<String, Set<RefEntity>> contents,
91                                     @NotNull final Map<RefEntity, CommonProblemDescriptor[]> problems) {
92     final InspectionToolWrapper toolWrapper = toolNode.getToolWrapper();
93     merge(toolNode, parentNode, false);
94
95     InspectionToolPresentation presentation = context.getPresentation(toolWrapper);
96     final Set<RefModule> moduleProblems = presentation.getModuleProblems();
97     if (!moduleProblems.isEmpty()) {
98       Set<RefEntity> entities = contents.get("");
99       if (entities == null) {
100         entities = new HashSet<RefEntity>();
101         contents.put("", entities);
102       }
103       entities.addAll(moduleProblems);
104     }
105     buildTree(context,
106               contents,
107               false,
108               toolWrapper,
109               refElement -> new RefElementContainer(refElement, problems.get(refElement)),
110               showStructure,
111               node -> merge(node, toolNode, true));
112   }
113
114   @Override
115   protected void appendDescriptor(@NotNull GlobalInspectionContextImpl context,
116                                   @NotNull final InspectionToolWrapper toolWrapper,
117                                   @NotNull final UserObjectContainer container,
118                                   @NotNull final InspectionTreeNode pNode,
119                                   final boolean canPackageRepeat) {
120     final RefElementContainer refElementDescriptor = (RefElementContainer)container;
121     final RefEntity refElement = refElementDescriptor.getUserObject();
122     InspectionToolPresentation presentation = context.getPresentation(toolWrapper);
123     final CommonProblemDescriptor[] problems = refElementDescriptor.getProblemDescriptors();
124     if (problems != null) {
125         final RefElementNode elemNode = addNodeToParent(container, presentation, pNode);
126         for (CommonProblemDescriptor problem : problems) {
127           assert problem != null;
128           elemNode.insertByOrder(new ProblemDescriptionNode(refElement, problem, toolWrapper,presentation));
129           if (problems.length == 1) {
130             elemNode.setProblem(problems[0]);
131           }
132         }
133     }
134     else {
135       if (canPackageRepeat && pNode instanceof InspectionPackageNode) {
136         final Set<RefEntity> currentElements = presentation.getContent().get(((InspectionPackageNode) pNode).getPackageName());
137         if (currentElements != null) {
138           final Set<RefEntity> currentEntities = new HashSet<RefEntity>(currentElements);
139           if (RefUtil.contains(refElement, currentEntities)) return;
140         }
141       }
142       addNodeToParent(container, presentation, pNode);
143     }
144   }
145
146   private static class RefElementContainer implements UserObjectContainer<RefEntity> {
147     @NotNull
148     private final RefEntity myElement;
149     private final CommonProblemDescriptor[] myDescriptors;
150
151     public RefElementContainer(@NotNull RefEntity element, CommonProblemDescriptor[] descriptors) {
152       myElement = element;
153       myDescriptors = descriptors;
154     }
155
156     @Override
157     @Nullable
158     public RefElementContainer getOwner() {
159       final RefEntity entity = myElement.getOwner();
160       if (entity instanceof RefElement && !(entity instanceof RefDirectory)) {
161         return new RefElementContainer(entity, myDescriptors);
162       }
163       return null;
164     }
165
166     @NotNull
167     @Override
168     public RefElementNode createNode(@NotNull InspectionToolPresentation presentation) {
169       return new RefElementNode(myElement, presentation);
170     }
171
172     @Override
173     @NotNull
174     public RefEntity getUserObject() {
175       return myElement;
176     }
177
178     @Override
179     @Nullable
180     public String getModule() {
181       final RefModule refModule = myElement instanceof RefElement
182                                   ? ((RefElement)myElement).getModule()
183                                   : myElement instanceof RefModule ? (RefModule)myElement : null;
184       return refModule != null ? refModule.getName() : null;
185     }
186
187     @Override
188     public boolean areEqual(final RefEntity o1, final RefEntity o2) {
189       return Comparing.equal(o1, o2);
190     }
191
192     @Override
193     public boolean supportStructure() {
194       return myElement instanceof RefElement && !(myElement instanceof RefDirectory); //do not show structure for refModule and refPackage
195     }
196
197     public CommonProblemDescriptor[] getProblemDescriptors() {
198       return myDescriptors;
199     }
200   }
201 }