do not forget about comments while searching using javac ast
authorDmitry Batkovich <dmitry.batkovich@jetbrains.com>
Wed, 28 Sep 2016 12:22:37 +0000 (15:22 +0300)
committerDmitry Batkovich <dmitry.batkovich@jetbrains.com>
Wed, 28 Sep 2016 12:22:37 +0000 (15:22 +0300)
java/compiler/impl/src/com/intellij/compiler/CompilerReferenceServiceImpl.java
java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
java/java-indexing-impl/src/com/intellij/compiler/CompilerReferenceService.java
java/java-indexing-impl/src/com/intellij/compiler/JavaCompilerReferencesInCodeScopeOptimizer.java [moved from java/java-indexing-impl/src/com/intellij/compiler/CompilerReferenceScopeOptimizer.java with 76% similarity]
platform/indexing-api/src/com/intellij/psi/search/InCodeScopeOptimizer.java [new file with mode: 0644]
platform/indexing-api/src/com/intellij/psi/search/SearchRequestCollector.java
platform/platform-resources/src/META-INF/LangExtensionPoints.xml
resources/src/META-INF/IdeaPlugin.xml

index 4b733acaa7d5101fcff66e91c77238bd0cdf942f..6b5d54d773e7c256d146e61a58b578ef40f100d3 100644 (file)
@@ -24,11 +24,11 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.roots.ProjectFileIndex;
 import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.roots.impl.LibraryScopeCache;
 import com.intellij.openapi.vfs.*;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.ProjectScope;
 import com.intellij.psi.util.CachedValueProvider;
 import com.intellij.psi.util.CachedValuesManager;
 import com.intellij.psi.util.PsiModificationTracker;
