From fd3c28c950425f68b264a5e61698496f1d4888f9 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Mon, 5 Oct 2015 17:50:23 +0300 Subject: [PATCH] Forbid Foo.Bar --- .../jetbrains/kotlin/diagnostics/Errors.java | 2 ++ .../rendering/DefaultErrorMessages.java | 2 +- .../org/jetbrains/kotlin/psi/JetUserType.java | 9 +++++ .../jetbrains/kotlin/resolve/TypeResolver.kt | 5 +++ .../funNestedStaticGenericClass.kt | 2 +- .../tests/classLiteral/genericClasses.kt | 6 ++-- .../tests/generics/genericsInType.kt | 36 +++++++++++++++++++ .../tests/generics/genericsInType.txt | 28 +++++++++++++++ .../GenericClassVsPackage.kt | 4 +-- .../compiledKotlin/nested/deepInnerGeneric.kt | 2 +- .../checkers/JetDiagnosticsTestGenerated.java | 6 ++++ 11 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/generics/genericsInType.kt create mode 100644 compiler/testData/diagnostics/tests/generics/genericsInType.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index f6f1cd83fb6..be913f7db7b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -176,6 +176,8 @@ public interface Errors { DiagnosticFactory0 NO_GENERICS_IN_SUPERTYPE_SPECIFIER = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 GENERICS_IN_CONTAINING_TYPE_NOT_ALLOWED = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 MANY_CLASSES_IN_SUPERTYPE_LIST = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 SUPERTYPE_APPEARS_TWICE = DiagnosticFactory0.create(ERROR); DiagnosticFactory3> 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 26a129fba8b..4ca4adf2046 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -34,7 +34,6 @@ import org.jetbrains.kotlin.renderer.MultiRenderer; import org.jetbrains.kotlin.renderer.Renderer; import org.jetbrains.kotlin.resolve.varianceChecker.VarianceChecker.VarianceConflictDiagnosticData; import org.jetbrains.kotlin.types.JetType; -import org.jetbrains.kotlin.types.expressions.OperatorConventions; import org.jetbrains.kotlin.util.MappedExtensionProvider; import org.jetbrains.kotlin.util.OperatorNameConventions; @@ -341,6 +340,7 @@ public class DefaultErrorMessages { MAP.put(TYPE_PARAMETER_IS_NOT_AN_EXPRESSION, "Type parameter ''{0}'' is not an expression", NAME); MAP.put(TYPE_PARAMETER_ON_LHS_OF_DOT, "Type parameter ''{0}'' cannot have or inherit a companion object, so it cannot be on the left hand side of dot", NAME); MAP.put(NO_GENERICS_IN_SUPERTYPE_SPECIFIER, "Generic arguments of the base type must be specified"); + MAP.put(GENERICS_IN_CONTAINING_TYPE_NOT_ALLOWED, "Generic arguments in containing types are not allowed"); MAP.put(NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE, "Nested {0} accessed via instance reference", RENDER_CLASS_OR_OBJECT_NAME); MAP.put(NESTED_CLASS_SHOULD_BE_QUALIFIED, "Nested {0} should be qualified as ''{1}''", RENDER_CLASS_OR_OBJECT_NAME, TO_STRING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetUserType.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetUserType.java index cba29f4c13f..149828da4fd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetUserType.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetUserType.java @@ -82,6 +82,15 @@ public class JetUserType extends JetElementImplStub implemen return getStubOrPsiChild(JetStubElementTypes.USER_TYPE); } + public boolean hasTypesWithTypeArgsInside() { + for (JetUserType type : getStubOrPsiChildrenAsList(JetStubElementTypes.USER_TYPE)) { + if (!type.getTypeArguments().isEmpty() || type.hasTypesWithTypeArgsInside()) { + return true; + } + } + return false; + } + public void deleteQualifier() { JetUserType qualifier = getQualifier(); assert qualifier != null; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index bd387ee0089..e38768773c0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.codeFragmentUtil.debugTypeInfo @@ -137,6 +138,10 @@ public class TypeResolver( c.trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor) + if (type.hasTypesWithTypeArgsInside()) { + c.trace.report(Errors.GENERICS_IN_CONTAINING_TYPE_NOT_ALLOWED.on(type)) + } + when (classifierDescriptor) { is TypeParameterDescriptor -> { diff --git a/compiler/testData/codegen/boxAgainstJava/visibility/protectedStatic/funNestedStaticGenericClass.kt b/compiler/testData/codegen/boxAgainstJava/visibility/protectedStatic/funNestedStaticGenericClass.kt index f4e1741e70c..7c5c35aa82f 100644 --- a/compiler/testData/codegen/boxAgainstJava/visibility/protectedStatic/funNestedStaticGenericClass.kt +++ b/compiler/testData/codegen/boxAgainstJava/visibility/protectedStatic/funNestedStaticGenericClass.kt @@ -1,4 +1,4 @@ -class Derived(): funNestedStaticGenericClass.Inner() { +class Derived(): funNestedStaticGenericClass.Inner() { fun test(): String { return funNestedStaticGenericClass.Inner.protectedFun()!! } diff --git a/compiler/testData/diagnostics/tests/classLiteral/genericClasses.kt b/compiler/testData/diagnostics/tests/classLiteral/genericClasses.kt index b424eeac499..9a1bdb4103b 100644 --- a/compiler/testData/diagnostics/tests/classLiteral/genericClasses.kt +++ b/compiler/testData/diagnostics/tests/classLiteral/genericClasses.kt @@ -15,12 +15,12 @@ val n1 = A.Nested::class val n2 = A.Nested<*>::class val i1 = A.Inner::class -val i2 = A<*>.Inner<*>::class -val i3 = A.Inner::class +val i2 = A<*>.Inner<*>::class +val i3 = A.Inner::class val m1 = Map::class val m2 = Map::class val m3 = Map.Entry::class val b1 = Int::class -val b2 = Nothing::class +val b2 = Nothing::class \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/genericsInType.kt b/compiler/testData/diagnostics/tests/generics/genericsInType.kt new file mode 100644 index 00000000000..44390e5ac96 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/genericsInType.kt @@ -0,0 +1,36 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION + + +class Foo { + class Bar { + class Baz { + + } + } +} + +fun a() {} + +fun test() { + Foo::class + Foo.Bar::class + Foo.Bar.Baz::class + + a>() + a() + + Foo.Bar::class + Foo<String>.Bar.Baz::class + + a<Foo.Bar>() + a<Foo<String>.Bar.Baz>() + + a>() + a<Foo.Bar.Baz>() +} + +fun Bar>> x() {} +fun Foo.Bar.ext() {} + +fun ex1(a: Foo.Bar): Foo.Bar { +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/genericsInType.txt b/compiler/testData/diagnostics/tests/generics/genericsInType.txt new file mode 100644 index 00000000000..aa6bfe85e5c --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/genericsInType.txt @@ -0,0 +1,28 @@ +package + +public fun a(): kotlin.Unit +public fun ex1(/*0*/ a: Foo.Bar): Foo.Bar +public fun test(): kotlin.Unit +public fun > x(): kotlin.Unit +public fun [ERROR : Bar].ext(): kotlin.Unit + +public final class Foo { + public constructor Foo() + 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 Bar { + public constructor Bar() + 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 Baz { + public constructor Baz() + 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/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.kt b/compiler/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.kt index 82b0e646a79..27c332badcd 100644 --- a/compiler/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.kt +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.kt @@ -30,7 +30,7 @@ fun test(ab_c: c) { ab_c3.ab_c() } -fun test2(a_bc: a.b.c) { +fun test2(a_bc: a.b.c) { a_bc.a_bc() // todo a_bc.ab_c() // todo } @@ -69,7 +69,7 @@ fun test(a_b: b) { _ab2._ab() // todo } -fun test2(_ab: a.b) { +fun test2(_ab: a.b) { _ab._ab() _ab.a_b() } \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledKotlin/nested/deepInnerGeneric.kt b/compiler/testData/loadJava/compiledKotlin/nested/deepInnerGeneric.kt index 0b500e848bb..1abdf24ebfa 100644 --- a/compiler/testData/loadJava/compiledKotlin/nested/deepInnerGeneric.kt +++ b/compiler/testData/loadJava/compiledKotlin/nested/deepInnerGeneric.kt @@ -6,7 +6,7 @@ class A { inner class D { fun foo(p1: P1, p2: P2, p3: P3, p4: P4): Nothing = null!! - fun bar(ta: TA, tb: TB, tc: TC, td: TD): A.B.C.D = foo(ta, tb, tc, td) + fun bar(ta: TA, tb: TB, tc: TC, td: TD): A.B.C.D = foo(ta, tb, tc, td) } } } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 55a90116ea1..01e3966dcf5 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -6327,6 +6327,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("genericsInType.kt") + public void testGenericsInType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/genericsInType.kt"); + doTest(fileName); + } + @TestMetadata("kt1575-Class.kt") public void testKt1575_Class() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/kt1575-Class.kt");