From 0925c6dfcbf11804bebe371d92a447b1977ebf7b Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 10 Apr 2012 12:06:25 +0400 Subject: [PATCH] better create local from usage: more sane variants --- .../codeInsight/ExpectedTypesProvider.java | 153 ++++++++++-------- .../impl/quickfix/CreateFromUsageUtils.java | 41 +++-- .../psi/impl/CompositeShortNamesCache.java | 16 ++ .../psi/impl/PsiShortNamesCacheImpl.java | 19 ++- .../psi/search/PsiShortNamesCache.java | 2 + .../search/DelegatingGlobalSearchScope.java | 36 ----- .../psi/search/GlobalSearchScope.java | 18 +++ .../lang/stubs/GroovyShortNamesCache.java | 6 + 8 files changed, 163 insertions(+), 128 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java index 258ac5a02d18..450244bb44bc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java @@ -59,19 +59,23 @@ public class ExpectedTypesProvider { private ExpectedTypesProvider() { } - public static ExpectedTypesProvider getInstance(Project project) { + public static ExpectedTypesProvider getInstance(@NotNull Project project) { return ServiceManager.getService(project, ExpectedTypesProvider.class); } private static final int MAX_COUNT = 50; private static final ExpectedClassProvider ourGlobalScopeClassProvider = new ExpectedClassProvider() { - public PsiField[] findDeclaredFields(final PsiManager manager, String name) { + @Override + @NotNull + public PsiField[] findDeclaredFields(@NotNull final PsiManager manager, @NotNull String name) { final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(manager.getProject()); GlobalSearchScope scope = GlobalSearchScope.allScope(manager.getProject()); return cache.getFieldsByName(name, scope); } - public PsiMethod[] findDeclaredMethods(final PsiManager manager, String name) { + @Override + @NotNull + public PsiMethod[] findDeclaredMethods(@NotNull final PsiManager manager, @NotNull String name) { final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(manager.getProject()); GlobalSearchScope scope = GlobalSearchScope.allScope(manager.getProject()); return cache.getMethodsByNameIfNotMoreThan(name, scope, MAX_COUNT); @@ -80,12 +84,12 @@ public class ExpectedTypesProvider { private static final PsiType[] PRIMITIVE_TYPES = {PsiType.BYTE, PsiType.CHAR, PsiType.SHORT, PsiType.INT, PsiType.LONG, PsiType.FLOAT, PsiType.DOUBLE}; @NotNull - public static ExpectedTypeInfo createInfo(@NotNull PsiType type, int kind, PsiType defaultType, TailType tailType) { + public static ExpectedTypeInfo createInfo(@NotNull PsiType type, int kind, PsiType defaultType, @NotNull TailType tailType) { return createInfoImpl(type, kind, defaultType, tailType); } @NotNull - private static ExpectedTypeInfoImpl createInfoImpl(@NotNull PsiType type, int kind, PsiType defaultType, TailType tailType) { + private static ExpectedTypeInfoImpl createInfoImpl(@NotNull PsiType type, int kind, PsiType defaultType, @NotNull TailType tailType) { int dims = 0; while (type instanceof PsiArrayType) { type = ((PsiArrayType) type).getComponentType(); @@ -129,8 +133,8 @@ public class ExpectedTypesProvider { return visitor.getResult(); } - public static PsiType[] processExpectedTypes(ExpectedTypeInfo[] infos, - final PsiTypeVisitor visitor, Project project) { + public static PsiType[] processExpectedTypes(@NotNull ExpectedTypeInfo[] infos, + @NotNull PsiTypeVisitor visitor, @NotNull Project project) { Set set = new LinkedHashSet(); for (ExpectedTypeInfo info : infos) { ExpectedTypeInfoImpl infoImpl = (ExpectedTypeInfoImpl)info; @@ -156,19 +160,20 @@ public class ExpectedTypesProvider { else if (infoImpl.getKind() == ExpectedTypeInfo.TYPE_OR_SUBTYPE) { if (infoImpl.getType() instanceof PsiPrimitiveType && infoImpl.getDimCount() == 0) { processPrimitiveTypeAndSubtypes((PsiPrimitiveType)infoImpl.getType(), visitor, set); - } //else too expensive to search + } + //else too expensive to search } } return set.toArray(new PsiType[set.size()]); } - private static void processType(@NotNull PsiType type, PsiTypeVisitor visitor, Set typeSet) { + private static void processType(@NotNull PsiType type, @NotNull PsiTypeVisitor visitor, @NotNull Set typeSet) { PsiType accepted = type.accept(visitor); if (accepted != null) typeSet.add(accepted); } - public static void processPrimitiveTypeAndSubtypes(PsiPrimitiveType type, PsiTypeVisitor visitor, Set set) { + public static void processPrimitiveTypeAndSubtypes(@NotNull PsiPrimitiveType type, @NotNull PsiTypeVisitor visitor, @NotNull Set set) { if (type.equals(PsiType.BOOLEAN) || type.equals(PsiType.VOID) || type.equals(PsiType.NULL)) return; for (int i = 0; ; i++) { @@ -178,7 +183,7 @@ public class ExpectedTypesProvider { } } - public static void processAllSuperTypes(PsiType type, int dimCount, PsiTypeVisitor visitor, Project project, Set set) { + public static void processAllSuperTypes(@NotNull PsiType type, int dimCount, @NotNull PsiTypeVisitor visitor, @NotNull Project project, @NotNull Set set) { if (type instanceof PsiPrimitiveType) { if (type.equals(PsiType.BOOLEAN) || type.equals(PsiType.VOID) || type.equals(PsiType.NULL)) return; @@ -232,12 +237,13 @@ public class ExpectedTypesProvider { myUsedAfter = usedAfter; } + @NotNull public ExpectedTypeInfo[] getResult() { return myResult; } @Override - public void visitAnnotationMethod(final PsiAnnotationMethod method) { + public void visitAnnotationMethod(@NotNull final PsiAnnotationMethod method) { if (myExpr == method.getDefaultValue()) { final PsiType type = method.getReturnType(); if (type != null) { @@ -247,7 +253,7 @@ public class ExpectedTypesProvider { } @Override - public void visitReferenceExpression(PsiReferenceExpression expression) { + public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { if (myForCompletion) { final MyParentVisitor visitor = new MyParentVisitor(expression, myForCompletion, myClassProvider, myVoidable, myUsedAfter); expression.getParent().accept(visitor); @@ -280,12 +286,12 @@ public class ExpectedTypesProvider { } } - @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { + @Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { myExpr = (PsiExpression)myExpr.getParent(); expression.getParent().accept(this); } - @Override public void visitAnnotationArrayInitializer(PsiArrayInitializerMemberValue initializer) { + @Override public void visitAnnotationArrayInitializer(@NotNull PsiArrayInitializerMemberValue initializer) { final PsiElement parent = initializer.getParent(); final PsiType type; if (parent instanceof PsiNameValuePair) { @@ -299,19 +305,20 @@ public class ExpectedTypesProvider { } } - @Override public void visitNameValuePair(PsiNameValuePair pair) { + @Override public void visitNameValuePair(@NotNull PsiNameValuePair pair) { final PsiType type = getAnnotationMethodType(pair); if (type == null) return; final ExpectedTypeInfoImpl info = createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.UNKNOWN); if (type instanceof PsiArrayType) { myResult = new ExpectedTypeInfo[]{info, createInfoImpl(((PsiArrayType)type).getComponentType(), ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.UNKNOWN)}; - } else { + } + else { myResult = new ExpectedTypeInfo[] {info}; } } @Nullable - private static PsiType getAnnotationMethodType(final PsiNameValuePair pair) { + private static PsiType getAnnotationMethodType(@NotNull final PsiNameValuePair pair) { final PsiReference reference = pair.getReference(); if (reference != null) { final PsiElement method = reference.resolve(); @@ -359,7 +366,7 @@ public class ExpectedTypesProvider { myResult = new ExpectedTypeInfo[]{info}; } - @Override public void visitForStatement(PsiForStatement statement) { + @Override public void visitForStatement(@NotNull PsiForStatement statement) { if (myExpr.equals(statement.getCondition())) { ExpectedTypeInfoImpl info = createInfoImpl(PsiType.BOOLEAN, ExpectedTypeInfo.TYPE_STRICTLY, PsiType.BOOLEAN, TailType.SEMICOLON); @@ -368,7 +375,7 @@ public class ExpectedTypesProvider { } @Override - public void visitAssertStatement(PsiAssertStatement statement) { + public void visitAssertStatement(@NotNull PsiAssertStatement statement) { if (statement.getAssertDescription() == myExpr) { final PsiClassType stringType = PsiType.getJavaLangString(myExpr.getManager(), myExpr.getResolveScope()); ExpectedTypeInfoImpl info = createInfoImpl(stringType, ExpectedTypeInfo.TYPE_STRICTLY, @@ -381,7 +388,7 @@ public class ExpectedTypesProvider { } } - @Override public void visitForeachStatement(PsiForeachStatement statement) { + @Override public void visitForeachStatement(@NotNull PsiForeachStatement statement) { if (myExpr.equals(statement.getIteratedValue())) { PsiType type = statement.getIterationParameter().getType(); @@ -395,7 +402,8 @@ public class ExpectedTypesProvider { JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Iterable", statement.getResolveScope()); if (iterableClass == null || iterableClass.getTypeParameters().length != 1) { myResult = new ExpectedTypeInfo[]{info1}; - } else { + } + else { Map map = new HashMap(); map.put(iterableClass.getTypeParameters()[0], PsiWildcardType.createExtends(manager, type)); PsiSubstitutor substitutor = factory.createSubstitutor(map); @@ -408,7 +416,7 @@ public class ExpectedTypesProvider { } } - @Override public void visitSwitchStatement(PsiSwitchStatement statement) { + @Override public void visitSwitchStatement(@NotNull PsiSwitchStatement statement) { ExpectedTypeInfoImpl info = createInfoImpl(PsiType.LONG, ExpectedTypeInfo.TYPE_OR_SUBTYPE, PsiType.INT, TailType.NONE); if (!PsiUtil.isLanguageLevel5OrHigher(statement)) { @@ -423,7 +431,7 @@ public class ExpectedTypesProvider { } @Override - public void visitSwitchLabelStatement(final PsiSwitchLabelStatement statement) { + public void visitSwitchLabelStatement(@NotNull final PsiSwitchLabelStatement statement) { final PsiSwitchStatement switchStatement = statement.getEnclosingSwitchStatement(); if (switchStatement != null) { final PsiExpression expression = switchStatement.getExpression(); @@ -436,13 +444,13 @@ public class ExpectedTypesProvider { } } - @Override public void visitSynchronizedStatement(PsiSynchronizedStatement statement) { + @Override public void visitSynchronizedStatement(@NotNull PsiSynchronizedStatement statement) { PsiElementFactory factory = JavaPsiFacade.getInstance(statement.getProject()).getElementFactory(); PsiType objectType = factory.createTypeByFQClassName("java.lang.Object", myExpr.getResolveScope()); myResult = new ExpectedTypeInfo[]{createInfoImpl(objectType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, objectType, TailType.NONE)}; } - @Override public void visitVariable(PsiVariable variable) { + @Override public void visitVariable(@NotNull PsiVariable variable) { PsiType type = variable.getType(); ExpectedTypeInfoImpl info = createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, variable instanceof PsiResourceVariable ? TailType.NONE : TailType.SEMICOLON); @@ -450,7 +458,7 @@ public class ExpectedTypesProvider { myResult = new ExpectedTypeInfo[]{info}; } - @Override public void visitAssignmentExpression(PsiAssignmentExpression assignment) { + @Override public void visitAssignmentExpression(@NotNull PsiAssignmentExpression assignment) { if (myExpr.equals(assignment.getRExpression())) { PsiExpression lExpr = assignment.getLExpression(); PsiType type = lExpr.getType(); @@ -498,7 +506,7 @@ public class ExpectedTypesProvider { } } - private static TailType getAssignmentRValueTailType(PsiAssignmentExpression assignment) { + private static TailType getAssignmentRValueTailType(@NotNull PsiAssignmentExpression assignment) { if (assignment.getParent() instanceof PsiExpressionStatement) { if (!(assignment.getParent().getParent() instanceof PsiForStatement)) { return TailType.SEMICOLON; @@ -512,7 +520,7 @@ public class ExpectedTypesProvider { return TailType.NONE; } - @Override public void visitExpressionList(PsiExpressionList list) { + @Override public void visitExpressionList(@NotNull PsiExpressionList list) { PsiResolveHelper helper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper(); if (list.getParent() instanceof PsiMethodCallExpression) { PsiMethodCallExpression methodCall = (PsiMethodCallExpression)list.getParent(); @@ -530,8 +538,8 @@ public class ExpectedTypesProvider { } } - private void getExpectedArgumentsTypesForEnumConstant(final PsiEnumConstant enumConstant, - final PsiExpressionList list) { + private void getExpectedArgumentsTypesForEnumConstant(@NotNull final PsiEnumConstant enumConstant, + @NotNull final PsiExpressionList list) { final PsiClass aClass = enumConstant.getContainingClass(); if (aClass != null) { LOG.assertTrue(aClass.isEnum()); @@ -539,8 +547,8 @@ public class ExpectedTypesProvider { } } - private void getExpectedArgumentsTypesForNewExpression(final PsiNewExpression newExpr, - final PsiExpressionList list) { + private void getExpectedArgumentsTypesForNewExpression(@NotNull final PsiNewExpression newExpr, + @NotNull final PsiExpressionList list) { PsiType newType = newExpr.getType(); if (newType instanceof PsiClassType) { JavaResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(newType); @@ -562,8 +570,8 @@ public class ExpectedTypesProvider { } } - private void getExpectedTypesForConstructorCall(final PsiClass referencedClass, - final PsiExpressionList argumentList, + private void getExpectedTypesForConstructorCall(@NotNull final PsiClass referencedClass, + @NotNull final PsiExpressionList argumentList, final PsiSubstitutor substitutor) { List array = new ArrayList(); for (PsiMethod constructor : referencedClass.getConstructors()) { @@ -574,7 +582,7 @@ public class ExpectedTypesProvider { } @Override - public void visitPolyadicExpression(PsiPolyadicExpression expr) { + public void visitPolyadicExpression(@NotNull PsiPolyadicExpression expr) { PsiExpression[] operands = expr.getOperands(); final int index = Arrays.asList(operands).indexOf(myExpr); assert index >= 0; @@ -704,7 +712,7 @@ public class ExpectedTypesProvider { return info; } - @Override public void visitPrefixExpression(PsiPrefixExpression expr) { + @Override public void visitPrefixExpression(@NotNull PsiPrefixExpression expr) { IElementType i = expr.getOperationTokenType(); final PsiType type = expr.getType(); final TailType tailType = expr.getParent() instanceof PsiAssignmentExpression && ((PsiAssignmentExpression) expr.getParent()).getRExpression() == expr ? @@ -737,7 +745,7 @@ public class ExpectedTypesProvider { } } - @Override public void visitPostfixExpression(PsiPostfixExpression expr) { + @Override public void visitPostfixExpression(@NotNull PsiPostfixExpression expr) { if (myForCompletion) return; PsiType type = expr.getType(); ExpectedTypeInfoImpl info; @@ -755,7 +763,7 @@ public class ExpectedTypesProvider { myResult = new ExpectedTypeInfo[]{info}; } - @Override public void visitArrayInitializerExpression(PsiArrayInitializerExpression expr) { + @Override public void visitArrayInitializerExpression(@NotNull PsiArrayInitializerExpression expr) { PsiElement pParent = expr.getParent(); PsiType arrayType = null; if (pParent instanceof PsiVariable) { @@ -779,7 +787,7 @@ public class ExpectedTypesProvider { } } - @Override public void visitNewExpression(PsiNewExpression expression) { + @Override public void visitNewExpression(@NotNull PsiNewExpression expression) { PsiExpression[] arrayDimensions = expression.getArrayDimensions(); for (PsiExpression dimension : arrayDimensions) { if (myExpr.equals(dimension)) { @@ -791,7 +799,7 @@ public class ExpectedTypesProvider { } } - @Override public void visitArrayAccessExpression(PsiArrayAccessExpression expr) { + @Override public void visitArrayAccessExpression(@NotNull PsiArrayAccessExpression expr) { if (myExpr.equals(expr.getIndexExpression())) { ExpectedTypeInfoImpl info = createInfoImpl(PsiType.INT, ExpectedTypeInfo.TYPE_OR_SUBTYPE, PsiType.INT, TailType.NONE) ; //todo: special tail type @@ -823,7 +831,7 @@ public class ExpectedTypesProvider { } } - @Override public void visitConditionalExpression(PsiConditionalExpression expr) { + @Override public void visitConditionalExpression(@NotNull PsiConditionalExpression expr) { if (myExpr.equals(expr.getCondition())) { if (myForCompletion) { myExpr = expr; @@ -853,7 +861,7 @@ public class ExpectedTypesProvider { } } - @Override public void visitThrowStatement(PsiThrowStatement statement) { + @Override public void visitThrowStatement(@NotNull PsiThrowStatement statement) { if (statement.getException() == myExpr) { PsiManager manager = statement.getManager(); PsiType throwableType = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName("java.lang.Throwable", myExpr.getResolveScope()); @@ -883,7 +891,7 @@ public class ExpectedTypesProvider { } } - @Override public void visitCodeFragment(JavaCodeFragment codeFragment) { + @Override public void visitCodeFragment(@NotNull JavaCodeFragment codeFragment) { if (codeFragment instanceof PsiExpressionCodeFragment) { final PsiType type = ((PsiExpressionCodeFragment)codeFragment).getExpectedType(); if (type != null) { @@ -892,9 +900,10 @@ public class ExpectedTypesProvider { } } - private ExpectedTypeInfo[] getExpectedArgumentTypesForMethodCall(CandidateInfo[] allCandidates, - PsiExpressionList argumentList, - PsiExpression argument, + @NotNull + private ExpectedTypeInfo[] getExpectedArgumentTypesForMethodCall(@NotNull CandidateInfo[] allCandidates, + @NotNull PsiExpressionList argumentList, + @NotNull PsiExpression argument, boolean forCompletion) { if (allCandidates.length == 0) { return ExpectedTypeInfo.EMPTY_ARRAY; @@ -917,7 +926,8 @@ public class ExpectedTypesProvider { if (index <= args.length - 1) { leftArgs = new PsiExpression[index]; System.arraycopy(args, 0, leftArgs, 0, index); - } else { + } + else { leftArgs = null; } @@ -965,8 +975,8 @@ public class ExpectedTypesProvider { return array.toArray(new ExpectedTypeInfo[array.size()]); } - private static TailType getMethodArgumentTailType(final PsiExpression argument, final int index, final PsiMethod method, final PsiSubstitutor substitutor, - final PsiParameter[] params) { + private static TailType getMethodArgumentTailType(@NotNull final PsiExpression argument, final int index, @NotNull final PsiMethod method, @NotNull final PsiSubstitutor substitutor, + @NotNull final PsiParameter[] params) { if (index >= params.length || index == params.length - 2 && params[index + 1].isVarArgs()) { return TailType.NONE; } @@ -981,13 +991,13 @@ public class ExpectedTypesProvider { return TailType.COMMA; } - private static void inferMethodCallArgumentTypes(final PsiExpression argument, + private static void inferMethodCallArgumentTypes(@NotNull final PsiExpression argument, final boolean forCompletion, - final PsiExpression[] args, + @NotNull final PsiExpression[] args, final int index, - final PsiMethod method, - final PsiSubstitutor substitutor, - final Set array) { + @NotNull final PsiMethod method, + @NotNull final PsiSubstitutor substitutor, + @NotNull final Set array) { PsiParameter[] parameters = method.getParameterList().getParameters(); if (!forCompletion && parameters.length != args.length) return; if (parameters.length <= index && !method.isVarArgs()) return; @@ -1023,7 +1033,7 @@ public class ExpectedTypesProvider { } @Nullable - private static PsiType getTypeParameterValue(PsiClass rootClass, PsiClass derivedClass, PsiSubstitutor substitutor, int index) { + private static PsiType getTypeParameterValue(@NotNull PsiClass rootClass, @NotNull PsiClass derivedClass, PsiSubstitutor substitutor, int index) { final PsiTypeParameter[] typeParameters = rootClass.getTypeParameters(); if (typeParameters.length > index) { final PsiSubstitutor psiSubstitutor = TypeConversionUtil.getClassSubstitutor(rootClass, derivedClass, substitutor); @@ -1036,7 +1046,7 @@ public class ExpectedTypesProvider { } @Nullable - protected static PsiType checkMethod(PsiMethod method, @NonNls final String className, final NullableFunction function) { + protected static PsiType checkMethod(@NotNull PsiMethod method, @NotNull @NonNls final String className, @NotNull final NullableFunction function) { final PsiClass containingClass = method.getContainingClass(); if (containingClass == null) return null; @@ -1046,7 +1056,7 @@ public class ExpectedTypesProvider { final PsiType[] type = {null}; DeepestSuperMethodsSearch.search(method).forEach(new Processor() { @Override - public boolean process(PsiMethod psiMethod) { + public boolean process(@NotNull PsiMethod psiMethod) { final PsiClass rootClass = psiMethod.getContainingClass(); assert rootClass != null; if (className.equals(rootClass.getQualifiedName())) { @@ -1060,15 +1070,16 @@ public class ExpectedTypesProvider { } @Nullable - private static PsiType getDefaultType(final PsiMethod method, final PsiSubstitutor substitutor, final PsiType parameterType, - final PsiExpression argument, PsiExpression[] args, int index) { + private static PsiType getDefaultType(@NotNull final PsiMethod method, final PsiSubstitutor substitutor, @NotNull final PsiType parameterType, + @NotNull final PsiExpression argument, @NotNull PsiExpression[] args, int index) { final PsiClass containingClass = method.getContainingClass(); if (containingClass == null) return parameterType; @NonNls final String name = method.getName(); if ("contains".equals(name) || "remove".equals(name)) { final PsiType type = checkMethod(method, CommonClassNames.JAVA_UTIL_COLLECTION, new NullableFunction() { - public PsiType fun(final PsiClass psiClass) { + @Override + public PsiType fun(@NotNull final PsiClass psiClass) { return getTypeParameterValue(psiClass, containingClass, substitutor, 0); } }); @@ -1076,7 +1087,8 @@ public class ExpectedTypesProvider { } if ("containsKey".equals(name) || "remove".equals(name) || "get".equals(name) || "containsValue".equals(name)) { final PsiType type = checkMethod(method, CommonClassNames.JAVA_UTIL_MAP, new NullableFunction() { - public PsiType fun(final PsiClass psiClass) { + @Override + public PsiType fun(@NotNull final PsiClass psiClass) { return getTypeParameterValue(psiClass, containingClass, substitutor, name.equals("containsValue") ? 1 : 0); } }); @@ -1084,6 +1096,7 @@ public class ExpectedTypesProvider { } if ("equals".equals(name)) { final PsiType type = checkMethod(method, CommonClassNames.JAVA_LANG_OBJECT, new NullableFunction() { + @Override public PsiType fun(final PsiClass psiClass) { final PsiElement parent = argument.getParent().getParent(); if (parent instanceof PsiMethodCallExpression) { @@ -1118,12 +1131,13 @@ public class ExpectedTypesProvider { return parameterType; } - private static PsiType getParameterType(PsiParameter parameter, PsiSubstitutor substitutor) { + private static PsiType getParameterType(@NotNull PsiParameter parameter, @NotNull PsiSubstitutor substitutor) { PsiType type = parameter.getType(); if (parameter.isVarArgs()) { if (type instanceof PsiArrayType) { type = ((PsiArrayType)type).getComponentType(); - } else { + } + else { LOG.error("Vararg parameter with non-array type. Class=" + parameter.getClass() + "; type=" + parameter.getType()); } } @@ -1144,7 +1158,7 @@ public class ExpectedTypesProvider { } @Nullable - private static String getPropertyName(PsiVariable variable) { + private static String getPropertyName(@NotNull PsiVariable variable) { final String name = variable.getName(); if (name == null) return null; JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(variable.getProject()); @@ -1152,6 +1166,7 @@ public class ExpectedTypesProvider { return codeStyleManager.variableNameToPropertyName(name, variableKind); } + @NotNull private ExpectedTypeInfo[] anyArrayType() { PsiType objType = PsiType.getJavaLangObject(myExpr.getManager(), myExpr.getResolveScope()).createArrayType(); ExpectedTypeInfo info = createInfoImpl(objType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, objType, @@ -1164,7 +1179,8 @@ public class ExpectedTypesProvider { return new ExpectedTypeInfo[]{info, info1, info2}; } - private ExpectedTypeInfo[] findClassesWithDeclaredMethod(final PsiMethodCallExpression methodCallExpr, final boolean forCompletion) { + @NotNull + private ExpectedTypeInfo[] findClassesWithDeclaredMethod(@NotNull final PsiMethodCallExpression methodCallExpr, final boolean forCompletion) { final PsiReferenceExpression reference = methodCallExpr.getMethodExpression(); if (reference.getQualifierExpression() instanceof PsiClassObjectAccessExpression) { return ExpectedTypeInfo.EMPTY_ARRAY; @@ -1193,7 +1209,8 @@ public class ExpectedTypesProvider { return types.toArray(new ExpectedTypeInfo[types.size()]); } - private ExpectedTypeInfo[] findClassesWithDeclaredField(PsiReferenceExpression expression) { + @NotNull + private ExpectedTypeInfo[] findClassesWithDeclaredField(@NotNull PsiReferenceExpression expression) { final JavaPsiFacade facade = JavaPsiFacade.getInstance(expression.getProject()); PsiField[] fields = myClassProvider.findDeclaredFields(expression.getManager(), expression.getReferenceName()); List types = new ArrayList(); @@ -1226,7 +1243,7 @@ public class ExpectedTypesProvider { PsiMethod[] findDeclaredMethods(final PsiManager manager, String name); } - public static TailType getFinalCallParameterTailType(PsiElement call, PsiType returnType, PsiMethod method) { + public static TailType getFinalCallParameterTailType(@NotNull PsiElement call, @Nullable PsiType returnType, @NotNull PsiMethod method) { if (method.isConstructor() && call instanceof PsiMethodCallExpression && ((PsiMethodCallExpression)call).getMethodExpression() instanceof PsiSuperExpression) { return TailTypes.CALL_RPARENTH_SEMICOLON; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java index ebd05b22788e..bef51af9bdbb 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java @@ -67,8 +67,6 @@ import org.jetbrains.annotations.Nullable; import java.util.*; -import static com.intellij.codeInsight.daemon.impl.quickfix.CreateClassKind.*; - /** * @author mike */ @@ -190,8 +188,8 @@ public class CreateFromUsageUtils { PsiElement l = PsiTreeUtil.skipSiblingsForward(body.getLBrace(), PsiWhiteSpace.class); PsiElement r = PsiTreeUtil.skipSiblingsBackward(body.getRBrace(), PsiWhiteSpace.class); if (l != null && r != null) { - int start = l.getTextRange().getStartOffset(), - end = r.getTextRange().getEndOffset(); + int start = l.getTextRange().getStartOffset(); + int end = r.getTextRange().getEndOffset(); newEditor.getCaretModel().moveToOffset(Math.max(start, end)); newEditor.getSelectionModel().setSelection(Math.min(start, end), Math.max(start, end)); newEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); @@ -346,9 +344,9 @@ public class CreateFromUsageUtils { PsiManager manager = psiClass.getManager(); PsiElementFactory elementFactory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - PsiClass result = classKind == INTERFACE ? elementFactory.createInterface(name) : - classKind == CLASS ? elementFactory.createClass(name) : - classKind == ANNOTATION ? elementFactory.createAnnotationType(name) : + PsiClass result = classKind == CreateClassKind.INTERFACE ? elementFactory.createInterface(name) : + classKind == CreateClassKind.CLASS ? elementFactory.createClass(name) : + classKind == CreateClassKind.ANNOTATION ? elementFactory.createAnnotationType(name) : elementFactory.createEnum(name); CreateFromUsageBaseFix.setupGenericParameters(result, referenceElement); result = (PsiClass)CodeStyleManager.getInstance(manager.getProject()).reformat(result); @@ -378,16 +376,16 @@ public class CreateFromUsageUtils { PsiClass targetClass; if (directory != null) { try { - if (classKind == INTERFACE) { + if (classKind == CreateClassKind.INTERFACE) { targetClass = JavaDirectoryService.getInstance().createInterface(directory, name); } - else if (classKind == CLASS) { + else if (classKind == CreateClassKind.CLASS) { targetClass = JavaDirectoryService.getInstance().createClass(directory, name); } - else if (classKind == ENUM) { + else if (classKind == CreateClassKind.ENUM) { targetClass = JavaDirectoryService.getInstance().createEnum(directory, name); } - else if (classKind == ANNOTATION) { + else if (classKind == CreateClassKind.ANNOTATION) { targetClass = JavaDirectoryService.getInstance().createAnnotationType(directory, name); } else { @@ -405,16 +403,16 @@ public class CreateFromUsageUtils { } else { //tests PsiClass aClass; - if (classKind == INTERFACE) { + if (classKind == CreateClassKind.INTERFACE) { aClass = factory.createInterface(name); } - else if (classKind == CLASS) { + else if (classKind == CreateClassKind.CLASS) { aClass = factory.createClass(name); } - else if (classKind == ENUM) { + else if (classKind == CreateClassKind.ENUM) { aClass = factory.createEnum(name); } - else if (classKind == ANNOTATION) { + else if (classKind == CreateClassKind.ANNOTATION) { aClass = factory.createAnnotationType(name); } else { @@ -428,7 +426,7 @@ public class CreateFromUsageUtils { final PsiClass superClass = facade.findClass(superClassName, targetClass.getResolveScope()); final PsiJavaCodeReferenceElement superClassReference = factory.createReferenceElementByFQClassName(superClassName, targetClass.getResolveScope()); - final PsiReferenceList list = classKind == INTERFACE || superClass == null || !superClass.isInterface() ? + final PsiReferenceList list = classKind == CreateClassKind.INTERFACE || superClass == null || !superClass.isInterface() ? targetClass.getExtendsList() : targetClass.getImplementsList(); list.add(superClassReference); } @@ -463,10 +461,6 @@ public class CreateFromUsageUtils { final List result = new ArrayList(); JavaRecursiveElementWalkingVisitor visitor = new JavaRecursiveElementWalkingVisitor() { - public List getResult() { - return result; - } - @Override public void visitReferenceExpression(PsiReferenceExpression expr) { if (expression instanceof PsiReferenceExpression) { if (expr.textMatches(expression) && !isValidReference(expr, false)) { @@ -740,6 +734,7 @@ public class CreateFromUsageUtils { Arrays.sort(members, new Comparator() { @Override public int compare(final PsiMember m1, final PsiMember m2) { + ProgressManager.checkCanceled(); int result = JavaStatisticsManager.createInfo(null, m2).getUseCount() - JavaStatisticsManager.createInfo(null, m1).getUseCount(); if (result != 0) return result; final PsiClass aClass = m1.getContainingClass(); @@ -761,13 +756,12 @@ public class CreateFromUsageUtils { List l = new ArrayList(); PsiManager manager = expression.getManager(); JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); - for (int i = 0; i < Math.min(MAX_GUESSED_MEMBERS_COUNT, members.length); i++) { + for (PsiMember member : members) { ProgressManager.checkCanceled(); - PsiMember member = members[i]; PsiClass aClass = member.getContainingClass(); if (aClass instanceof PsiAnonymousClass || aClass == null) continue; - if (facade.getResolveHelper().isAccessible(aClass, expression, null)) { + if (facade.getResolveHelper().isAccessible(member, expression, null)) { PsiClassType type; final PsiElement pparent = expression.getParent().getParent(); if (pparent instanceof PsiMethodCallExpression && member instanceof PsiMethod) { @@ -783,6 +777,7 @@ public class CreateFromUsageUtils { type = factory.createType(aClass); } l.add(ExpectedTypesProvider.createInfo(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.NONE)); + if (l.size() == MAX_GUESSED_MEMBERS_COUNT) break; } } diff --git a/java/java-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java b/java/java-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java index feff94865669..79670fdbbfdf 100644 --- a/java/java-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java +++ b/java/java-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java @@ -142,6 +142,22 @@ public class CompositeShortNamesCache extends PsiShortNamesCache { return result == null ? PsiMethod.EMPTY_ARRAY : result; } + @NotNull + @Override + public PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, int maxCount) { + Merger merger = null; + for (PsiShortNamesCache cache : myCacheArray) { + PsiField[] methods = cache.getFieldsByNameIfNotMoreThan(name, scope, maxCount); + if (methods.length == maxCount) return methods; + if (methods.length != 0) { + if (merger == null) merger = new Merger(); + merger.add(methods); + } + } + PsiField[] result = merger == null ? null : merger.getResult(); + return result == null ? PsiField.EMPTY_ARRAY : result; + } + @Override public boolean processMethodsWithName(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java b/java/java-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java index 82ad5be28079..c6989f730f34 100644 --- a/java/java-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java @@ -158,6 +158,22 @@ class PsiShortNamesCacheImpl extends PsiShortNamesCache { @Override @NotNull + public PsiField[] getFieldsByNameIfNotMoreThan(@NotNull String name, @NotNull final GlobalSearchScope scope, final int maxCount) { + final List methods = new SmartList(); + StubIndex.getInstance().process(JavaStubIndexKeys.FIELDS, name, myManager.getProject(), scope, new CommonProcessors.CollectProcessor(methods){ + @Override + public boolean process(PsiField method) { + return methods.size() != maxCount && super.process(method); + } + }); + if (methods.isEmpty()) return PsiField.EMPTY_ARRAY; + + List list = filterMembers(methods, scope); + return list.toArray(new PsiField[list.size()]); + } + + @NotNull + @Override public PsiField[] getFieldsByName(@NotNull String name, @NotNull final GlobalSearchScope scope) { final Collection fields = JavaFieldNameIndex.getInstance().get(name, myManager.getProject(), scope); @@ -190,7 +206,8 @@ class PsiShortNamesCacheImpl extends PsiShortNamesCache { String name = clazz.getName(); if (name != null) { code += name.hashCode(); - } else { + } + else { //anonymous classes are not equivalent code += clazz.hashCode(); } diff --git a/java/openapi/src/com/intellij/psi/search/PsiShortNamesCache.java b/java/openapi/src/com/intellij/psi/search/PsiShortNamesCache.java index 9deb3240ef38..b85bd97bd318 100644 --- a/java/openapi/src/com/intellij/psi/search/PsiShortNamesCache.java +++ b/java/openapi/src/com/intellij/psi/search/PsiShortNamesCache.java @@ -104,6 +104,8 @@ public abstract class PsiShortNamesCache { @NotNull public abstract PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, int maxCount); + @NotNull + public abstract PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, int maxCount); public abstract boolean processMethodsWithName(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, @NotNull Processor processor); diff --git a/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java index 83b33c411b18..835a3b0409af 100644 --- a/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java +++ b/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java @@ -55,42 +55,6 @@ public class DelegatingGlobalSearchScope extends GlobalSearchScope { return myBaseScope.isSearchOutsideRootModel(); } - @Override - @NotNull - public GlobalSearchScope intersectWith(@NotNull GlobalSearchScope scope) { - return super.intersectWith(scope); - } - - @Override - @NotNull - public SearchScope intersectWith(@NotNull SearchScope scope2) { - return super.intersectWith(scope2); - } - - @NotNull - @Override - public SearchScope intersectWith(@NotNull LocalSearchScope localScope2) { - return super.intersectWith(localScope2); - } - - @Override - @NotNull - public GlobalSearchScope union(@NotNull SearchScope scope) { - return super.union(scope); - } - - @Override - @NotNull - public GlobalSearchScope union(@NotNull LocalSearchScope scope) { - return super.union(scope); - } - - @NotNull - @Override - public GlobalSearchScope uniteWith(@NotNull GlobalSearchScope scope) { - return super.uniteWith(scope); - } - @Override public String getDisplayName() { return myBaseScope.getDisplayName(); diff --git a/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java index 6b0a63b0dc6e..000e8a8246de 100644 --- a/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java +++ b/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java @@ -27,6 +27,7 @@ import com.intellij.psi.PsiBundle; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -147,6 +148,11 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw public boolean isSearchInLibraries() { return GlobalSearchScope.this.isSearchInLibraries(); } + + @Override + public String toString() { + return "UnionToLocal: (" + GlobalSearchScope.this.toString() + ", " + scope + ")"; + } }; } @@ -341,7 +347,13 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw public int hashCode() { return 31 * myScope1.hashCode() + myScope2.hashCode(); } + + @Override + public String toString() { + return "Intersection: (" + myScope1 + ", " + myScope2 + ")"; + } } + private static class UnionScope extends GlobalSearchScope { private final GlobalSearchScope myScope1; private final GlobalSearchScope myScope2; @@ -419,6 +431,12 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw public int hashCode() { return 31 * myScope1.hashCode() + myScope2.hashCode(); } + + @NonNls + @Override + public String toString() { + return "Union: (" + myScope1 + ", " + myScope2 + ")"; + } } @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/stubs/GroovyShortNamesCache.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/stubs/GroovyShortNamesCache.java index 29485e32f0ff..87e84bbdc8cf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/stubs/GroovyShortNamesCache.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/stubs/GroovyShortNamesCache.java @@ -152,6 +152,12 @@ public class GroovyShortNamesCache extends PsiShortNamesCache { return getMethodsByName(name, scope); } + @NotNull + @Override + public PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, int maxCount) { + return getFieldsByName(name, scope); + } + @Override @NotNull public String[] getAllMethodNames() {