From 7b432c878a758ad7b141629d9ccaa7c3d03161e6 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 17 Nov 2015 15:51:57 +0300 Subject: [PATCH] Diagnostics improvements for corner cases (class/package qualifier in non-qualifier position). --- .../resolve/QualifiedExpressionResolver.kt | 6 ++-- .../resolve/calls/CallExpressionResolver.java | 14 ++++++---- .../tests/PackageInExpressionPosition.kt | 28 +++++++++---------- .../tests/PackageInExpressionPosition.txt | 10 +++---- .../tests/SafeCallOnFakePackage.kt | 4 +-- .../tests/classObjects/ClassObjects.kt | 2 +- .../tests/classObjects/ClassObjects.txt | 2 +- .../InnerClassAccessThroughClassObject.kt | 2 +- .../InnerClassAccessThroughEnum.kt | 2 +- .../arrayExpression.kt | 2 +- ...nestedClassAccessedViaInstanceReference.kt | 6 ++-- .../diagnostics/tests/regressions/kt2956.kt | 2 +- .../tests/resolve/constructorVsCompanion.kt | 4 +-- .../tests/resolve/constructorVsCompanion.txt | 4 +-- .../tests/sealed/TreeWhenFunctionalNoIs.kt | 2 +- .../resolve/javaStaticMembers.kt | 6 ++-- .../autoImports/unresolvedReferenceInCall.kt | 2 +- .../unresolvedReferenceInCall.kt.after | 2 +- 18 files changed, 52 insertions(+), 48 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt index bf43a40996d..896b3814f8f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt @@ -399,14 +399,16 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa val qualifierDescriptor = when { receiver is PackageQualifier -> { val childPackageFQN = receiver.packageView.fqName.child(name) - val childPackageDescriptor = receiver.packageView.module.getPackage(childPackageFQN).check { !it.isEmpty() } - childPackageDescriptor ?: receiver.packageView.memberScope.getContributedClassifier(name, KotlinLookupLocation(expression)) + receiver.packageView.module.getPackage(childPackageFQN).check { !it.isEmpty() } ?: + receiver.packageView.memberScope.getContributedClassifier(name, KotlinLookupLocation(expression)) } receiver is ClassQualifier -> receiver.scope.getContributedClassifier(name, KotlinLookupLocation(expression)) !receiver.exists() -> context.scope.findClassifier(name, KotlinLookupLocation(expression)) ?: context.scope.ownerDescriptor.module.getPackage(FqName.ROOT.child(name)).check { !it.isEmpty() } + receiver is ReceiverValue -> + receiver.type.memberScope.memberScopeAsImportingScope().findClassifier(name, KotlinLookupLocation(expression)) else -> null } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java index 594c57aba96..398298b2bae 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java @@ -177,11 +177,13 @@ public class CallExpressionResolver { call, newContext, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, result); if (result[0]) { FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; - temporaryForFunction.commit(); - boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0; - context.trace.report(FUNCTION_CALL_EXPECTED.on(nameExpression, nameExpression, hasValueParameters)); - type = functionDescriptor != null ? functionDescriptor.getReturnType() : null; - return TypeInfoFactoryKt.createTypeInfo(type, context); + if (!(functionDescriptor instanceof ConstructorDescriptor)) { + temporaryForFunction.commit(); + boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0; + context.trace.report(FUNCTION_CALL_EXPECTED.on(nameExpression, nameExpression, hasValueParameters)); + type = functionDescriptor != null ? functionDescriptor.getReturnType() : null; + return TypeInfoFactoryKt.createTypeInfo(type, context); + } } TemporaryTraceAndCache temporaryForQualifier = TemporaryTraceAndCache.create(context, "trace to resolve as qualifier", nameExpression); @@ -190,7 +192,7 @@ public class CallExpressionResolver { if (qualifier != null) { QualifiedExpressionResolveUtilKt.resolveQualifierAsStandaloneExpression(qualifier, contextForQualifier, symbolUsageValidator); temporaryForQualifier.commit(); - return TypeInfoFactoryKt.createTypeInfo(null, context); + return TypeInfoFactoryKt.noTypeInfo(context); } temporaryForVariable.commit(); diff --git a/compiler/testData/diagnostics/tests/PackageInExpressionPosition.kt b/compiler/testData/diagnostics/tests/PackageInExpressionPosition.kt index 4de84a1a10e..19bbc758b52 100644 --- a/compiler/testData/diagnostics/tests/PackageInExpressionPosition.kt +++ b/compiler/testData/diagnostics/tests/PackageInExpressionPosition.kt @@ -3,24 +3,24 @@ package foo class X {} val s = java -val ss = System -val sss = X -val x = "${System}" +val ss = System +val sss = X +val x = "${System}" val xs = java.lang -val xss = java.lang.System -val xsss = foo.X +val xss = java.lang.System +val xsss = foo.X val xssss = foo -val f = { System } +val f = { System } fun main(args : Array) { java = null - System = null - System!! - java.lang.System = null - java.lang.System!! - System is Int + System = null + System!! + java.lang.System = null + java.lang.System!! + System is Int System() - (System) - foo@ System - null in System + (System) + foo@ System + null in System } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/PackageInExpressionPosition.txt b/compiler/testData/diagnostics/tests/PackageInExpressionPosition.txt index 42cd87be5ec..4485e026e44 100644 --- a/compiler/testData/diagnostics/tests/PackageInExpressionPosition.txt +++ b/compiler/testData/diagnostics/tests/PackageInExpressionPosition.txt @@ -1,14 +1,14 @@ package package foo { - public val f: () -> java.lang.System + public val f: () -> ??? public val s: [ERROR : Type for java] - public val ss: java.lang.System - public val sss: foo.X + public val ss: [ERROR : Type for System] + public val sss: [ERROR : Type for X] public val x: kotlin.String public val xs: [ERROR : Type for java.lang] - public val xss: java.lang.System - public val xsss: foo.X + public val xss: [ERROR : Type for java.lang.System] + public val xsss: [ERROR : Type for foo.X] public val xssss: [ERROR : Type for foo] public fun main(/*0*/ args: kotlin.Array): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/SafeCallOnFakePackage.kt b/compiler/testData/diagnostics/tests/SafeCallOnFakePackage.kt index e050eab938d..438400a2b11 100644 --- a/compiler/testData/diagnostics/tests/SafeCallOnFakePackage.kt +++ b/compiler/testData/diagnostics/tests/SafeCallOnFakePackage.kt @@ -10,7 +10,7 @@ val s: String = "test" // FILE: test.kt fun ff() { - val a = Test?.FOO + val a = Test?.FOO val b = foo?.s - System?.out.println(a + b) + System?.out.println(a + b) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/classObjects/ClassObjects.kt b/compiler/testData/diagnostics/tests/classObjects/ClassObjects.kt index fa901d730f6..95191baeb53 100644 --- a/compiler/testData/diagnostics/tests/classObjects/ClassObjects.kt +++ b/compiler/testData/diagnostics/tests/classObjects/ClassObjects.kt @@ -36,7 +36,7 @@ val a = A.x val c = B.x val d = b.x -val s = System // error +val s = System // error fun test() { System.out.println() java.lang.System.out.println() diff --git a/compiler/testData/diagnostics/tests/classObjects/ClassObjects.txt b/compiler/testData/diagnostics/tests/classObjects/ClassObjects.txt index 0c499f84944..a672bc12d37 100644 --- a/compiler/testData/diagnostics/tests/classObjects/ClassObjects.txt +++ b/compiler/testData/diagnostics/tests/classObjects/ClassObjects.txt @@ -4,7 +4,7 @@ package Jet86 { public val a: kotlin.Int = 1 public val c: [ERROR : Type for B.x] public val d: [ERROR : Type for b.x] - public val s: java.lang.System + public val s: [ERROR : Type for System] public fun test(): kotlin.Unit public final class A { diff --git a/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughClassObject.kt b/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughClassObject.kt index 680e6fe56cf..f5a74364b7e 100644 --- a/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughClassObject.kt +++ b/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughClassObject.kt @@ -28,7 +28,7 @@ object O { fun f() { A.c A.hashCode() - A().Nested + A().Nested A.Nested() A().Inner() A.Companion.Nested diff --git a/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum.kt b/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum.kt index f8be2f7d2c9..63471ab7579 100644 --- a/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum.kt +++ b/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum.kt @@ -32,7 +32,7 @@ enum class C { } fun f() { - C.E1.A + C.E1.A C.E1.A() C.E2.B() diff --git a/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/arrayExpression.kt b/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/arrayExpression.kt index 64480d663e8..c94d9ba916f 100644 --- a/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/arrayExpression.kt +++ b/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/arrayExpression.kt @@ -3,5 +3,5 @@ package bar fun main(args : Array) { class Some - Some[] names = ["ads"] + Some[] names = ["ads"] } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inner/nestedClassAccessedViaInstanceReference.kt b/compiler/testData/diagnostics/tests/inner/nestedClassAccessedViaInstanceReference.kt index c233d9959f8..35bd514a8ae 100644 --- a/compiler/testData/diagnostics/tests/inner/nestedClassAccessedViaInstanceReference.kt +++ b/compiler/testData/diagnostics/tests/inner/nestedClassAccessedViaInstanceReference.kt @@ -28,7 +28,7 @@ fun test(with: WithClassObject, without: WithoutClassObject, obj: Obj) { with.NestedWithClassObject with.NestedWithClassObject() with.NestedWithClassObject.foo() - with.NestedEnum.A + with.NestedEnum.A with.NestedObj with.NestedObj() with.NestedObj.foo() @@ -37,7 +37,7 @@ fun test(with: WithClassObject, without: WithoutClassObject, obj: Obj) { without.NestedWithClassObject without.NestedWithClassObject() without.NestedWithClassObject.foo() - without.NestedEnum.A + without.NestedEnum.A without.NestedObj without.NestedObj() without.NestedObj.foo() @@ -46,7 +46,7 @@ fun test(with: WithClassObject, without: WithoutClassObject, obj: Obj) { obj.NestedWithClassObject obj.NestedWithClassObject() obj.NestedWithClassObject.foo() - obj.NestedEnum.A + obj.NestedEnum.A obj.NestedObj obj.NestedObj() obj.NestedObj.foo() diff --git a/compiler/testData/diagnostics/tests/regressions/kt2956.kt b/compiler/testData/diagnostics/tests/regressions/kt2956.kt index d0b150002ee..e128a6685de 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt2956.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt2956.kt @@ -1 +1 @@ -val a: String = Nothing \ No newline at end of file +val a: String = Nothing \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/constructorVsCompanion.kt b/compiler/testData/diagnostics/tests/resolve/constructorVsCompanion.kt index 1dd8405d4a1..b3a45c91266 100644 --- a/compiler/testData/diagnostics/tests/resolve/constructorVsCompanion.kt +++ b/compiler/testData/diagnostics/tests/resolve/constructorVsCompanion.kt @@ -16,8 +16,8 @@ class E private constructor() { } } -val a = A +val a = A val b = B -val c = C +val c = C val d = D val e = E(42) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/constructorVsCompanion.txt b/compiler/testData/diagnostics/tests/resolve/constructorVsCompanion.txt index e560bfa5f4c..8a73be8eb4e 100644 --- a/compiler/testData/diagnostics/tests/resolve/constructorVsCompanion.txt +++ b/compiler/testData/diagnostics/tests/resolve/constructorVsCompanion.txt @@ -1,8 +1,8 @@ package -public val a: A +public val a: [ERROR : Type for A] public val b: B.Companion -public val c: C +public val c: [ERROR : Type for C] public val d: D.Companion public val e: kotlin.Int diff --git a/compiler/testData/diagnostics/tests/sealed/TreeWhenFunctionalNoIs.kt b/compiler/testData/diagnostics/tests/sealed/TreeWhenFunctionalNoIs.kt index 2264609a5ae..b6d17eac5d4 100644 --- a/compiler/testData/diagnostics/tests/sealed/TreeWhenFunctionalNoIs.kt +++ b/compiler/testData/diagnostics/tests/sealed/TreeWhenFunctionalNoIs.kt @@ -11,7 +11,7 @@ sealed class Tree { fun maxIsClass(): Int = when(this) { Empty -> -1 - Leaf -> 0 + Leaf -> 0 is Node -> this.left.max() } diff --git a/compiler/testData/diagnostics/testsWithStdLib/resolve/javaStaticMembers.kt b/compiler/testData/diagnostics/testsWithStdLib/resolve/javaStaticMembers.kt index dcb6eba37cd..b5e670dd9a5 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/resolve/javaStaticMembers.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/resolve/javaStaticMembers.kt @@ -6,7 +6,7 @@ public class Test { // FILE: test.kt fun ff() { val a = Test.FOO - val b = Test?.FOO - System.out.println(a + b) - System?.out.println(a + b) + val b = Test?.FOO + System.out.println(a + b) + System?.out.println(a + b) } \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/unresolvedReferenceInCall.kt b/idea/testData/quickfix/autoImports/unresolvedReferenceInCall.kt index c880b13579e..7eff2d31234 100644 --- a/idea/testData/quickfix/autoImports/unresolvedReferenceInCall.kt +++ b/idea/testData/quickfix/autoImports/unresolvedReferenceInCall.kt @@ -1,5 +1,5 @@ // "Import" "true" -// ERROR: Function invocation 'ArrayList()' expected +// ERROR: Please specify constructor invocation; classifier 'ArrayList' does not have a companion object // KT-4000 diff --git a/idea/testData/quickfix/autoImports/unresolvedReferenceInCall.kt.after b/idea/testData/quickfix/autoImports/unresolvedReferenceInCall.kt.after index cae88b4a17b..34d5e839e1c 100644 --- a/idea/testData/quickfix/autoImports/unresolvedReferenceInCall.kt.after +++ b/idea/testData/quickfix/autoImports/unresolvedReferenceInCall.kt.after @@ -1,5 +1,5 @@ // "Import" "true" -// ERROR: Function invocation 'ArrayList()' expected +// ERROR: Please specify constructor invocation; classifier 'ArrayList' does not have a companion object // KT-4000