Fixed NPE in ArgumentMatchImpl.getStatus
Check value arguments if there is wrong number of type arguments
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user