read actions are not necessary in completion now

This commit is contained in:
peter
2010-10-30 15:23:27 +04:00
parent c9133d2c37
commit 706ff88a9c
4 changed files with 109 additions and 192 deletions
@@ -20,10 +20,8 @@ import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.lang.LangBundle;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.PsiJavaElementPattern;
import com.intellij.psi.*;
@@ -83,18 +81,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
final StatisticsInfo[] infos =
StatisticsManager.getInstance().getAllValues(JavaCompletionStatistician.CLASS_NAME_COMPLETION_PREFIX + StringUtil.capitalsOnly(prefix));
for (final StatisticsInfo info : infos) {
final PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
public PsiClass[] compute() {
return JavaPsiFacade.getInstance(project).findClasses(info.getValue(), file.getResolveScope());
}
});
for (final PsiClass psiClass : classes) {
final boolean isExcluded = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
return JavaCompletionUtil.isInExcludedPackage(psiClass);
}
}).booleanValue();
if (!isExcluded) {
for (final PsiClass psiClass : JavaPsiFacade.getInstance(project).findClasses(info.getValue(), file.getResolveScope())) {
if (!JavaCompletionUtil.isInExcludedPackage(psiClass)) {
result.addElement(AllClassesGetter.createLookupItem(psiClass));
}
}
@@ -102,25 +90,19 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
if (afterNew) {
final PsiExpression expr = PsiTreeUtil.getContextOfType(insertedElement, PsiExpression.class, true);
if (expr != null) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
for (final ExpectedTypeInfo info : ExpectedTypesProvider.getInstance(project).getExpectedTypes(expr, true)) {
final PsiType type = info.getType();
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
if (psiClass != null) {
result.addElement(AllClassesGetter.createLookupItem(psiClass));
}
final PsiType defaultType = info.getDefaultType();
if (!defaultType.equals(type)) {
final PsiClass defClass = PsiUtil.resolveClassInType(defaultType);
if (defClass != null) {
result.addElement(AllClassesGetter.createLookupItem(defClass));
}
}
}
for (final ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes(expr, true)) {
final PsiType type = info.getType();
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
if (psiClass != null) {
result.addElement(AllClassesGetter.createLookupItem(psiClass));
}
final PsiType defaultType = info.getDefaultType();
if (!defaultType.equals(type)) {
final PsiClass defClass = PsiUtil.resolveClassInType(defaultType);
if (defClass != null) {
result.addElement(AllClassesGetter.createLookupItem(defClass));
}
});
}
}
}
@@ -2,7 +2,6 @@ package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.VariableLookupItem;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
@@ -61,19 +60,15 @@ public class JavaGlobalMemberNameCompletionContributor extends CompletionContrib
}
};
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
final PsiFile file = position.getContainingFile();
if (file instanceof PsiJavaFile) {
final PsiImportList importList = ((PsiJavaFile)file).getImportList();
if (importList != null) {
for (PsiImportStaticStatement statement : importList.getImportStaticStatements()) {
processor.importMembersOf(statement.resolveTargetClass());
}
}
final PsiFile file = position.getContainingFile();
if (file instanceof PsiJavaFile) {
final PsiImportList importList = ((PsiJavaFile)file).getImportList();
if (importList != null) {
for (PsiImportStaticStatement statement : importList.getImportStaticStatements()) {
processor.importMembersOf(statement.resolveTargetClass());
}
}
});
}
return processor;
}
@@ -18,8 +18,6 @@ package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.*;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.lookup.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
@@ -129,11 +127,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
extend(CompletionType.SMART, psiElement().afterLeaf(PsiKeyword.INSTANCEOF), new CompletionProvider<CompletionParameters>(false) {
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
final PsiElement position = parameters.getPosition();
final PsiType[] leftTypes = ApplicationManager.getApplication().runReadAction(new Computable<PsiType[]>() {
public PsiType[] compute() {
return InstanceOfLeftPartTypeGetter.getLeftTypes(position);
}
});
final PsiType[] leftTypes = InstanceOfLeftPartTypeGetter.getLeftTypes(position);
final Set<PsiClassType> expectedClassTypes = new LinkedHashSet<PsiClassType>();
final Set<PsiClass> parameterizedTypes = new THashSet<PsiClass>();
for (final PsiType type : leftTypes) {
@@ -203,12 +197,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
extend(CompletionType.SMART, INSIDE_EXPRESSION, new ExpectedTypeBasedCompletionProvider() {
protected void addCompletions(final CompletionParameters params, final CompletionResultSet result, final Collection<ExpectedTypeInfo> _infos) {
final Set<ExpectedTypeInfo> infos = ApplicationManager.getApplication().runReadAction(new Computable<Set<ExpectedTypeInfo>>() {
public Set<ExpectedTypeInfo> compute() {
return new THashSet<ExpectedTypeInfo>(_infos, EXPECTED_TYPE_INFO_STRATEGY);
}
});
for (final ExpectedTypeInfo info : infos) {
for (final ExpectedTypeInfo info : new THashSet<ExpectedTypeInfo>(_infos, EXPECTED_TYPE_INFO_STRATEGY)) {
final JavaSmartCompletionParameters parameters = new JavaSmartCompletionParameters(params, info);
final PsiType type = info.getType();
@@ -235,8 +224,8 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
});
extend(CompletionType.SMART, or(
PsiJavaPatterns.psiElement().withParent(PsiNameValuePair.class),
PsiJavaPatterns.psiElement().withSuperParent(2, PsiNameValuePair.class)), new CompletionProvider<CompletionParameters>() {
PsiJavaPatterns.psiElement().withParent(PsiNameValuePair.class),
PsiJavaPatterns.psiElement().withSuperParent(2, PsiNameValuePair.class)), new CompletionProvider<CompletionParameters>() {
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
final PsiElement element = parameters.getPosition();
final ElementPattern<? extends PsiElement> leftNeighbor = PsiJavaPatterns.psiElement().afterLeaf(PsiJavaPatterns.psiElement().withText("."));
@@ -255,8 +244,8 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
});
extend(CompletionType.SMART, psiElement().inside(
psiElement(PsiDocTag.class).withName(
string().oneOf(PsiKeyword.THROWS, EXCEPTION_TAG))), new CompletionProvider<CompletionParameters>() {
psiElement(PsiDocTag.class).withName(
string().oneOf(PsiKeyword.THROWS, EXCEPTION_TAG))), new CompletionProvider<CompletionParameters>() {
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
final PsiElement element = parameters.getPosition();
final Set<PsiClass> throwsSet = new HashSet<PsiClass>();
@@ -275,8 +264,8 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
final Key<PsiTryStatement> tryKey = Key.create("try");
extend(CompletionType.SMART, psiElement().afterLeaf(
psiElement().withText("("))
.withSuperParent(3, psiElement(PsiCatchSection.class).withParent(
psiElement().withText("("))
.withSuperParent(3, psiElement(PsiCatchSection.class).withParent(
psiElement(PsiTryStatement.class).save(tryKey))), new CompletionProvider<CompletionParameters>() {
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
final PsiCodeBlock tryBlock = context.get(tryKey).getTryBlock();
@@ -305,40 +294,32 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
boolean isLast = parameterIndex == typeParameters.length - 1;
final TailType tail = isLast ? new CharTailType('>') : TailType.COMMA;
boolean hasExpected = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper();
final PsiType[] psiTypes = ExpectedTypesGetter.getExpectedTypes(context, false);
if (psiTypes.length == 0) return false;
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper();
final PsiType[] psiTypes = ExpectedTypesGetter.getExpectedTypes(context, false);
if (psiTypes.length > 0) {
for (PsiType type : psiTypes) {
if (!(type instanceof PsiClassType)) continue;
final PsiClassType.ClassResolveResult result = ((PsiClassType)type).resolveGenerics();
final PsiClass typeClass = result.getElement();
final PsiSubstitutor substitutor = result.getSubstitutor();
for (PsiType type : psiTypes) {
if (!(type instanceof PsiClassType)) continue;
final PsiClassType.ClassResolveResult result = ((PsiClassType)type).resolveGenerics();
final PsiClass typeClass = result.getElement();
final PsiSubstitutor substitutor = result.getSubstitutor();
if (!InheritanceUtil.isInheritorOrSelf(referencedClass, typeClass, true)) continue;
if (!InheritanceUtil.isInheritorOrSelf(referencedClass, typeClass, true)) continue;
final PsiSubstitutor currentSubstitutor =
TypeConversionUtil.getClassSubstitutor(typeClass, referencedClass, PsiSubstitutor.EMPTY);
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(typeClass)) {
final PsiType argSubstitution = substitutor.substitute(parameter);
final PsiType paramSubstitution = currentSubstitutor.substitute(parameter);
final PsiType substitution = resolveHelper
.getSubstitutionForTypeParameter(targetParameter, paramSubstitution, argSubstitution, false,
PsiUtil.getLanguageLevel(context));
if (substitution != null && substitution != PsiType.NULL) {
final LookupItem item = PsiTypeLookupItem.createLookupItem(substitution, context);
resultSet.addElement(TailTypeDecorator.withTail(item.setInsertHandler(new DefaultInsertHandler()), tail));
}
final PsiSubstitutor currentSubstitutor =
TypeConversionUtil.getClassSubstitutor(typeClass, referencedClass, PsiSubstitutor.EMPTY);
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(typeClass)) {
final PsiType argSubstitution = substitutor.substitute(parameter);
final PsiType paramSubstitution = currentSubstitutor.substitute(parameter);
final PsiType substitution = resolveHelper
.getSubstitutionForTypeParameter(targetParameter, paramSubstitution, argSubstitution, false,
PsiUtil.getLanguageLevel(context));
if (substitution != null && substitution != PsiType.NULL) {
final LookupItem item = PsiTypeLookupItem.createLookupItem(substitution, context);
resultSet.addElement(TailTypeDecorator.withTail(item.setInsertHandler(new DefaultInsertHandler()), tail));
}
}
return true;
}
}).booleanValue();
if (!hasExpected) {
} else {
final List<PsiClassType> typeList = Collections.singletonList((PsiClassType)TypeConversionUtil.typeParameterErasure(targetParameter));
processInheritors(parameters, context, parameters.getOriginalFile(), typeList, new Consumer<PsiType>() {
public void consume(final PsiType type) {
@@ -363,37 +344,29 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
final List<PsiArrayType> expectedArrayTypes = new SmartList<PsiArrayType>();
final List<ExpectedTypeInfo> infos = new SmartList<ExpectedTypeInfo>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
ContainerUtil.addAll(infos, getExpectedTypes(parameters));
for (PsiType type : ExpectedTypesGetter.getExpectedTypes(identifierCopy, true)) {
if (type instanceof PsiClassType) {
final PsiClassType classType = (PsiClassType)type;
if (classType.resolve() != null) {
expectedClassTypes.add(classType);
}
}
else if (type instanceof PsiArrayType) {
expectedArrayTypes.add((PsiArrayType)type);
}
ContainerUtil.addAll(infos, getExpectedTypes(parameters));
for (PsiType type : ExpectedTypesGetter.getExpectedTypes(identifierCopy, true)) {
if (type instanceof PsiClassType) {
final PsiClassType classType = (PsiClassType)type;
if (classType.resolve() != null) {
expectedClassTypes.add(classType);
}
}
});
else if (type instanceof PsiArrayType) {
expectedArrayTypes.add((PsiArrayType)type);
}
}
for (final PsiArrayType type : expectedArrayTypes) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), identifierCopy);
if (item.getObject() instanceof PsiClass) {
JavaCompletionUtil.setShowFQN(item);
}
item.setInsertHandler(new DefaultInsertHandler()); //braces & shortening
result.addElement(decorate(item, infos));
}
});
final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), identifierCopy);
if (item.getObject() instanceof PsiClass) {
JavaCompletionUtil.setShowFQN(item);
}
item.setInsertHandler(new DefaultInsertHandler()); //braces & shortening
result.addElement(decorate(item, infos));
}
processInheritors(parameters, identifierCopy, file, expectedClassTypes, new Consumer<PsiType>() {
public void consume(final PsiType type) {
addExpectedType(result, type, parameters, infos);
@@ -466,38 +439,34 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
public static void processInheritors(final CompletionParameters parameters, final PsiElement identifierCopy, final PsiFile file, final Collection<PsiClassType> expectedClassTypes,
final Consumer<PsiType> consumer, final PrefixMatcher matcher) {
final Consumer<PsiType> consumer, final PrefixMatcher matcher) {
//quick
for (final PsiClassType type : expectedClassTypes) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
consumer.consume(type);
consumer.consume(type);
final PsiClassType.ClassResolveResult baseResult = JavaCompletionUtil.originalize(type).resolveGenerics();
final PsiClass baseClass = baseResult.getElement();
if (baseClass == null) return;
final PsiClassType.ClassResolveResult baseResult = JavaCompletionUtil.originalize(type).resolveGenerics();
final PsiClass baseClass = baseResult.getElement();
if (baseClass == null) return;
final PsiSubstitutor baseSubstitutor = baseResult.getSubstitutor();
final PsiSubstitutor baseSubstitutor = baseResult.getSubstitutor();
final THashSet<PsiType> statVariants = new THashSet<PsiType>();
final Processor<PsiClass> processor = CodeInsightUtil
.createInheritorsProcessor(parameters.getPosition(), type, 0, false, statVariants, baseClass, baseSubstitutor);
final StatisticsInfo[] statisticsInfos =
StatisticsManager.getInstance().getAllValues(JavaStatisticsManager.getAfterNewKey(type));
for (final StatisticsInfo statisticsInfo : statisticsInfos) {
final String value = statisticsInfo.getValue();
if (value.startsWith(JavaStatisticsManager.CLASS_PREFIX)) {
final String qname = value.substring(JavaStatisticsManager.CLASS_PREFIX.length());
final PsiClass psiClass = JavaPsiFacade.getInstance(file.getProject()).findClass(qname, file.getResolveScope());
if (psiClass != null && !PsiTreeUtil.isAncestor(file, psiClass, true) && !processor.process(psiClass)) break;
}
}
for (final PsiType variant : statVariants) {
consumer.consume(variant);
}
final THashSet<PsiType> statVariants = new THashSet<PsiType>();
final Processor<PsiClass> processor = CodeInsightUtil.createInheritorsProcessor(parameters.getPosition(), type, 0, false,
statVariants, baseClass, baseSubstitutor);
final StatisticsInfo[] statisticsInfos =
StatisticsManager.getInstance().getAllValues(JavaStatisticsManager.getAfterNewKey(type));
for (final StatisticsInfo statisticsInfo : statisticsInfos) {
final String value = statisticsInfo.getValue();
if (value.startsWith(JavaStatisticsManager.CLASS_PREFIX)) {
final String qname = value.substring(JavaStatisticsManager.CLASS_PREFIX.length());
final PsiClass psiClass = JavaPsiFacade.getInstance(file.getProject()).findClass(qname, file.getResolveScope());
if (psiClass != null && !PsiTreeUtil.isAncestor(file, psiClass, true) && !processor.process(psiClass)) break;
}
});
}
for (final PsiType variant : statVariants) {
consumer.consume(variant);
}
}
//long
@@ -507,22 +476,10 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
}
};
for (final PsiClassType type : expectedClassTypes) {
final boolean shouldSearchForInheritors = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
final PsiClass psiClass = type.resolve();
return psiClass != null && psiClass.isValid() && !psiClass.hasModifierProperty(PsiModifier.FINAL);
}
}).booleanValue();
if (shouldSearchForInheritors) {
final Set<PsiType> psiTypes = CodeInsightUtil.addSubtypes(type, identifierCopy, false, shortNameCondition);
for (final PsiType psiType : psiTypes) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
if (psiType.isValid()) {
consumer.consume(psiType);
}
}
});
final PsiClass psiClass = type.resolve();
if (psiClass != null && !psiClass.hasModifierProperty(PsiModifier.FINAL)) {
for (final PsiType psiType : CodeInsightUtil.addSubtypes(type, identifierCopy, false, shortNameCondition)) {
consumer.consume(psiType);
}
}
}
@@ -3,9 +3,7 @@ package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.daemon.impl.quickfix.StaticImportMethodFix;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
@@ -53,42 +51,27 @@ public abstract class StaticMemberProcessor {
final PrefixMatcher matcher = resultSet.getPrefixMatcher();
final GlobalSearchScope scope = myPosition.getResolveScope();
final PsiShortNamesCache namesCache = JavaPsiFacade.getInstance(myProject).getShortNamesCache();
final String[] methodNames = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
public String[] compute() {
return namesCache.getAllMethodNames();
}
});
for (final String methodName : methodNames) {
for (final String methodName : namesCache.getAllMethodNames()) {
if (matcher.prefixMatches(methodName)) {
final PsiMethod[] methods = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod[]>() {
public PsiMethod[] compute() {
return namesCache.getMethodsByName(methodName, scope);
}
});
for (final PsiMethod method : methods) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
if (isStaticallyImportable(method)) {
final PsiClass containingClass = method.getContainingClass();
assert containingClass != null;
for (final PsiMethod method : namesCache.getMethodsByName(methodName, scope)) {
if (isStaticallyImportable(method)) {
final PsiClass containingClass = method.getContainingClass();
assert containingClass != null;
final boolean shouldImport = myStaticImportedClasses.contains(containingClass);
if (!myHintShown &&
!shouldImport &&
FeatureUsageTracker.getInstance().isToBeShown(JavaCompletionFeatures.IMPORT_STATIC, myProject) &&
CompletionService.getCompletionService().getAdvertisementText() == null) {
final String shortcut = CompletionContributor.getActionShortcut("EditorRight");
if (shortcut != null) {
CompletionService.getCompletionService().setAdvertisementText("To import a method statically, press " + shortcut);
}
myHintShown = true;
}
consumer.consume(createLookupElement(method, containingClass, shouldImport));
final boolean shouldImport = myStaticImportedClasses.contains(containingClass);
if (!myHintShown &&
!shouldImport &&
FeatureUsageTracker.getInstance().isToBeShown(JavaCompletionFeatures.IMPORT_STATIC, myProject) &&
CompletionService.getCompletionService().getAdvertisementText() == null) {
final String shortcut = CompletionContributor.getActionShortcut("EditorRight");
if (shortcut != null) {
CompletionService.getCompletionService().setAdvertisementText("To import a method statically, press " + shortcut);
}
myHintShown = true;
}
});
consumer.consume(createLookupElement(method, containingClass, shouldImport));
}
}
}
}