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() {
|
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();
|
if (functionDescriptor.getTypeParameters().isEmpty()) return Collections.emptyMap();
|
||||||
|
|
||||||
Map<TypeConstructor, TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>();
|
Map<TypeConstructor, TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>();
|
||||||
|
|
||||||
int typeArgumentsSize = typeArguments.size();
|
|
||||||
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
||||||
assert typeArgumentsSize == typeParameters.size();
|
assert typeArguments.size() >= typeParameters.size() :
|
||||||
for (int i = 0; i < typeArgumentsSize; i++) {
|
"Insufficient number of type arguments.\nType arguments: " + typeArguments + "\nType parameters: " + typeParameters;
|
||||||
|
for (int i = 0; i < typeParameters.size(); i++) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
||||||
JetType typeArgument = typeArguments.get(i);
|
JetType typeArgument = typeArguments.get(i);
|
||||||
result.put(typeParameterDescriptor.getTypeConstructor(), new TypeProjectionImpl(typeArgument));
|
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")));
|
projection.getTypeReference(), context.scope, context.trace, ErrorUtils.createErrorType("Star projection in a call")));
|
||||||
}
|
}
|
||||||
int expectedTypeArgumentCount = candidate.getTypeParameters().size();
|
int expectedTypeArgumentCount = candidate.getTypeParameters().size();
|
||||||
if (expectedTypeArgumentCount == jetTypeArguments.size()) {
|
for (int index = jetTypeArguments.size(); index < expectedTypeArgumentCount; index++) {
|
||||||
|
typeArguments.add(ErrorUtils.createErrorType(
|
||||||
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, context.trace);
|
"Explicit type argument expected for " + candidate.getTypeParameters().get(index).getName()));
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else {
|
Map<TypeConstructor, TypeProjection> substitutionContext =
|
||||||
|
FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor) candidate, typeArguments);
|
||||||
|
TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext);
|
||||||
|
|
||||||
|
if (expectedTypeArgumentCount != jetTypeArguments.size()) {
|
||||||
candidateCall.addStatus(OTHER_ERROR);
|
candidateCall.addStatus(OTHER_ERROR);
|
||||||
context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount);
|
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);
|
task.performAdvancedChecks(candidate, context.trace, context.tracing);
|
||||||
@@ -648,17 +651,11 @@ public class CandidateResolver {
|
|||||||
@NotNull List<JetTypeProjection> jetTypeArguments,
|
@NotNull List<JetTypeProjection> jetTypeArguments,
|
||||||
@NotNull List<JetType> typeArguments,
|
@NotNull List<JetType> typeArguments,
|
||||||
@NotNull CallableDescriptor functionDescriptor,
|
@NotNull CallableDescriptor functionDescriptor,
|
||||||
@NotNull BindingTrace trace) {
|
@NotNull TypeSubstitutor substitutor,
|
||||||
Map<TypeConstructor, TypeProjection> context = Maps.newHashMap();
|
@NotNull BindingTrace trace
|
||||||
|
) {
|
||||||
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters();
|
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
||||||
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
for (int i = 0; i < typeParameters.size(); 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++) {
|
|
||||||
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
||||||
JetType typeArgument = typeArguments.get(i);
|
JetType typeArgument = typeArguments.get(i);
|
||||||
JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference();
|
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");
|
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")
|
@TestMetadata("compiler/testData/diagnostics/tests/resolve/invoke")
|
||||||
@InnerTestClasses({Invoke.Errors.class})
|
@InnerTestClasses({Invoke.Errors.class})
|
||||||
public static class Invoke extends AbstractJetDiagnosticsTest {
|
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");
|
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