Fixed NPE in ArgumentMatchImpl.getStatus

Check value arguments if there is wrong number of type arguments
This commit is contained in:
Svetlana Isakova
2014-08-14 11:41:30 +04:00
parent 05637226e1
commit bbeb44e6ee
6 changed files with 60 additions and 27 deletions
@@ -53,15 +53,18 @@ public class FunctionDescriptorUtil {
private FunctionDescriptorUtil() {
}
public static Map<TypeConstructor, TypeProjection> createSubstitutionContext(@NotNull FunctionDescriptor functionDescriptor, List<JetType> typeArguments) {
public static Map<TypeConstructor, TypeProjection> createSubstitutionContext(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull List<JetType> typeArguments
) {
if (functionDescriptor.getTypeParameters().isEmpty()) return Collections.emptyMap();
Map<TypeConstructor, TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>();
int typeArgumentsSize = typeArguments.size();
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
assert typeArgumentsSize == typeParameters.size();
for (int i = 0; i < typeArgumentsSize; i++) {
assert typeArguments.size() >= typeParameters.size() :
"Insufficient number of type arguments.\nType arguments: " + typeArguments + "\nType parameters: " + typeParameters;
for (int i = 0; i < typeParameters.size(); i++) {
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
JetType typeArgument = typeArguments.get(i);
result.put(typeParameterDescriptor.getTypeConstructor(), new TypeProjectionImpl(typeArgument));
@@ -142,22 +142,25 @@ public class CandidateResolver {
projection.getTypeReference(), context.scope, context.trace, ErrorUtils.createErrorType("Star projection in a call")));
}
int expectedTypeArgumentCount = candidate.getTypeParameters().size();
if (expectedTypeArgumentCount == jetTypeArguments.size()) {
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, context.trace);
Map<TypeConstructor, TypeProjection>
substitutionContext = FunctionDescriptorUtil
.createSubstitutionContext((FunctionDescriptor) candidate, typeArguments);
TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext);
candidateCall.setResultingSubstitutor(substitutor);
candidateCall.addStatus(checkAllValueArguments(context, SHAPE_FUNCTION_ARGUMENTS).status);
for (int index = jetTypeArguments.size(); index < expectedTypeArgumentCount; index++) {
typeArguments.add(ErrorUtils.createErrorType(
"Explicit type argument expected for " + candidate.getTypeParameters().get(index).getName()));
}
else {
Map<TypeConstructor, TypeProjection> substitutionContext =
FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor) candidate, typeArguments);
TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext);
if (expectedTypeArgumentCount != jetTypeArguments.size()) {
candidateCall.addStatus(OTHER_ERROR);
context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount);
}
else {
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, substitutor, context.trace);
}
candidateCall.setResultingSubstitutor(substitutor);
candidateCall.addStatus(checkAllValueArguments(context, SHAPE_FUNCTION_ARGUMENTS).status);
}
task.performAdvancedChecks(candidate, context.trace, context.tracing);
@@ -648,17 +651,11 @@ public class CandidateResolver {
@NotNull List<JetTypeProjection> jetTypeArguments,
@NotNull List<JetType> typeArguments,
@NotNull CallableDescriptor functionDescriptor,
@NotNull BindingTrace trace) {
Map<TypeConstructor, TypeProjection> context = Maps.newHashMap();
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters();
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
TypeParameterDescriptor typeParameter = typeParameters.get(i);
JetType typeArgument = typeArguments.get(i);
context.put(typeParameter.getTypeConstructor(), new TypeProjectionImpl(typeArgument));
}
TypeSubstitutor substitutor = TypeSubstitutor.create(context);
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
@NotNull TypeSubstitutor substitutor,
@NotNull BindingTrace trace
) {
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
for (int i = 0; i < typeParameters.size(); i++) {
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
JetType typeArgument = typeArguments.get(i);
JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference();
@@ -0,0 +1,14 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun <T> foo(t: T) = t
fun test1() {
foo<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, String><!>(<!TYPE_MISMATCH!>""<!>)
}
fun <T, R> bar(t: T, r: R) {}
fun test2() {
bar<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>(<!TYPE_MISMATCH!>""<!>, "")
}
@@ -7048,6 +7048,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest("compiler/testData/diagnostics/tests/resolve/resolveWithoutGenerics.kt");
}
@TestMetadata("wrongNumberOfTypeArguments.kt")
public void testWrongNumberOfTypeArguments() throws Exception {
doTest("compiler/testData/diagnostics/tests/resolve/wrongNumberOfTypeArguments.kt");
}
@TestMetadata("compiler/testData/diagnostics/tests/resolve/invoke")
@InnerTestClasses({Invoke.Errors.class})
public static class Invoke extends AbstractJetDiagnosticsTest {
@@ -0,0 +1,9 @@
package aaaa
fun <T> foo(s: String, t: T) {}
fun test(s: String) {
foo<Int, String>(<caret>)
}
// EXIST: s
@@ -578,4 +578,9 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
doTest("idea/testData/completion/smart/WithQualifier.kt");
}
@TestMetadata("WrongNumberOfTypeArguments.kt")
public void testWrongNumberOfTypeArguments() throws Exception {
doTest("idea/testData/completion/smart/WrongNumberOfTypeArguments.kt");
}
}