better create local from usage: more sane variants

This commit is contained in:
Alexey Kudravtsev
2012-04-10 12:06:25 +04:00
parent efb3edebb2
commit 0925c6dfcb
8 changed files with 163 additions and 128 deletions
@@ -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<PsiType> visitor, Project project) {
public static PsiType[] processExpectedTypes(@NotNull ExpectedTypeInfo[] infos,
@NotNull PsiTypeVisitor<PsiType> visitor, @NotNull Project project) {
Set<PsiType> set = new LinkedHashSet<PsiType>();
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<PsiType> visitor, Set<PsiType> typeSet) {
private static void processType(@NotNull PsiType type, @NotNull PsiTypeVisitor<PsiType> visitor, @NotNull Set<PsiType> typeSet) {
PsiType accepted = type.accept(visitor);
if (accepted != null) typeSet.add(accepted);
}
public static void processPrimitiveTypeAndSubtypes(PsiPrimitiveType type, PsiTypeVisitor<PsiType> visitor, Set<PsiType> set) {
public static void processPrimitiveTypeAndSubtypes(@NotNull PsiPrimitiveType type, @NotNull PsiTypeVisitor<PsiType> visitor, @NotNull Set<PsiType> 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<PsiType> visitor, Project project, Set<PsiType> set) {
public static void processAllSuperTypes(@NotNull PsiType type, int dimCount, @NotNull PsiTypeVisitor<PsiType> visitor, @NotNull Project project, @NotNull Set<PsiType> 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<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
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<CandidateInfo> array = new ArrayList<CandidateInfo>();
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<ExpectedTypeInfo> array) {
@NotNull final PsiMethod method,
@NotNull final PsiSubstitutor substitutor,
@NotNull final Set<ExpectedTypeInfo> 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<PsiClass,PsiType> function) {
protected static PsiType checkMethod(@NotNull PsiMethod method, @NotNull @NonNls final String className, @NotNull final NullableFunction<PsiClass,PsiType> 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<PsiMethod>() {
@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<PsiClass, PsiType>() {
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<PsiClass, PsiType>() {
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<PsiClass, PsiType>() {
@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<ExpectedTypeInfo> types = new ArrayList<ExpectedTypeInfo>();
@@ -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;
@@ -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<PsiReferenceExpression> result = new ArrayList<PsiReferenceExpression>();
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<PsiMember>() {
@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<ExpectedTypeInfo> l = new ArrayList<ExpectedTypeInfo>();
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;
}
}
@@ -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<PsiField> 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<PsiField>();
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,
@@ -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<PsiField> methods = new SmartList<PsiField>();
StubIndex.getInstance().process(JavaStubIndexKeys.FIELDS, name, myManager.getProject(), scope, new CommonProcessors.CollectProcessor<PsiField>(methods){
@Override
public boolean process(PsiField method) {
return methods.size() != maxCount && super.process(method);
}
});
if (methods.isEmpty()) return PsiField.EMPTY_ARRAY;
List<PsiField> 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<PsiField> 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();
}