Improve message clarity for WRONG_NUMBER_OF_TYPE_ARGUMENTS diagnostics

#KT-9887 Fixed
This commit is contained in:
Pavel V. Talanov
2016-03-10 14:17:28 +03:00
parent d6cd46e079
commit 7de171efda
23 changed files with 75 additions and 40 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -98,7 +98,8 @@ public interface Errors {
DiagnosticFactory0<KtTypeProjection> PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT = DiagnosticFactory0.create(ERROR, VARIANCE_IN_PROJECTION);
DiagnosticFactory2<KtTypeReference, KotlinType, KotlinType> UPPER_BOUND_VIOLATED = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<KtNullableType> REDUNDANT_NULLABLE = DiagnosticFactory0.create(WARNING, NULLABLE_TYPE);
DiagnosticFactory1<KtElement, Integer> WRONG_NUMBER_OF_TYPE_ARGUMENTS = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<KtElement, Integer, DeclarationDescriptor> WRONG_NUMBER_OF_TYPE_ARGUMENTS = DiagnosticFactory2.create(ERROR);
DiagnosticFactory1<KtElement, String> TYPE_ARGUMENTS_NOT_ALLOWED = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<KtTypeReference, Integer, String> NO_TYPE_ARGUMENTS_ON_RHS = DiagnosticFactory2.create(ERROR);
DiagnosticFactory1<KtTypeProjection, ClassifierDescriptor> CONFLICTING_PROJECTION = DiagnosticFactory1.create(ERROR, VARIANCE_IN_PROJECTION);
DiagnosticFactory1<KtTypeProjection, ClassifierDescriptor> REDUNDANT_PROJECTION = DiagnosticFactory1.create(WARNING, VARIANCE_IN_PROJECTION);
@@ -656,9 +656,10 @@ public class DefaultErrorMessages {
MAP.put(TYPE_INFERENCE_FAILED_ON_SPECIAL_CONSTRUCT, "Type inference for control flow expression failed. Please specify its type explicitly.");
MAP.put(WRONG_NUMBER_OF_TYPE_ARGUMENTS, "{0,choice,0#No type arguments|1#Type argument|1<{0,number,integer} type arguments} expected", (DiagnosticParameterRenderer) null);
MAP.put(NO_TYPE_ARGUMENTS_ON_RHS, "{0,choice,0#No type arguments|1#Type argument|1<{0,number,integer} type arguments} expected. " +
"Use ''{1}'' if you don''t want to pass type arguments", null, STRING);
String wrongNumberOfTypeArguments = "{0,choice,0#No type arguments|1#One type argument|1<{0,number,integer} type arguments} expected";
MAP.put(WRONG_NUMBER_OF_TYPE_ARGUMENTS, wrongNumberOfTypeArguments + " for {1}", null, WITHOUT_MODIFIERS);
MAP.put(NO_TYPE_ARGUMENTS_ON_RHS, wrongNumberOfTypeArguments + ". Use ''{1}'' if you don''t want to pass type arguments", null, STRING);
MAP.put(TYPE_ARGUMENTS_NOT_ALLOWED, "Type arguments are not allowed {0}", STRING);
MAP.put(TYPE_PARAMETER_AS_REIFIED, "Cannot use ''{0}'' as reified type parameter. Use a class instead.", NAME);
MAP.put(REIFIED_TYPE_PARAMETER_NO_INLINE, "Only type parameters of inline functions can be reified");
@@ -433,6 +433,9 @@ object Renderers {
@JvmField val FQ_NAMES_IN_TYPES = DescriptorRenderer.FQ_NAMES_IN_TYPES.asRenderer()
@JvmField val COMPACT = DescriptorRenderer.COMPACT.asRenderer()
@JvmField val WITHOUT_MODIFIERS = DescriptorRenderer.withOptions {
modifiers = emptySet()
}.asRenderer()
@JvmField val SHORT_NAMES_IN_TYPES = DescriptorRenderer.SHORT_NAMES_IN_TYPES.asRenderer()
@JvmField val COMPACT_WITH_MODIFIERS = DescriptorRenderer.COMPACT_WITH_MODIFIERS.asRenderer()
@JvmField val DEPRECATION_RENDERER = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.withOptions {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -306,7 +306,7 @@ class TypeResolver(
val arguments = resolveTypeProjections(c, ErrorUtils.createErrorType("No type").constructor, type.typeArguments)
if (!arguments.isEmpty()) {
c.trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type.typeArgumentList!!, 0))
c.trace.report(TYPE_ARGUMENTS_NOT_ALLOWED.on(type.typeArgumentList!!, "for type parameters"))
}
val containing = typeParameter.containingDeclaration
@@ -445,7 +445,10 @@ class TypeResolver(
if (currentArguments.size != currentParameters.size) {
c.trace.report(
WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(qualifierPart.typeArguments ?: qualifierPart.expression, currentParameters.size))
WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(
qualifierPart.typeArguments ?: qualifierPart.expression, currentParameters.size, classDescriptorChain[index]
)
)
return null
}
@@ -461,7 +464,7 @@ class TypeResolver(
for (qualifierPart in nonClassQualifierParts) {
if (qualifierPart.typeArguments != null) {
c.trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(qualifierPart.typeArguments, 0))
c.trace.report(TYPE_ARGUMENTS_NOT_ALLOWED.on(qualifierPart.typeArguments, "here"))
return null
}
}
@@ -471,7 +474,7 @@ class TypeResolver(
val typeParametersToSpecify =
parameters.subList(result.size, parameters.size).takeWhile { it.original.containingDeclaration is ClassDescriptor }
if (typeParametersToSpecify.any { parameter -> !parameter.isDeclaredInScope(c) }) {
c.trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(qualifierParts.last().expression, parameters.size))
c.trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(qualifierParts.last().expression, parameters.size, classDescriptor))
return null
}
}
@@ -135,7 +135,7 @@ class CandidateResolver(
if (expectedTypeArgumentCount != jetTypeArguments.size) {
candidateCall.addStatus(OTHER_ERROR)
tracing.wrongNumberOfTypeArguments(trace, expectedTypeArgumentCount)
tracing.wrongNumberOfTypeArguments(trace, expectedTypeArgumentCount, candidateDescriptor)
}
else {
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidateDescriptor, substitutor, trace)
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -103,14 +103,13 @@ public abstract class AbstractTracingStrategy implements TracingStrategy {
}
@Override
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {
public void wrongNumberOfTypeArguments(
@NotNull BindingTrace trace, int expectedTypeArgumentCount, @NotNull CallableDescriptor descriptor
) {
KtTypeArgumentList typeArgumentList = call.getTypeArgumentList();
if (typeArgumentList != null) {
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(typeArgumentList, expectedTypeArgumentCount));
}
else {
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(reference, expectedTypeArgumentCount));
}
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(
typeArgumentList != null ? typeArgumentList : reference, expectedTypeArgumentCount, descriptor
));
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -67,7 +67,7 @@ public interface TracingStrategy {
public void noValueForParameter(@NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter) {}
@Override
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {}
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount, @NotNull CallableDescriptor descriptor) {}
@Override
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> descriptors) {}
@@ -132,7 +132,11 @@ public interface TracingStrategy {
void noValueForParameter(@NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter);
void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount);
void wrongNumberOfTypeArguments(
@NotNull BindingTrace trace,
int expectedTypeArgumentCount,
@NotNull CallableDescriptor descriptor
);
<D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> descriptors);
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -126,7 +126,7 @@ class TracingStrategyForImplicitConstructorDelegationCall(
unexpectedError("noReceiverAllowed")
}
override fun wrongNumberOfTypeArguments(trace: BindingTrace, expectedTypeArgumentCount: Int) {
override fun wrongNumberOfTypeArguments(trace: BindingTrace, expectedTypeArgumentCount: Int, descriptor: CallableDescriptor) {
unexpectedError("wrongNumberOfTypeArguments")
}
@@ -542,7 +542,7 @@ public class ControlStructureTypingUtils {
}
@Override
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount, @NotNull CallableDescriptor descriptor) {
logError();
}
+1 -1
View File
@@ -12,7 +12,7 @@ package foobar.a
package foobar
abstract class Foo<T>() {
abstract val x : T<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>
abstract val x : T<!TYPE_ARGUMENTS_NOT_ALLOWED!><Int><!>
}
// FILE: b.kt
@@ -1,7 +1,7 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun <T> foo(t: T<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String, Int><!>) {}
fun <T> foo(t: T<!TYPE_ARGUMENTS_NOT_ALLOWED!><String, Int><!>) {}
interface A
class B<T: A>
fun <T> foo1(t: T<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><B<<!UPPER_BOUND_VIOLATED!>String<!>>><!>) {}
fun <T> foo1(t: T<!TYPE_ARGUMENTS_NOT_ALLOWED!><B<<!UPPER_BOUND_VIOLATED!>String<!>>><!>) {}
@@ -48,4 +48,4 @@ fun error4(): Outer<!TYPE_ARGUMENTS_FOR_OUTER_CLASS_WHEN_NESTED_REFERENCED!><A><
fun error5(): Outer<!TYPE_ARGUMENTS_FOR_OUTER_CLASS_WHEN_NESTED_REFERENCED!><A><!>.Obj.Nested2<B>.Inner5<C> = null!!
fun error6(): Outer.Obj<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><A><!>.Nested2<B>.Inner5<C> = null!!
fun error7(): test<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String><!>.Outer.Obj.Nested2<A>.Inner5<B> = null!!
fun error7(): test<!TYPE_ARGUMENTS_NOT_ALLOWED!><String><!>.Outer.Obj.Nested2<A>.Inner5<B> = null!!
+7
View File
@@ -0,0 +1,7 @@
package foo
open class A<T>
fun <T> f(<warning>t</warning>: T<error descr="[TYPE_ARGUMENTS_NOT_ALLOWED] Type arguments are not allowed for type parameters"><T></error>) {}
fun <T> use(<warning>b</warning>: foo<error descr="[TYPE_ARGUMENTS_NOT_ALLOWED] Type arguments are not allowed here"><T></error>.A<T>) {}
+5
View File
@@ -0,0 +1,5 @@
open class A<T>()
class G<T>()
class B : A<<error descr="[WRONG_NUMBER_OF_TYPE_ARGUMENTS] One type argument expected for class G<T> defined in root package">G</error>>()
@@ -1,5 +1,5 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddStarProjectionsFix" "false"
// ERROR: 2 type arguments expected
// ERROR: 2 type arguments expected for interface Map<K, out V> defined in kotlin.collections
public fun foo(a: Any) {
a is <caret>Map<Int>
}
@@ -1,5 +1,5 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddStarProjectionsFix" "false"
// ERROR: 2 type arguments expected
// ERROR: 2 type arguments expected for Map
public fun foo(a: Any) {
a is Map<Int>
}
@@ -1,5 +1,5 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddStarProjectionsFix" "false"
// ERROR: 2 type arguments expected
// ERROR: 2 type arguments expected for interface Map<K, out V> defined in kotlin.collections
public fun foo(a: Any) {
when (a) {
is <caret>Map<Int> -> {}
@@ -1,5 +1,5 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddStarProjectionsFix" "false"
// ERROR: 2 type arguments expected
// ERROR: 2 type arguments expected for Map
public fun foo(a: Any) {
when (a) {
is Map<Int> -> {}
@@ -1,7 +1,7 @@
// "Create secondary constructor" "false"
// ACTION: Add parameter to constructor 'A'
// ACTION: Create function 'A'
// ERROR: No type arguments expected
// ERROR: No type arguments expected for constructor A() defined in A
// ERROR: Too many arguments for public constructor A() defined in A
class A
+1 -1
View File
@@ -1,6 +1,6 @@
// "Make 'IterablePipeline' abstract" "true"
// ERROR: 'pipe' overrides nothing
// ERROR: Type argument expected
// ERROR: One type argument expected for interface Pipeline<TPipeline> defined in root package
// Actually this test is about getting rid of assertion happenning while creating quick fixes
// See KT-10409
+1 -1
View File
@@ -1,6 +1,6 @@
// "Make 'IterablePipeline' abstract" "true"
// ERROR: 'pipe' overrides nothing
// ERROR: Type argument expected
// ERROR: One type argument expected for interface Pipeline<TPipeline> defined in root package
// Actually this test is about getting rid of assertion happenning while creating quick fixes
// See KT-10409
@@ -343,6 +343,12 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
doTest(fileName);
}
@TestMetadata("TypeArgumentsNotAllowed.kt")
public void testTypeArgumentsNotAllowed() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/TypeArgumentsNotAllowed.kt");
doTest(fileName);
}
@TestMetadata("TypeParameterBounds.kt")
public void testTypeParameterBounds() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/TypeParameterBounds.kt");
@@ -598,6 +604,12 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
doTest(fileName);
}
@TestMetadata("kt9887.kt")
public void testKt9887() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/kt9887.kt");
doTest(fileName);
}
@TestMetadata("objectLiteralInSupertypeList.kt")
public void testObjectLiteralInSupertypeList() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/objectLiteralInSupertypeList.kt");
@@ -51,16 +51,16 @@ End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
Type argument expected
Type argument expected
Type argument expected
One type argument expected for class A<T> defined in foo
One type argument expected for class A<T> defined in foo
One type argument expected for class A<T> defined in foo
Type inference failed: Not enough information to infer parameter T in constructor A<T>()
Please specify it explicitly.
Type inference failed: Not enough information to infer parameter T in constructor A<T>()
Please specify it explicitly.
Type inference failed: Not enough information to infer parameter T in constructor A<T>()
Please specify it explicitly.
Type argument expected
One type argument expected for class A<T> defined in foo
================ Step #2 =================