Change importing rules for objects:
Allow importing classes from object, prohibit import-on-demand from objects It's unclear what import-on-demand from object should mean so we prohibit it for now
This commit is contained in:
@@ -100,6 +100,7 @@ public interface Errors {
|
||||
// Imports
|
||||
|
||||
DiagnosticFactory1<JetSimpleNameExpression, DeclarationDescriptor> CANNOT_IMPORT_FROM_ELEMENT = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<JetSimpleNameExpression, ClassDescriptor> CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<JetSimpleNameExpression, DeclarationDescriptor> CANNOT_BE_IMPORTED = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<JetExpression, String> CONFLICTING_IMPORT = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
+1
@@ -166,6 +166,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(EXPRESSION_EXPECTED_PACKAGE_FOUND, "Expression expected, but a package name found");
|
||||
|
||||
MAP.put(CANNOT_IMPORT_FROM_ELEMENT, "Cannot import from ''{0}''", NAME);
|
||||
MAP.put(CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON, "Cannot import-on-demand from object ''{0}''", NAME);
|
||||
MAP.put(CANNOT_BE_IMPORTED, "Cannot import ''{0}'', functions and properties can be imported only from packages", NAME);
|
||||
MAP.put(CONFLICTING_IMPORT, "Conflicting import, imported name ''{0}'' is ambiguous", STRING);
|
||||
MAP.put(PLATFORM_CLASS_MAPPED_TO_KOTLIN, "This class shouldn''t be used in Kotlin. Use {0} instead.", CLASSES_OR_SEPARATED);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class Importer {
|
||||
if (descriptor is PackageViewDescriptor) {
|
||||
allUnderImportScopes.add(NoSubpackagesInPackageScope(descriptor))
|
||||
}
|
||||
else if (descriptor is ClassDescriptor && descriptor.getKind() != ClassKind.OBJECT) {
|
||||
else if (descriptor is ClassDescriptor && QualifiedExpressionResolver.canAllUnderImportFromClass(descriptor)) {
|
||||
allUnderImportScopes.add(descriptor.getStaticScope())
|
||||
allUnderImportScopes.add(descriptor.getUnsubstitutedInnerClassesScope())
|
||||
|
||||
|
||||
+24
-1
@@ -54,6 +54,25 @@ public class QualifiedExpressionResolver {
|
||||
EVERYTHING
|
||||
}
|
||||
|
||||
public static boolean canAllUnderImportFrom(@NotNull Collection<DeclarationDescriptor> descriptors) {
|
||||
if (descriptors.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
if (!(descriptor instanceof ClassDescriptor)) {
|
||||
return true;
|
||||
}
|
||||
if (canAllUnderImportFromClass((ClassDescriptor) descriptor)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean canAllUnderImportFromClass(@NotNull ClassDescriptor descriptor) {
|
||||
return !descriptor.getKind().isSingleton();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<DeclarationDescriptor> processImportReference(
|
||||
@NotNull JetImportDirective importDirective,
|
||||
@@ -88,6 +107,10 @@ public class QualifiedExpressionResolver {
|
||||
|
||||
JetSimpleNameExpression referenceExpression = JetPsiUtil.getLastReference(importedReference);
|
||||
if (importDirective.isAllUnder()) {
|
||||
if (!canAllUnderImportFrom(descriptors) && referenceExpression != null) {
|
||||
trace.report(CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON.on(referenceExpression, (ClassDescriptor) descriptors.iterator().next()));
|
||||
}
|
||||
|
||||
if (referenceExpression == null || !canImportMembersFrom(descriptors, referenceExpression, trace, lookupMode)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -150,7 +173,7 @@ public class QualifiedExpressionResolver {
|
||||
if (descriptor instanceof PackageViewDescriptor) {
|
||||
return true;
|
||||
}
|
||||
if (descriptor instanceof ClassDescriptor && !((ClassDescriptor) descriptor).getKind().isSingleton()) {
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
return true;
|
||||
}
|
||||
trace.report(CANNOT_IMPORT_FROM_ELEMENT.on(reference, descriptor));
|
||||
|
||||
@@ -70,7 +70,7 @@ fun bar() {}
|
||||
//FILE:c.kt
|
||||
package c
|
||||
|
||||
import c.<!CANNOT_IMPORT_FROM_ELEMENT!>C<!>.*
|
||||
import c.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>C<!>.*
|
||||
|
||||
object C {
|
||||
fun f() {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package a
|
||||
|
||||
import a.A.*
|
||||
import a.A.C
|
||||
import a.A.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>C<!>.*
|
||||
import a.A.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>D<!>.*
|
||||
import a.A.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>C<!>.*
|
||||
import a.A.C.G
|
||||
import a.A.E.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>J<!>.*
|
||||
import a.A.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>CO<!>.*
|
||||
import a.A.CO
|
||||
|
||||
import a.B.C.*
|
||||
import a.B.C.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>A<!>.*
|
||||
import a.B.C.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>D<!>.*
|
||||
|
||||
import a.E.*
|
||||
import a.E.E1
|
||||
import a.E.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>E2<!>.*
|
||||
|
||||
class A {
|
||||
object C {
|
||||
object G
|
||||
}
|
||||
object D {
|
||||
|
||||
}
|
||||
|
||||
class E {
|
||||
object J
|
||||
}
|
||||
|
||||
class object CO {
|
||||
object H
|
||||
}
|
||||
}
|
||||
|
||||
enum class E {
|
||||
E1 E2
|
||||
}
|
||||
|
||||
object B {
|
||||
class C {
|
||||
object A
|
||||
object D
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package
|
||||
|
||||
package a {
|
||||
|
||||
internal 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
|
||||
|
||||
internal object C {
|
||||
private 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
|
||||
|
||||
internal object G {
|
||||
private constructor G()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
internal class object CO {
|
||||
private constructor CO()
|
||||
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
|
||||
|
||||
internal object H {
|
||||
private constructor H()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
internal object D {
|
||||
private 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
|
||||
}
|
||||
|
||||
internal final class E {
|
||||
public constructor E()
|
||||
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
|
||||
|
||||
internal object J {
|
||||
private constructor J()
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object B {
|
||||
private 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
|
||||
|
||||
internal final class C {
|
||||
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
|
||||
|
||||
internal object A {
|
||||
private 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
|
||||
}
|
||||
|
||||
internal object D {
|
||||
private 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal final enum class E : kotlin.Enum<a.E> {
|
||||
public enum entry E1 : a.E {
|
||||
private constructor E1()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: a.E): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry E2 : a.E {
|
||||
private constructor E2()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: a.E): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor E()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: a.E): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): a.E
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<a.E>
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
package c
|
||||
|
||||
import c.A.*
|
||||
import c.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.*
|
||||
import c.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>M<!>.*
|
||||
|
||||
fun foo() {
|
||||
val <!UNUSED_VARIABLE!>b<!>: B = B()
|
||||
|
||||
@@ -2,18 +2,18 @@ package d
|
||||
|
||||
//import from objects before properties resolve
|
||||
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>A<!>.*
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>R<!>
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>R<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>bar<!>
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>T<!>
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>Y<!>
|
||||
import d.<!CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON!>A<!>.*
|
||||
import d.M.R
|
||||
import d.M.R.<!CANNOT_BE_IMPORTED!>bar<!>
|
||||
import d.M.T
|
||||
import d.M.Y
|
||||
|
||||
var r: T = <!UNRESOLVED_REFERENCE!>T<!>()
|
||||
val y: T = <!UNRESOLVED_REFERENCE!>Y<!>
|
||||
var r: T = T()
|
||||
val y: T = Y
|
||||
|
||||
fun f() {
|
||||
<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
<!UNRESOLVED_REFERENCE!>R<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>bar<!>()
|
||||
R.bar()
|
||||
<!UNRESOLVED_REFERENCE!>B<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>foo<!>()
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ object N {
|
||||
//FILE:b.kt
|
||||
package b
|
||||
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>N<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>M<!>
|
||||
import b.N.M
|
||||
import b.A.P
|
||||
import b.A.B
|
||||
|
||||
@@ -45,7 +45,7 @@ fun foo() {
|
||||
|
||||
P.foo()
|
||||
|
||||
<!UNRESOLVED_REFERENCE!>M<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>bar<!>()
|
||||
M.bar()
|
||||
}
|
||||
|
||||
class A() {
|
||||
|
||||
@@ -5209,6 +5209,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/RenameOnImport.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("StarImportFromObject.kt")
|
||||
public void testStarImportFromObject() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/StarImportFromObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/incompleteCode")
|
||||
|
||||
Reference in New Issue
Block a user