do not forget about comments while searching using javac ast

This commit is contained in:
Dmitry Batkovich
2016-09-28 15:22:37 +03:00
parent 99a8cbb31a
commit 000b0a0e78
8 changed files with 91 additions and 30 deletions
@@ -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
@@ -194,4 +194,4 @@ public class DataFlowInspection extends DataFlowInspectionBase {
}
}
}
}
@@ -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();
@@ -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);
}
}
@@ -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);
}
@@ -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) {
@@ -260,6 +260,7 @@
<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"/>
+1 -1
View File
@@ -1803,7 +1803,7 @@
<fileBasedIndex implementation="com.intellij.psi.impl.search.JavaNullMethodArgumentIndex"/>
<useScopeOptimizer implementation="com.intellij.find.compiler.CompilerReferenceScopeOptimizer"/>
<inCodeScopeOptimizer implementation="com.intellij.compiler.JavaCompilerReferencesInCodeScopeOptimizer"/>
</extensions>
<actions>