@@ -55,6 +55,7 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService {
   private final Set<FileType> myFileTypes;
 
   private volatile CompilerReferenceReader myReader;
+  private volatile GlobalSearchScope myMayContainInvalidDataScope = GlobalSearchScope.EMPTY_SCOPE;
 
   private final Object myLock = new Object();
 
@@ -79,6 +80,7 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService {
         @Override
         public boolean execute(CompileContext context) {
           myChangedModules.clear();
+          myMayContainInvalidDataScope = GlobalSearchScope.EMPTY_SCOPE;
           openReaderIfNeed();
           return true;
         }
@@ -127,7 +129,9 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService {
         if (myReader != null && myProjectFileIndex.isInSourceContent(file) && myFileTypes.contains(file.getFileType())) {
           final Module module = myProjectFileIndex.getModuleForFile(file);
           if (module != null) {
-            myChangedModules.add(module);
+            if (myChangedModules.add(module)) {
+              myMayContainInvalidDataScope = myMayContainInvalidDataScope.union(module.getModuleWithDependentsScope());
+            }
           }
         }
       }
@@ -139,25 +143,27 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService {
     closeReaderIfNeed();
   }
 
+  @Nullable
   @Override
-  public GlobalSearchScope getScopeWithoutReferences(@NotNull PsiElement element) {
+  public GlobalSearchScope getMayContainReferencesInCodeScope(@NotNull PsiElement element) {
     if (!isServiceEnabled()) return null;
-    return CachedValuesManager.getCachedValue(element, () -> CachedValueProvider.Result.create(calculateScopeWithoutReferences(element),
-                                                                                               PsiModificationTracker.MODIFICATION_COUNT));
+    return CachedValuesManager.getCachedValue(element, () -> CachedValueProvider.Result.create(calculateMayContainReferencesScope(element), PsiModificationTracker.MODIFICATION_COUNT));
   }
 
+
   private boolean isServiceEnabled() {
     return myReader != null && isEnabled();
   }
 
   @Nullable
-  private GlobalSearchScope calculateScopeWithoutReferences(@NotNull PsiElement element) {
+  private GlobalSearchScope calculateMayContainReferencesScope(@NotNull PsiElement element) {
     TIntHashSet referentFileIds = getReferentFileIds(element);
     if (referentFileIds == null) return null;
 
-    final GlobalSearchScope everythingIsClearScope = GlobalSearchScope
-      .getScopeRestrictedByFileTypes(ProjectScope.getContentScope(myProject), myFileTypes.toArray(new FileType[myFileTypes.size()]));
-    return new ScopeWithoutBytecodeReferences(referentFileIds).intersectWith(everythingIsClearScope);
+    return new ScopeWithBytecodeReferences(referentFileIds)
+      .union(myMayContainInvalidDataScope)
+      .union(LibraryScopeCache.getInstance(element.getProject()).getLibrariesOnlyScope())
+      .union(GlobalSearchScope.notScope(GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(myProject), myFileTypes.toArray(new FileType[myFileTypes.size()]))));
   }
 
   @Nullable
@@ -171,11 +177,9 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService {
     if (place == null) {
       return null;
     }
-    if (!myChangedModules.isEmpty()) {
-      final Module module = myProjectFileIndex.getModuleForFile(vFile);
-      if (module == null || areDependenciesOrSelfChanged(module, new THashSet<>())) {
-        return null;
-      }
+
+    if (myMayContainInvalidDataScope.contains(vFile)) {
+      return null;
     }
     final FileType type = vFile.getFileType();
     CompilerElement[] compilerElements = null;
@@ -250,16 +254,16 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService {
     }
   }
 
-  private static class ScopeWithoutBytecodeReferences extends GlobalSearchScope {
+  private static class ScopeWithBytecodeReferences extends GlobalSearchScope {
     private final TIntHashSet myReferentIds;
 
-    private ScopeWithoutBytecodeReferences(TIntHashSet ids) {
+    private ScopeWithBytecodeReferences(TIntHashSet ids) {
       myReferentIds = ids;
     }
 
     @Override
     public boolean contains(@NotNull VirtualFile file) {
-      return !(file instanceof VirtualFileWithId) || !myReferentIds.contains(((VirtualFileWithId)file).getId());
+      return file instanceof VirtualFileWithId && myReferentIds.contains(((VirtualFileWithId)file).getId());
     }
 
     @Override
index 6b0e5a204fd94abef864ca5dffffa0870ff40f1c..437d09fd2dfeff7307855f4d2af2fc4530639fe2 100644 (file)
@@ -194,4 +194,4 @@ public class DataFlowInspection extends DataFlowInspectionBase {
     }
   }
 
-}
+}
\ No newline at end of file
index 39c1480af5b2cca6193efaefd66b51c205574e04..0b5d252ad6589ad6eca8d654c946c72b76e6ef62 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.registry.RegistryValue;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.search.GlobalSearchScope;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 public abstract class CompilerReferenceService extends AbstractProjectComponent {
   public static final RegistryValue IS_ENABLED_KEY = Registry.get("bytecode.ref.index");
@@ -34,7 +35,8 @@ public abstract class CompilerReferenceService extends AbstractProjectComponent
     return project.getComponent(CompilerReferenceService.class);
   }
 
-  public abstract GlobalSearchScope getScopeWithoutReferences(@NotNull PsiElement element);
+  @Nullable
+  public abstract GlobalSearchScope getMayContainReferencesInCodeScope(@NotNull PsiElement element);
 
   public static boolean isEnabled() {
     return IS_ENABLED_KEY.asBoolean();
similarity index 76%
rename from java/java-indexing-impl/src/com/intellij/compiler/CompilerReferenceScopeOptimizer.java
rename to java/java-indexing-impl/src/com/intellij/compiler/JavaCompilerReferencesInCodeScopeOptimizer.java
index 2050ef343c792006936456fb27a9eef99162d18e..537c2e481fc151a1d5c3e4b06fe712cf31181f0e 100644 (file)
@@ -17,14 +17,14 @@ package com.intellij.compiler;
 
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.UseScopeOptimizer;
+import com.intellij.psi.search.InCodeScopeOptimizer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public class CompilerReferenceScopeOptimizer extends UseScopeOptimizer {
+public class JavaCompilerReferencesInCodeScopeOptimizer implements InCodeScopeOptimizer {
   @Nullable
   @Override
-  public GlobalSearchScope getScopeToExclude(@NotNull PsiElement element) {
-    return CompilerReferenceService.getInstance(element.getProject()).getScopeWithoutReferences(element);
+  public GlobalSearchScope getOptimizedScopeInCode(@NotNull PsiElement element) {
+    return CompilerReferenceService.getInstance(element.getProject()).getMayContainReferencesInCodeScope(element);
   }
 }
diff --git a/platform/indexing-api/src/com/intellij/psi/search/InCodeScopeOptimizer.java b/platform/indexing-api/src/com/intellij/psi/search/InCodeScopeOptimizer.java
new file mode 100644 (file)
index 0000000..178df2e
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2016 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.psi.search;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public interface InCodeScopeOptimizer {
+  ExtensionPointName<InCodeScopeOptimizer> EP_NAME = ExtensionPointName.create("com.intellij.inCodeScopeOptimizer");
+
+  @Nullable
+  GlobalSearchScope getOptimizedScopeInCode(@NotNull PsiElement element);
+}
index 84fe188c138229c0efc9019a9a1e0f7ff680c45a..0d542827cb5a4f06e95425597bd3d7d151ec2183 100644 (file)
@@ -28,6 +28,8 @@ import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -60,7 +62,7 @@ public class SearchRequestCollector {
                          short searchContext,
                          boolean caseSensitive,
                          @NotNull PsiElement searchTarget) {
-    searchWord(word, searchScope, searchContext, caseSensitive, getContainerName(searchTarget), new SingleTargetRequestResultProcessor(searchTarget));
+    searchWord(word, searchScope, searchContext, caseSensitive, getContainerName(searchTarget), new SingleTargetRequestResultProcessor(searchTarget), searchTarget);
   }
 
   private void searchWord(@NotNull String word,
@@ -68,11 +70,35 @@ public class SearchRequestCollector {
                           short searchContext,
                           boolean caseSensitive,
                           String containerName,
-                          @NotNull RequestResultProcessor processor) {
+                          @NotNull RequestResultProcessor processor,
+                          PsiElement searchTarget) {
     if (!makesSenseToSearch(word, searchScope)) return;
+
+    Collection<PsiSearchRequest> requests = null;
+    if (searchTarget != null && (searchScope instanceof GlobalSearchScope) && ((searchContext & UsageSearchContext.IN_CODE) != 0 || searchContext == UsageSearchContext.ANY)) {
+      for (InCodeScopeOptimizer optimizer : InCodeScopeOptimizer.EP_NAME.getExtensions()) {
+        final GlobalSearchScope optimizedSourcesSearchScope = optimizer.getOptimizedScopeInCode(searchTarget);
+        if (optimizedSourcesSearchScope != null) {
+          short exceptCodeSearchContext = searchContext == UsageSearchContext.ANY
+          ? (short)(searchContext ^ UsageSearchContext.IN_CODE)
+          : (UsageSearchContext.IN_COMMENTS |
+             UsageSearchContext.IN_STRINGS |
+             UsageSearchContext.IN_FOREIGN_LANGUAGES |
+             UsageSearchContext.IN_PLAIN_TEXT);
+          final GlobalSearchScope effectiveScopeWithSources = ((GlobalSearchScope)searchScope).intersectWith(optimizedSourcesSearchScope);
+          final GlobalSearchScope effectiveScopeWithoutSources =
+            ((GlobalSearchScope)searchScope).intersectWith(GlobalSearchScope.notScope(optimizedSourcesSearchScope));
+          requests = ContainerUtil.list(new PsiSearchRequest(effectiveScopeWithSources, word, searchContext, caseSensitive, containerName, processor),
+                                        new PsiSearchRequest(effectiveScopeWithoutSources, word, exceptCodeSearchContext, caseSensitive, containerName, processor));
+        }
+      }
+    }
+    if (requests == null) {
+      requests = Collections.singleton(new PsiSearchRequest(searchScope, word, searchContext, caseSensitive, containerName, processor));
+    }
+
     synchronized (lock) {
-      PsiSearchRequest request = new PsiSearchRequest(searchScope, word, searchContext, caseSensitive, containerName, processor);
-      myWordRequests.add(request);
+      myWordRequests.addAll(requests);
     }
   }
   public void searchWord(@NotNull String word,
@@ -81,7 +107,7 @@ public class SearchRequestCollector {
                           boolean caseSensitive,
                           @NotNull PsiElement searchTarget,
                           @NotNull RequestResultProcessor processor) {
-    searchWord(word, searchScope, searchContext, caseSensitive, getContainerName(searchTarget), processor);
+    searchWord(word, searchScope, searchContext, caseSensitive, getContainerName(searchTarget), processor, searchTarget);
   }
 
   private static String getContainerName(@NotNull final PsiElement target) {
@@ -111,7 +137,7 @@ public class SearchRequestCollector {
                          short searchContext,
                          boolean caseSensitive,
                          @NotNull RequestResultProcessor processor) {
-    searchWord(word, searchScope, searchContext, caseSensitive, (String)null, processor);
+    searchWord(word, searchScope, searchContext, caseSensitive, null, processor, null);
   }
 
   private static boolean makesSenseToSearch(@NotNull String word, @NotNull SearchScope searchScope) {
index 016b8f89683d21f9ca4b1f4c8d48044ea29af1f6..13b6174833520d7259a8356c0554366d0402fd74 100644 (file)
     <extensionPoint name="resolveScopeEnlarger" interface="com.intellij.psi.ResolveScopeEnlarger"/>
     <extensionPoint name="resolveScopeProvider" interface="com.intellij.psi.ResolveScopeProvider"/>
     <extensionPoint name="useScopeOptimizer" interface="com.intellij.psi.search.UseScopeOptimizer"/>
+    <extensionPoint name="inCodeScopeOptimizer" interface="com.intellij.psi.search.InCodeScopeOptimizer"/>
 
     <extensionPoint name="generatedSourcesFilter" interface="com.intellij.openapi.roots.GeneratedSourcesFilter"/>
     <extensionPoint name="outOfSourcesChecker" interface="com.intellij.openapi.projectRoots.OutOfSourcesChecker"/>
index 069fd6e320481137daa8181faa68e433b2dd003c..5bf0a71ad8861a68bf8149bb2ec8b0650c68b555 100644 (file)
 
     <fileBasedIndex implementation="com.intellij.psi.impl.search.JavaNullMethodArgumentIndex"/>
 
-    <useScopeOptimizer implementation="com.intellij.find.compiler.CompilerReferenceScopeOptimizer"/>
+    <inCodeScopeOptimizer implementation="com.intellij.compiler.JavaCompilerReferencesInCodeScopeOptimizer"/>
   </extensions>
 
   <actions>