mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-116628 No nulls in type parameters
This commit is contained in:
+61
-1
@@ -16,6 +16,7 @@
|
||||
package org.jetbrains.plugins.groovy.codeInspection.noReturnMethod;
|
||||
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
@@ -29,16 +30,26 @@ import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.MaybeReturnInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ThrowingInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
@@ -67,7 +78,7 @@ public class MissingReturnInspection extends GroovySuppressableInspectionTool {
|
||||
|
||||
public static ReturnStatus getReturnStatus(PsiElement subject) {
|
||||
if (subject instanceof GrClosableBlock) {
|
||||
final PsiType inferredReturnType = GroovyExpectedTypesProvider.getExpectedClosureReturnType((GrClosableBlock)subject);
|
||||
final PsiType inferredReturnType = getExpectedClosureReturnType((GrClosableBlock)subject);
|
||||
if (inferredReturnType instanceof PsiClassType) {
|
||||
PsiClass resolved = ((PsiClassType)inferredReturnType).resolve();
|
||||
if (resolved != null && !(resolved instanceof PsiTypeParameter)) return mustReturnValue;
|
||||
@@ -83,6 +94,55 @@ public class MissingReturnInspection extends GroovySuppressableInspectionTool {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiType getExpectedClosureReturnType(GrClosableBlock closure) {
|
||||
List<PsiType> expectedReturnTypes = new ArrayList<PsiType>();
|
||||
|
||||
PsiElement parent = closure.getParent();
|
||||
if (parent instanceof GrArgumentList && parent.getParent() instanceof GrMethodCall || parent instanceof GrMethodCall) {
|
||||
GrMethodCall call = (GrMethodCall)(parent instanceof GrArgumentList ? parent.getParent() : parent);
|
||||
|
||||
GroovyResolveResult[] variants = call.getCallVariants(null);
|
||||
|
||||
for (GroovyResolveResult variant : variants) {
|
||||
Map<GrExpression,Pair<PsiParameter,PsiType>> map =
|
||||
GrClosureSignatureUtil.mapArgumentsToParameters(variant, closure, true, true, call.getNamedArguments(), call.getExpressionArguments(), call.getClosureArguments());
|
||||
|
||||
if (map != null) {
|
||||
Pair<PsiParameter, PsiType> pair = map.get(closure);
|
||||
if (pair == null) continue;
|
||||
|
||||
PsiParameter parameter = pair.getFirst();
|
||||
|
||||
PsiType type = parameter.getType();
|
||||
if (TypesUtil.isPsiClassTypeToClosure(type)) {
|
||||
PsiType[] parameters = ((PsiClassType)type).getParameters();
|
||||
if (parameters.length == 1) {
|
||||
expectedReturnTypes.add(parameters[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Set<PsiType> expectedTypes = GroovyExpectedTypesProvider.getDefaultExpectedTypes(closure);
|
||||
|
||||
for (PsiType expectedType : expectedTypes) {
|
||||
if (TypesUtil.isPsiClassTypeToClosure(expectedType)) {
|
||||
PsiType[] parameters = ((PsiClassType)expectedType).getParameters();
|
||||
if (parameters.length == 1) {
|
||||
expectedReturnTypes.add(parameters[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiType type : expectedReturnTypes) {
|
||||
if (PsiType.VOID.equals(type)) return PsiType.VOID;
|
||||
}
|
||||
return TypesUtil.getLeastUpperBoundNullable(expectedReturnTypes, closure.getManager());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder problemsHolder, boolean onTheFly) {
|
||||
return new GroovyPsiElementVisitor(new GroovyElementVisitor() {
|
||||
|
||||
@@ -73,10 +73,13 @@ public class GppTypeConverter extends GrTypeConverter {
|
||||
|
||||
final PsiType expectedComponent = PsiUtil.extractIterableTypeParameter(lType, false);
|
||||
if (expectedComponent != null && isMethodCallConversion(context)) {
|
||||
PsiType tupleComponent = tupleType.getParameters()[0];
|
||||
if (tupleComponent != null &&
|
||||
TypesUtil.isAssignable(expectedComponent, tupleComponent, context) && hasDefaultConstructor(lType)) {
|
||||
return true;
|
||||
PsiType[] parameters = tupleType.getParameters();
|
||||
if (parameters.length == 1) {
|
||||
PsiType tupleComponent = parameters[0];
|
||||
if (tupleComponent != null &&
|
||||
TypesUtil.isAssignable(expectedComponent, tupleComponent, context) && hasDefaultConstructor(lType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,10 +91,10 @@ public class GppTypeConverter extends GrTypeConverter {
|
||||
final PsiType lKeyType = PsiUtil.substituteTypeParameter(lType, CommonClassNames.JAVA_UTIL_MAP, 0, false);
|
||||
final PsiType lValueType = PsiUtil.substituteTypeParameter(lType, CommonClassNames.JAVA_UTIL_MAP, 1, false);
|
||||
final PsiType[] parameters = ((GrMapType)rType).getParameters();
|
||||
if (lKeyType != null && lValueType != null &&
|
||||
if (parameters.length == 2 && lKeyType != null && lValueType != null &&
|
||||
parameters[0] != null && parameters[1] != null &&
|
||||
(!TypesUtil.isAssignable(lKeyType, parameters[0], context) || !TypesUtil
|
||||
.isAssignable(lValueType, parameters[1], context))) {
|
||||
(!TypesUtil.isAssignable(lKeyType, parameters[0], context) ||
|
||||
!TypesUtil.isAssignable(lValueType, parameters[1], context))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+1
-27
@@ -105,32 +105,6 @@ public class GroovyExpectedTypesProvider {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiType getExpectedClosureReturnType(GrClosableBlock closure) {
|
||||
final Set<PsiType> expectedTypes = getDefaultExpectedTypes(closure);
|
||||
|
||||
List<PsiType> expectedReturnTypes = new ArrayList<PsiType>();
|
||||
for (PsiType expectedType : expectedTypes) {
|
||||
if (!(expectedType instanceof PsiClassType)) return null;
|
||||
|
||||
final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)expectedType).resolveGenerics();
|
||||
final PsiClass resolved = resolveResult.getElement();
|
||||
if (resolved == null || !(GroovyCommonClassNames.GROOVY_LANG_CLOSURE.equals(resolved.getQualifiedName()))) return null;
|
||||
|
||||
final PsiTypeParameter[] typeParameters = resolved.getTypeParameters();
|
||||
if (typeParameters.length != 1) return null;
|
||||
|
||||
final PsiTypeParameter expected = typeParameters[0];
|
||||
final PsiType expectedReturnType = resolveResult.getSubstitutor().substitute(expected);
|
||||
if (expectedReturnType == PsiType.VOID || expectedReturnType == null) return null;
|
||||
|
||||
expectedReturnTypes.add(expectedReturnType);
|
||||
}
|
||||
|
||||
return TypesUtil.getLeastUpperBoundNullable(expectedReturnTypes, closure.getManager());
|
||||
}
|
||||
|
||||
|
||||
private static class MyCalculator extends GroovyElementVisitor {
|
||||
private TypeConstraint[] myResult;
|
||||
private final GrExpression myExpression;
|
||||
@@ -214,7 +188,7 @@ public class GroovyExpectedTypesProvider {
|
||||
final GrExpression[] expressionArgs = argumentList == null ? GrExpression.EMPTY_ARRAY : argumentList.getExpressionArguments();
|
||||
try {
|
||||
final Map<GrExpression, Pair<PsiParameter, PsiType>> map =
|
||||
GrClosureSignatureUtil.mapArgumentsToParameters(variant, methodCall, true, true, namedArgs, expressionArgs, closureArgs);
|
||||
GrClosureSignatureUtil.mapArgumentsToParameters(variant, methodCall, true, false, namedArgs, expressionArgs, closureArgs);
|
||||
addConstraintsFromMap(constraints, map);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
|
||||
@@ -39,7 +39,7 @@ import java.util.List;
|
||||
* @author ven
|
||||
*/
|
||||
public class GrClosureType extends GrLiteralClassType {
|
||||
private final @NotNull GrSignature mySignature;
|
||||
private final GrSignature mySignature;
|
||||
private PsiType[] myTypeArgs = null;
|
||||
|
||||
private GrClosureType(@NotNull LanguageLevel languageLevel,
|
||||
@@ -52,21 +52,22 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
if (!shouldInferTypeParameters) myTypeArgs = PsiType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
private GrClosureType(@NotNull LanguageLevel level,
|
||||
@NotNull GlobalSearchScope scope,
|
||||
@NotNull JavaPsiFacade facade,
|
||||
@NotNull GrSignature signature,
|
||||
@NotNull PsiType[] typeArgs) {
|
||||
super(level, scope, facade);
|
||||
|
||||
mySignature = signature;
|
||||
myTypeArgs = typeArgs;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getClassName() {
|
||||
return "Closure";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getParameterCount() {
|
||||
if (myTypeArgs != null) {
|
||||
return myTypeArgs.length;
|
||||
}
|
||||
|
||||
final PsiClass psiClass = resolve();
|
||||
return psiClass != null && psiClass.getTypeParameters().length == 1 ? 1 : 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiType[] getParameters() {
|
||||
if (myTypeArgs == null) {
|
||||
@@ -79,7 +80,7 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
final PsiClass psiClass = resolve();
|
||||
if (psiClass != null && psiClass.getTypeParameters().length == 1) {
|
||||
final PsiType type = GrClosureSignatureUtil.getReturnType(mySignature);
|
||||
if (type == PsiType.NULL) {
|
||||
if (type == PsiType.NULL || type == null) {
|
||||
return new PsiType[]{null};
|
||||
}
|
||||
else {
|
||||
@@ -129,9 +130,7 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
|
||||
@NotNull
|
||||
public PsiClassType setLanguageLevel(@NotNull final LanguageLevel languageLevel) {
|
||||
final GrClosureType result = create(mySignature, myScope, myFacade, languageLevel, true);
|
||||
result.myTypeArgs = this.myTypeArgs;
|
||||
return result;
|
||||
return new GrClosureType(languageLevel, myScope, myFacade, mySignature, myTypeArgs);
|
||||
}
|
||||
|
||||
public static GrClosureType create(GroovyResolveResult[] results, GroovyPsiElement context) {
|
||||
@@ -187,9 +186,7 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
public PsiType curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context) {
|
||||
final GrSignature newSignature = mySignature.curry(args, position, context);
|
||||
if (newSignature == null) return null;
|
||||
final GrClosureType result = create(newSignature, myScope, myFacade, myLanguageLevel, true);
|
||||
result.myTypeArgs = this.myTypeArgs;
|
||||
return result;
|
||||
return new GrClosureType(myLanguageLevel, myScope, myFacade, newSignature, myTypeArgs);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+19
-15
@@ -46,20 +46,7 @@ public abstract class GrLiteralClassType extends PsiClassType {
|
||||
@NotNull
|
||||
public ClassResolveResult resolveGenerics() {
|
||||
final PsiClass myBaseClass = resolve();
|
||||
final PsiSubstitutor substitutor;
|
||||
if (myBaseClass != null) {
|
||||
final PsiType[] typeArgs = getParameters();
|
||||
final PsiTypeParameter[] typeParams = myBaseClass.getTypeParameters();
|
||||
if (typeParams.length == typeArgs.length) {
|
||||
substitutor = PsiSubstitutor.EMPTY.putAll(myBaseClass, typeArgs);
|
||||
}
|
||||
else {
|
||||
substitutor = PsiSubstitutor.EMPTY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
substitutor = PsiSubstitutor.EMPTY;
|
||||
}
|
||||
final PsiSubstitutor substitutor = inferSubstitutor(myBaseClass);
|
||||
|
||||
return new ClassResolveResult() {
|
||||
|
||||
@@ -94,6 +81,23 @@ public abstract class GrLiteralClassType extends PsiClassType {
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiSubstitutor inferSubstitutor(@Nullable PsiClass myBaseClass) {
|
||||
if (myBaseClass != null) {
|
||||
final PsiType[] typeArgs = getParameters();
|
||||
final PsiTypeParameter[] typeParams = myBaseClass.getTypeParameters();
|
||||
if (typeParams.length == typeArgs.length) {
|
||||
return PsiSubstitutor.EMPTY.putAll(myBaseClass, typeArgs);
|
||||
}
|
||||
else {
|
||||
return PsiSubstitutor.EMPTY.putAll(myBaseClass, new PsiType[typeParams.length]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return PsiSubstitutor.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public abstract String getClassName() ;
|
||||
@@ -161,7 +165,7 @@ public abstract class GrLiteralClassType extends PsiClassType {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected PsiType getLeastUpperBound(PsiType[] psiTypes) {
|
||||
protected PsiType getLeastUpperBound(PsiType... psiTypes) {
|
||||
PsiType result = null;
|
||||
final PsiManager manager = getPsiManager();
|
||||
for (final PsiType other : psiTypes) {
|
||||
|
||||
@@ -37,8 +37,6 @@ import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.
|
||||
* @author peter
|
||||
*/
|
||||
public class GrMapType extends GrLiteralClassType {
|
||||
private static final PsiType[] RAW_PARAMETERS = new PsiType[]{null, null};
|
||||
|
||||
private final Map<String, PsiType> myStringEntries;
|
||||
private final List<Pair<PsiType, PsiType>> myOtherEntries;
|
||||
private final String myJavaClassName;
|
||||
@@ -83,12 +81,6 @@ public class GrMapType extends GrLiteralClassType {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassType rawType() {
|
||||
return new GrMapType(myFacade, getResolveScope(), Collections.<String, PsiType>emptyMap(), Collections.<Pair<PsiType,PsiType>>emptyList(), getLanguageLevel());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getJavaClassName() {
|
||||
@@ -136,7 +128,7 @@ public class GrMapType extends GrLiteralClassType {
|
||||
final PsiType[] keyTypes = getAllKeyTypes();
|
||||
final PsiType[] valueTypes = getAllValueTypes();
|
||||
if (keyTypes.length == 0 && valueTypes.length == 0) {
|
||||
return RAW_PARAMETERS;
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
return new PsiType[]{getLeastUpperBound(keyTypes), getLeastUpperBound(valueTypes)};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -38,6 +39,8 @@ public class GrRangeType extends GrLiteralClassType {
|
||||
private final PsiType myIterationType;
|
||||
private final String myQualifiedName;
|
||||
|
||||
private final PsiType[] myParameters;
|
||||
|
||||
public GrRangeType(LanguageLevel languageLevel,
|
||||
GlobalSearchScope scope,
|
||||
JavaPsiFacade facade,
|
||||
@@ -53,6 +56,8 @@ public class GrRangeType extends GrLiteralClassType {
|
||||
else {
|
||||
myQualifiedName = GroovyCommonClassNames.GROOVY_LANG_OBJECT_RANGE;
|
||||
}
|
||||
|
||||
myParameters = inferParameters();
|
||||
}
|
||||
|
||||
public GrRangeType(GlobalSearchScope scope, JavaPsiFacade facade, @Nullable PsiType left, @Nullable PsiType right) {
|
||||
@@ -74,7 +79,16 @@ public class GrRangeType extends GrLiteralClassType {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiType[] getParameters() {
|
||||
return PsiType.EMPTY_ARRAY;
|
||||
return myParameters;
|
||||
}
|
||||
|
||||
private PsiType[] inferParameters() {
|
||||
if (myIterationType == null) return EMPTY_ARRAY;
|
||||
|
||||
PsiClass resolved = resolve();
|
||||
if (resolved == null || resolved.getTypeParameters().length == 0) return EMPTY_ARRAY;
|
||||
|
||||
return new PsiType[]{myIterationType};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrSpreadType extends GrLiteralClassType {
|
||||
|
||||
private PsiType myType;
|
||||
|
||||
public GrSpreadType(PsiType original, PsiType containerType, GlobalSearchScope scope) {
|
||||
this(original, containerType, LanguageLevel.JDK_1_5, scope, JavaPsiFacade.getInstance(scope.getProject()));
|
||||
}
|
||||
|
||||
public GrSpreadType(PsiType original, PsiType containerType, LanguageLevel languageLevel, GlobalSearchScope scope, JavaPsiFacade facade) {
|
||||
super(languageLevel, scope, facade);
|
||||
|
||||
final Project project = facade.getProject();
|
||||
myType = TypesUtil.createSimilarCollection(containerType, project, original);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getJavaClassName() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiType[] getParameters() {
|
||||
return new PsiType[0]; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassType setLanguageLevel(@NotNull LanguageLevel languageLevel) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInternalCanonicalText() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return false; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,8 +31,8 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
|
||||
* @author ven
|
||||
*/
|
||||
public class GrTupleType extends GrLiteralClassType {
|
||||
private static final PsiType[] RAW_PARAMETERS = new PsiType[]{null};
|
||||
private final PsiType[] myComponentTypes;
|
||||
private final PsiType[] myParameters;
|
||||
|
||||
public GrTupleType(PsiType[] componentTypes, JavaPsiFacade facade, GlobalSearchScope scope) {
|
||||
this(componentTypes, facade, scope,LanguageLevel.JDK_1_5);
|
||||
@@ -40,6 +40,8 @@ public class GrTupleType extends GrLiteralClassType {
|
||||
public GrTupleType(PsiType[] componentTypes, JavaPsiFacade facade, GlobalSearchScope scope,LanguageLevel languageLevel) {
|
||||
super(languageLevel, scope, facade);
|
||||
myComponentTypes = componentTypes;
|
||||
|
||||
myParameters = inferParameters();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -48,12 +50,6 @@ public class GrTupleType extends GrLiteralClassType {
|
||||
return CommonClassNames.JAVA_UTIL_ARRAY_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassType rawType() {
|
||||
return new GrTupleType(RAW_PARAMETERS, myFacade, getResolveScope(), getLanguageLevel());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getClassName() {
|
||||
return StringUtil.getShortName(getJavaClassName());
|
||||
@@ -61,9 +57,13 @@ public class GrTupleType extends GrLiteralClassType {
|
||||
|
||||
@NotNull
|
||||
public PsiType[] getParameters() {
|
||||
if (myComponentTypes.length == 0) return RAW_PARAMETERS;
|
||||
return myParameters;
|
||||
}
|
||||
|
||||
private PsiType[] inferParameters() {
|
||||
if (myComponentTypes.length == 0) return PsiType.EMPTY_ARRAY;
|
||||
final PsiType leastUpperBound = getLeastUpperBound(myComponentTypes);
|
||||
if (leastUpperBound == PsiType.NULL) return RAW_PARAMETERS;
|
||||
if (leastUpperBound == PsiType.NULL) return EMPTY_ARRAY;
|
||||
return new PsiType[]{leastUpperBound};
|
||||
}
|
||||
|
||||
|
||||
+9
@@ -913,4 +913,13 @@ public class TypesUtil {
|
||||
if (!changed) return null;
|
||||
return JavaPsiFacade.getElementFactory(project).createType(element, parameters);
|
||||
}
|
||||
|
||||
public static boolean isPsiClassTypeToClosure(PsiType type) {
|
||||
if (!(type instanceof PsiClassType)) return false;
|
||||
|
||||
final PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
if (psiClass == null) return false;
|
||||
|
||||
return GROOVY_LANG_CLOSURE.equals(psiClass.getQualifiedName());
|
||||
}
|
||||
}
|
||||
|
||||
+2
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -109,7 +109,7 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal
|
||||
if (type instanceof GrClosureType) {
|
||||
returnType = GrClosureSignatureUtil.getReturnType(((GrClosureType)type).getSignature(), callExpression);
|
||||
}
|
||||
else if (isPsiClassTypeToClosure(type)) {
|
||||
else if (TypesUtil.isPsiClassTypeToClosure(type)) {
|
||||
assert type instanceof PsiClassType;
|
||||
final PsiType[] parameters = ((PsiClassType)type).getParameters();
|
||||
if (parameters.length == 1) {
|
||||
@@ -131,15 +131,6 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal
|
||||
}
|
||||
|
||||
|
||||
private static boolean isPsiClassTypeToClosure(PsiType type) {
|
||||
if (!(type instanceof PsiClassType)) return false;
|
||||
|
||||
final PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
if (psiClass == null) return false;
|
||||
|
||||
return GroovyCommonClassNames.GROOVY_LANG_CLOSURE.equals(psiClass.getQualifiedName());
|
||||
}
|
||||
|
||||
private static final Set<String> CLOSURE_METHODS = new HashSet<String>();
|
||||
static {
|
||||
CLOSURE_METHODS.add("call");
|
||||
|
||||
@@ -405,41 +405,6 @@ class Point {
|
||||
assertEquals 1, multiResolveReference().size()
|
||||
}
|
||||
|
||||
public void testGotoSuperConstructorFromLiteralOnsets() throws Exception {
|
||||
PsiClass point = myFixture.addClass("""
|
||||
class Point {
|
||||
Point() {}
|
||||
Point(int y) {}
|
||||
}""")
|
||||
|
||||
configureGppScript "Point p = <caret>[super: 2]"
|
||||
assertEquals point.constructors[1], resolveReference()
|
||||
|
||||
configureGppScript "Point p = <caret>[2]"
|
||||
assertEquals point.constructors[1], resolveReference()
|
||||
|
||||
configureGppScript "Point p = <caret>[]"
|
||||
assertEquals point.constructors[0], resolveReference()
|
||||
|
||||
configureGppScript "Point p = <caret>[:]"
|
||||
assertEquals point.constructors[0], resolveReference()
|
||||
|
||||
configureGppScript "Point p = <caret>[239, 42]"
|
||||
assertEquals 2, multiResolveReference().size()
|
||||
|
||||
configureGppScript """
|
||||
def foo(Point p) {}
|
||||
foo(<caret>[2, 3])
|
||||
"""
|
||||
assertEquals 2, multiResolveReference().size()
|
||||
|
||||
configureGppScript """
|
||||
def foo(Point... p) {}
|
||||
foo(<caret>['super':[2, 3]])
|
||||
"""
|
||||
assertEquals 2, multiResolveReference().size()
|
||||
}
|
||||
|
||||
public void testGotoClassFromLiteralOnsetsWhenNoConstructorsPresent() throws Exception {
|
||||
PsiClass point = myFixture.addClass(""" class Point { }""")
|
||||
configureGppScript "Point p = <caret>[super: 2]"
|
||||
|
||||
+1
-93
@@ -42,7 +42,7 @@ class LiteralConstructorUsagesTest extends LightGroovyTestCase {
|
||||
myFixture.addFileToProject "a.gpp", "Foo x = []"
|
||||
assertOneElement(ReferencesSearch.search(foo.constructors[0]).findAll())
|
||||
}
|
||||
|
||||
|
||||
public void testList_ReturnValue() throws Exception {
|
||||
def foo = myFixture.addClass("""class Foo {
|
||||
Foo() {}
|
||||
@@ -97,98 +97,6 @@ Foo untyped() { [] }
|
||||
assertEquals(2, ReferencesSearch.search(foo.constructors[0]).findAll().size())
|
||||
}
|
||||
|
||||
public void testList_GppMethodCall() throws Exception {
|
||||
//------------------------declarations
|
||||
def foo = myFixture.addClass("""
|
||||
package z;
|
||||
class Foo {
|
||||
public Foo() {}
|
||||
}
|
||||
""")
|
||||
|
||||
myFixture.addClass("""
|
||||
package z;
|
||||
public class Bar {
|
||||
public static void giveMeFoo(int a, Foo f) {}
|
||||
}
|
||||
""")
|
||||
myFixture.addFileToProject("Decl.groovy", "static def giveMeFooAsWell(z.Foo f) {}")
|
||||
|
||||
//----------------------usages
|
||||
myFixture.addFileToProject "a.gpp", "z.Bar.giveMeFoo(2, []) //usage"
|
||||
myFixture.addFileToProject "b.groovy", """
|
||||
@Typed package aa;
|
||||
z.Bar.giveMeFoo(3, []) //usage
|
||||
"""
|
||||
myFixture.addFileToProject "c.groovy", """
|
||||
@Typed def someMethod() {
|
||||
z.Bar.giveMeFoo 4, [] //usage
|
||||
Decl.giveMeFooAsWell([]) //usage
|
||||
}
|
||||
z.Bar.giveMeFoo 5, [] //non-typed context
|
||||
Decl.giveMeFooAsWell([])
|
||||
"""
|
||||
myFixture.addFileToProject "invalid.gpp", "z.Bar.giveMeFoo 42, 239, []"
|
||||
myFixture.addFileToProject "nonGpp.groovy", "z.Bar.giveMeFoo(6, [])"
|
||||
assertEquals(4, ReferencesSearch.search(foo.constructors[0]).findAll().size())
|
||||
}
|
||||
|
||||
public void testList_GppConstructorCallWithSeveralParameters() throws Exception {
|
||||
def foo = myFixture.addClass("""
|
||||
class Foo {
|
||||
Foo() {}
|
||||
}
|
||||
""")
|
||||
|
||||
myFixture.addClass("""
|
||||
class Bar {
|
||||
Bar(Foo f1, Foo f2, Foo f3) {}
|
||||
}
|
||||
""")
|
||||
myFixture.addFileToProject "a.gpp", "new Bar([],[],[])"
|
||||
assertEquals(3, ReferencesSearch.search(foo.constructors[0]).findAll().size())
|
||||
}
|
||||
|
||||
public void testMap_GppOverloads() throws Exception {
|
||||
def foo = myFixture.addClass("""
|
||||
class Foo {
|
||||
Foo() {}
|
||||
Foo(int a) {}
|
||||
}
|
||||
""")
|
||||
|
||||
myFixture.addClass("""
|
||||
class Bar {
|
||||
static void foo(Foo f1, Foo f2) {}
|
||||
}
|
||||
""")
|
||||
myFixture.addFileToProject "a.gpp", "Bar.foo([:], [super:2])"
|
||||
assertEquals(1, ReferencesSearch.search(foo.constructors[0]).findAll().size())
|
||||
assertEquals(1, ReferencesSearch.search(foo.constructors[1]).findAll().size())
|
||||
}
|
||||
|
||||
public void testGppCallVarargs() throws Exception {
|
||||
def foo = myFixture.addClass("""
|
||||
class Foo {
|
||||
Foo() {}
|
||||
Foo(int a) {}
|
||||
}
|
||||
""")
|
||||
|
||||
myFixture.addClass("""
|
||||
class Bar {
|
||||
static void foo(Foo f1, Foo f2) {}
|
||||
static void doo(int a, Foo f1, Foo f2) {}
|
||||
}
|
||||
""")
|
||||
myFixture.addFileToProject "a.gpp", """
|
||||
Bar.foo([:], [super:2])
|
||||
Bar.doo 3, [:], [super:2]
|
||||
"""
|
||||
assertEquals(2, ReferencesSearch.search(foo.constructors[0]).findAll().size())
|
||||
assertEquals(2, ReferencesSearch.search(foo.constructors[1]).findAll().size())
|
||||
}
|
||||
|
||||
public void testOverloadedConstructorUsages() throws Exception {
|
||||
def foo = myFixture.addClass("""
|
||||
class Foo {
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
java.util.ArrayList<java.lang.Object> list = new java.util.ArrayList<java.lang.Object>();
|
||||
java.util.ArrayList list = new java.util.ArrayList();
|
||||
java.lang.Integer[] arr = new java.lang.Integer[0];
|
||||
java.util.List<java.lang.String> strings = new java.util.ArrayList<java.lang.String>();
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
java.util.Map<java.lang.Object, java.lang.Object> map = new java.util.Map<java.lang.Object, java.lang.Object>();
|
||||
java.util.Map map = new java.util.Map();
|
||||
print(map.get(1));
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ java.lang.String s = "a";
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.invokeMethod(s, "bar", new java.lang.Object[]{4});
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, org.codehaus.groovy.runtime.DefaultGroovyMethods.invokeMethod(s, "bar", new java.lang.Object[]{5}));
|
||||
|
||||
return org.codehaus.groovy.runtime.DefaultGroovyMethods.invokeMethod(s, "anme", new java.util.ArrayList<java.lang.Object>());
|
||||
return org.codehaus.groovy.runtime.DefaultGroovyMethods.invokeMethod(s, "anme", new java.util.ArrayList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -2,7 +2,7 @@ public class MyClass {
|
||||
public void foo(java.util.Map args, java.lang.String a, java.lang.String... b) {}
|
||||
|
||||
public void foo(java.lang.String a, java.lang.String... b) {
|
||||
foo(new java.util.LinkedHashMap<java.lang.Object, java.lang.Object>(), a, b);
|
||||
foo(new java.util.LinkedHashMap(), a, b);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user