From 556df93ca7ada2a2f6216bf2d561586de196ed20 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 14 Sep 2016 12:33:27 +0300 Subject: [PATCH] Refine diagnostic about type arguments for an outer class #KT-11263 Fixed --- .../jetbrains/kotlin/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 5 ++ .../jetbrains/kotlin/resolve/TypeResolver.kt | 3 +- .../implicitArguments/fromCompanionObject.kt | 2 +- .../implicitArguments/inStaticScope.kt | 4 +- .../generics/innerClasses/importedInner.kt | 4 +- .../innerClasses/outerArgumentsRequired.kt | 23 +++++++++ .../innerClasses/outerArgumentsRequired.txt | 49 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 +++ 9 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/generics/innerClasses/outerArgumentsRequired.kt create mode 100644 compiler/testData/diagnostics/tests/generics/innerClasses/outerArgumentsRequired.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index f299e963daf..7465375966e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -103,6 +103,7 @@ public interface Errors { DiagnosticFactory2 UPPER_BOUND_VIOLATED = DiagnosticFactory2.create(ERROR); DiagnosticFactory0 REDUNDANT_NULLABLE = DiagnosticFactory0.create(WARNING, NULLABLE_TYPE); DiagnosticFactory2 WRONG_NUMBER_OF_TYPE_ARGUMENTS = DiagnosticFactory2.create(ERROR); + DiagnosticFactory1 OUTER_CLASS_ARGUMENTS_REQUIRED = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 TYPE_ARGUMENTS_NOT_ALLOWED = DiagnosticFactory1.create(ERROR); DiagnosticFactory2 NO_TYPE_ARGUMENTS_ON_RHS = DiagnosticFactory2.create(ERROR); DiagnosticFactory1 CONFLICTING_PROJECTION = DiagnosticFactory1.create(ERROR, VARIANCE_IN_PROJECTION); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 3b1f715f035..7ed83e59d18 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -680,6 +680,11 @@ public class DefaultErrorMessages { 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( + OUTER_CLASS_ARGUMENTS_REQUIRED, + "Type arguments should be specified for an outer {0}. Use full class name to specify them", + RENDER_CLASS_OR_OBJECT_NAME); 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); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index 74bab690f46..d87ac21fa13 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -645,8 +645,7 @@ class TypeResolver( if (restArguments == null && typeArgumentsCanBeSpecifiedCount > result.size) { c.trace.report( - WRONG_NUMBER_OF_TYPE_ARGUMENTS.on( - qualifierParts.last().expression, typeArgumentsCanBeSpecifiedCount, classifierDescriptor)) + OUTER_CLASS_ARGUMENTS_REQUIRED.on(qualifierParts.first().expression, nextParameterOwner)) return null } else if (restArguments == null) { diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromCompanionObject.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromCompanionObject.kt index e8868755fee..e55283f2f3a 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromCompanionObject.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromCompanionObject.kt @@ -14,7 +14,7 @@ class A { // Does not work, could be Outer.Inner // TODO: Should work? - fun foo(x: Inner) { + fun foo(x: Inner) { // Inner() call use companion as implicit receiver val y: Outer.Inner = Inner() } diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/inStaticScope.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/inStaticScope.kt index 0fcae058ddf..a377312ddb7 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/inStaticScope.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/inStaticScope.kt @@ -2,6 +2,6 @@ interface Inv class Outer { inner class Inner - class Nested : Inv<Inner> - object Obj : Inv<Inner> + class Nested : Inv<Inner> + object Obj : Inv<Inner> } diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/importedInner.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/importedInner.kt index 30c88512308..c2faa24b804 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/importedInner.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/importedInner.kt @@ -11,10 +11,10 @@ class Outer { } class Nested { - fun bar(x: Inner) {} + fun bar(x: Inner) {} } } class E -fun bar(x: Inner) {} +fun bar(x: Inner) {} diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/outerArgumentsRequired.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/outerArgumentsRequired.kt new file mode 100644 index 00000000000..8332da177c1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/outerArgumentsRequired.kt @@ -0,0 +1,23 @@ +import A.B.D +import A.B.C +import A.B.D.Innermost + +class A { + inner class B { + inner class C + inner class D { + inner class Innermost + } + } + + class Nested { + val x: B? = null + val y: B.C? = null + val z: B.D? = null + + val c: C? = null + val d: D? = null + + val innerMost: Innermost? = null + } +} diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/outerArgumentsRequired.txt b/compiler/testData/diagnostics/tests/generics/innerClasses/outerArgumentsRequired.txt new file mode 100644 index 00000000000..386a8307121 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/outerArgumentsRequired.txt @@ -0,0 +1,49 @@ +package + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public final inner class B /*captured type parameters: /*1*/ T*/ { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public final inner class C /*captured type parameters: /*1*/ F, /*2*/ T*/ { + public constructor C() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public final inner class D /*captured type parameters: /*0*/ F, /*1*/ T*/ { + public constructor D() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public final inner class Innermost /*captured type parameters: /*1*/ F, /*2*/ T*/ { + public constructor Innermost() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } + } + + public final class Nested { + public constructor Nested() + public final val c: [ERROR : C]? + public final val d: [ERROR : D]? + public final val innerMost: [ERROR : Innermost]? + public final val x: [ERROR : B]? + public final val y: [ERROR : C]? + public final val z: [ERROR : D]? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index e9c89b7e161..f0b4683e96c 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -7934,6 +7934,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("outerArgumentsRequired.kt") + public void testOuterArgumentsRequired() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/innerClasses/outerArgumentsRequired.kt"); + doTest(fileName); + } + @TestMetadata("parameterShadowing.kt") public void testParameterShadowing() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/innerClasses/parameterShadowing.kt");