diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index e9c3c0fbacd..f91d60fb6de 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -96,6 +96,9 @@ public interface BindingContext { WritableSlice REFERENCE_TARGET = new BasicWritableSlice(DO_NOTHING); + // if 'A' really means 'A.Default' then this slice stores class descriptor for A, REFERENCE_TARGET stores descriptor Default in this case + WritableSlice SHORT_REFERENCE_TO_DEFAULT_OBJECT = + new BasicWritableSlice(DO_NOTHING); @KotlinSignature("val RESOLVED_CALL: WritableSlice>") WritableSlice> RESOLVED_CALL = new BasicWritableSlice>(DO_NOTHING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TracingStrategyImpl.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TracingStrategyImpl.java index 7a1cfce657b..7dc05129cc9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TracingStrategyImpl.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TracingStrategyImpl.java @@ -58,7 +58,11 @@ public class TracingStrategyImpl extends AbstractTracingStrategy { descriptor = ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall().getCandidateDescriptor(); } if (descriptor instanceof FakeCallableDescriptorForObject) { - descriptor = ((FakeCallableDescriptorForObject) descriptor).getReferencedDescriptor(); + FakeCallableDescriptorForObject fakeCallableDescriptorForObject = (FakeCallableDescriptorForObject) descriptor; + descriptor = fakeCallableDescriptorForObject.getReferencedDescriptor(); + if (fakeCallableDescriptorForObject.getClassDescriptor().getDefaultObjectDescriptor() != null) { + trace.record(SHORT_REFERENCE_TO_DEFAULT_OBJECT, reference, fakeCallableDescriptorForObject.getClassDescriptor()); + } } DeclarationDescriptor storedReference = trace.get(REFERENCE_TARGET, reference); if (storedReference == null || !ErrorUtils.isError(descriptor)) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt index 4bb4de410ea..49152690123 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt @@ -30,7 +30,7 @@ import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.resolve.descriptorUtil.getClassObjectReferenceTarget public class FakeCallableDescriptorForObject( - private val classDescriptor: ClassDescriptor + public val classDescriptor: ClassDescriptor ) : DeclarationDescriptorWithVisibility by classDescriptor.getClassObjectReferenceTarget(), VariableDescriptor { { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/Qualifier.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/Qualifier.kt index 8b41c42e97a..7527f7caed8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/Qualifier.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/Qualifier.kt @@ -148,11 +148,14 @@ private fun QualifierReceiver.resolveAsReceiverInQualifiedExpression(context: Ex } private fun QualifierReceiver.resolveAndRecordReferenceTarget(context: ExpressionTypingContext, selector: DeclarationDescriptor?) { - resultingDescriptor = resolveReferenceTarget(selector) + resultingDescriptor = resolveReferenceTarget(context, selector) context.trace.record(REFERENCE_TARGET, referenceExpression, resultingDescriptor) } -private fun QualifierReceiver.resolveReferenceTarget(selector: DeclarationDescriptor?): DeclarationDescriptor { +private fun QualifierReceiver.resolveReferenceTarget( + context: ExpressionTypingContext, + selector: DeclarationDescriptor? +): DeclarationDescriptor { if (classifier is TypeParameterDescriptor) { return classifier } @@ -168,6 +171,9 @@ private fun QualifierReceiver.resolveReferenceTarget(selector: DeclarationDescri } if (classifier is ClassDescriptor && classifier.classObjectDescriptor == selectorContainer) { + if (classifier.getDefaultObjectDescriptor() != null) { + context.trace.record(SHORT_REFERENCE_TO_DEFAULT_OBJECT, referenceExpression, classifier) + } return classifier.getClassObjectReferenceTarget() } diff --git a/compiler/testData/diagnostics/tests/classObjects/importClassInClassObject.txt b/compiler/testData/diagnostics/tests/classObjects/importClassInClassObject.txt index 05e7722f8f9..3d3ea7b4414 100644 --- a/compiler/testData/diagnostics/tests/classObjects/importClassInClassObject.txt +++ b/compiler/testData/diagnostics/tests/classObjects/importClassInClassObject.txt @@ -1,7 +1,7 @@ package package f { - internal fun test(): f.A.B + internal fun test(): f.A.Default.B internal final class A { public constructor A() diff --git a/compiler/testData/diagnostics/tests/classObjects/nestedClassInPrivateClassObject.txt b/compiler/testData/diagnostics/tests/classObjects/nestedClassInPrivateClassObject.txt index bdb0baff154..e23758f3e95 100644 --- a/compiler/testData/diagnostics/tests/classObjects/nestedClassInPrivateClassObject.txt +++ b/compiler/testData/diagnostics/tests/classObjects/nestedClassInPrivateClassObject.txt @@ -1,6 +1,6 @@ package -internal fun f1(): A.B.C.Default +internal fun f1(): A.Default.B.C.Default internal fun f2(): kotlin.Unit internal final class A { diff --git a/compiler/testData/diagnostics/tests/enum/inner/insideClassObject.txt b/compiler/testData/diagnostics/tests/enum/inner/insideClassObject.txt index fa99875489d..583ba64eb9b 100644 --- a/compiler/testData/diagnostics/tests/enum/inner/insideClassObject.txt +++ b/compiler/testData/diagnostics/tests/enum/inner/insideClassObject.txt @@ -12,10 +12,10 @@ internal final class A { 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 { - public enum entry ENTRY : A.E { + internal final enum class E : kotlin.Enum { + public enum entry ENTRY : A.Default.E { private constructor ENTRY() - public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.E): kotlin.Int + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.Default.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 @@ -24,7 +24,7 @@ internal final class A { } private constructor E() - public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.E): kotlin.Int + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.Default.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 @@ -32,8 +32,8 @@ internal final class A { 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 + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): A.Default.E + public final /*synthesized*/ fun values(): kotlin.Array } } } diff --git a/compiler/testData/diagnostics/tests/enum/inner/redeclarationInClassObject.txt b/compiler/testData/diagnostics/tests/enum/inner/redeclarationInClassObject.txt index eedefe3f321..03d656f6d1e 100644 --- a/compiler/testData/diagnostics/tests/enum/inner/redeclarationInClassObject.txt +++ b/compiler/testData/diagnostics/tests/enum/inner/redeclarationInClassObject.txt @@ -12,10 +12,10 @@ internal final class A { 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 { - public enum entry ENTRY2 : A.E { + internal final enum class E : kotlin.Enum { + public enum entry ENTRY2 : A.Default.E { private constructor ENTRY2() - public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.E): kotlin.Int + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.Default.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 @@ -24,7 +24,7 @@ internal final class A { } private constructor E() - public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.E): kotlin.Int + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.Default.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 @@ -32,8 +32,8 @@ internal final class A { 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 + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): A.Default.E + public final /*synthesized*/ fun values(): kotlin.Array } } diff --git a/compiler/testData/diagnostics/tests/enum/inner/twoEnumsInClassObjectAndInnerClass.txt b/compiler/testData/diagnostics/tests/enum/inner/twoEnumsInClassObjectAndInnerClass.txt index eb0f22915a1..bcd72307232 100644 --- a/compiler/testData/diagnostics/tests/enum/inner/twoEnumsInClassObjectAndInnerClass.txt +++ b/compiler/testData/diagnostics/tests/enum/inner/twoEnumsInClassObjectAndInnerClass.txt @@ -43,10 +43,10 @@ internal final class A { 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 { - public enum entry ENTRY : A.E { + internal final enum class E : kotlin.Enum { + public enum entry ENTRY : A.Default.E { private constructor ENTRY() - public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.E): kotlin.Int + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.Default.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 @@ -55,7 +55,7 @@ internal final class A { } private constructor E() - public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.E): kotlin.Int + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A.Default.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 @@ -63,8 +63,8 @@ internal final class A { 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 + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): A.Default.E + public final /*synthesized*/ fun values(): kotlin.Array } } } diff --git a/compiler/testData/diagnostics/tests/imports/Imports.txt b/compiler/testData/diagnostics/tests/imports/Imports.txt index bd469c4d99b..19b517e81b1 100644 --- a/compiler/testData/diagnostics/tests/imports/Imports.txt +++ b/compiler/testData/diagnostics/tests/imports/Imports.txt @@ -81,8 +81,8 @@ package c { } package d { - internal val b: d.A.B - internal val c: d.A.B + internal val b: d.A.Default.B + internal val c: d.A.Default.B internal final class A { public constructor A() @@ -103,7 +103,7 @@ package d { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } - internal object C : d.A.B { + internal object C : d.A.Default.B { 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 diff --git a/compiler/testData/diagnostics/tests/inner/selfAnnotationForClassObject.txt b/compiler/testData/diagnostics/tests/inner/selfAnnotationForClassObject.txt index ce3ab1010a9..fca99511db7 100644 --- a/compiler/testData/diagnostics/tests/inner/selfAnnotationForClassObject.txt +++ b/compiler/testData/diagnostics/tests/inner/selfAnnotationForClassObject.txt @@ -6,7 +6,7 @@ internal final class Test { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - Test.ClassObjectAnnotation() Test.NestedAnnotation() internal class object Default { + Test.Default.ClassObjectAnnotation() Test.NestedAnnotation() internal class object Default { private constructor Default() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int diff --git a/compiler/testData/diagnostics/tests/multimodule/duplicateClass/duplicateNestedClasses.kt b/compiler/testData/diagnostics/tests/multimodule/duplicateClass/duplicateNestedClasses.kt index 8075ccc506a..27221f8e8db 100644 --- a/compiler/testData/diagnostics/tests/multimodule/duplicateClass/duplicateNestedClasses.kt +++ b/compiler/testData/diagnostics/tests/multimodule/duplicateClass/duplicateNestedClasses.kt @@ -64,5 +64,5 @@ fun test(m1: M1) { d(m1.d) e(m1.e) f(m1.f) - g(m1.g) + g(m1.g) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/multimodule/duplicateClass/duplicateNestedClasses.txt b/compiler/testData/diagnostics/tests/multimodule/duplicateClass/duplicateNestedClasses.txt index a57af5731ce..8edcd908c75 100644 --- a/compiler/testData/diagnostics/tests/multimodule/duplicateClass/duplicateNestedClasses.txt +++ b/compiler/testData/diagnostics/tests/multimodule/duplicateClass/duplicateNestedClasses.txt @@ -64,10 +64,10 @@ package p { public final val a: p.A public final val b: p.A.B public final val c: p.A.C - public final val d: p.A.D - public final val e: p.A.D.E + public final val d: p.A.Default.D + public final val e: p.A.Default.D.E public final val f: p.A.F - public final val g: p.A.G + public final val g: p.A.Default.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 @@ -82,8 +82,8 @@ package p { public fun a(/*0*/ p: p.A): kotlin.Unit public fun b(/*0*/ p: p.A.B): kotlin.Unit public fun c(/*0*/ p: p.A.C): kotlin.Unit - public fun d(/*0*/ p: p.A.D): kotlin.Unit - public fun e(/*0*/ p: p.A.D.E): kotlin.Unit + public fun d(/*0*/ p: p.A.Default.D): kotlin.Unit + public fun e(/*0*/ p: p.A.Default.D.E): kotlin.Unit public fun f(/*0*/ p: p.A.F): kotlin.Unit public fun g(/*0*/ p: p.A.G): kotlin.Unit @@ -154,8 +154,8 @@ package p { public fun a(/*0*/ p: p.A): kotlin.Unit public fun b(/*0*/ p: p.A.B): kotlin.Unit public fun c(/*0*/ p: p.A.C): kotlin.Unit - public fun d(/*0*/ p: p.A.D): kotlin.Unit - public fun e(/*0*/ p: p.A.D.E): kotlin.Unit + public fun d(/*0*/ p: p.A.Default.D): kotlin.Unit + public fun e(/*0*/ p: p.A.Default.D.E): kotlin.Unit public fun f(/*0*/ p: p.A.F): kotlin.Unit public fun g(/*0*/ p: p.A.G): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/regressions/kt394.txt b/compiler/testData/diagnostics/tests/regressions/kt394.txt index 31453a6ee1a..0d980ab69f5 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt394.txt +++ b/compiler/testData/diagnostics/tests/regressions/kt394.txt @@ -2,7 +2,7 @@ package internal final class X { public constructor X() - internal final val y: X.Y + internal final val y: X.Default.Y 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/scopes/kt587.txt b/compiler/testData/diagnostics/tests/scopes/kt587.txt index 6f6987cf904..cbc53fd71a9 100644 --- a/compiler/testData/diagnostics/tests/scopes/kt587.txt +++ b/compiler/testData/diagnostics/tests/scopes/kt587.txt @@ -20,7 +20,7 @@ internal final class Main { internal class object Default { private constructor Default() - public final val N: Main.States + public final val N: Main.Default.States 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/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.txt b/compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.txt index 05cdc21fc67..8b93de1706e 100644 --- a/compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.txt +++ b/compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.txt @@ -20,6 +20,6 @@ internal final class A { } } -test.A.Anno1() test.A.B.Anno2() internal final class C { +test.A.Default.Anno1() test.A.Default.B.Anno2() internal final class C { /*primary*/ public constructor C() } diff --git a/compiler/testData/loadJava/compiledKotlin/fromLoadJava/classObjectAnnotation.txt b/compiler/testData/loadJava/compiledKotlin/fromLoadJava/classObjectAnnotation.txt index 3eb84564ffb..2dfae0b1d83 100644 --- a/compiler/testData/loadJava/compiledKotlin/fromLoadJava/classObjectAnnotation.txt +++ b/compiler/testData/loadJava/compiledKotlin/fromLoadJava/classObjectAnnotation.txt @@ -3,7 +3,7 @@ package test internal final class Some { /*primary*/ public constructor Some() - test.Some.TestAnnotation() internal class object Default { + test.Some.Default.TestAnnotation() internal class object Default { /*primary*/ private constructor Default() internal final annotation class TestAnnotation : kotlin.Annotation { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index f5552ad97e1..e84ee378e07 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -104,20 +104,14 @@ public class DescriptorUtils { @NotNull private static FqNameUnsafe getFqNameUnsafe(@NotNull DeclarationDescriptor descriptor) { - DeclarationDescriptor containingDeclaration = getContainingDeclarationSkippingClassObjects(descriptor); + DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); assert containingDeclaration != null : "Not package/module descriptor doesn't have containing declaration: " + descriptor; return getFqName(containingDeclaration).child(descriptor.getName()); } - @Nullable - private static DeclarationDescriptor getContainingDeclarationSkippingClassObjects(@NotNull DeclarationDescriptor descriptor) { - DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); - return isClassObject(containingDeclaration) ? containingDeclaration.getContainingDeclaration() : containingDeclaration; - } - @NotNull public static FqName getFqNameFromTopLevelClass(@NotNull DeclarationDescriptor descriptor) { - DeclarationDescriptor containingDeclaration = getContainingDeclarationSkippingClassObjects(descriptor); + DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); Name name = descriptor.getName(); if (!(containingDeclaration instanceof ClassDescriptor)) { return FqName.topLevel(name); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt index 520ebb956be..1009964c149 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt @@ -26,7 +26,7 @@ public fun ClassDescriptor.getClassObjectReferenceTarget(): ClassDescriptor = ge public fun DeclarationDescriptor.getImportableDescriptor(): DeclarationDescriptor { return when { - this is ConstructorDescriptor, DescriptorUtils.isClassObject(this) -> getContainingDeclaration()!! + this is ConstructorDescriptor -> getContainingDeclaration() this is PropertyAccessorDescriptor -> getCorrespondingProperty() else -> this } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ImportsUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ImportsUtils.kt index af7f488c238..41d4d0ce2e8 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ImportsUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ImportsUtils.kt @@ -19,16 +19,16 @@ package org.jetbrains.kotlin.idea.imports import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.descriptors.ConstructorDescriptor -import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.descriptors.PackageViewDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.psi.JetSimpleNameExpression import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression import com.intellij.psi.PsiElement import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.* public val DeclarationDescriptor.importableFqName: FqName? get() { @@ -60,3 +60,12 @@ public fun JetType.canBeReferencedViaImport(): Boolean { val descriptor = getConstructor().getDeclarationDescriptor() return descriptor != null && descriptor.canBeReferencedViaImport() } + +// for cases when class qualifier refers default object treats it like reference to class itself +public fun JetReferenceExpression.getImportableTargets(bindingContext: BindingContext): Collection { + val targets = bindingContext[BindingContext.SHORT_REFERENCE_TO_DEFAULT_OBJECT, this]?.let { listOf(it) } + ?: bindingContext[BindingContext.REFERENCE_TARGET, this]?.let { listOf(it) } + ?: bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, this] + ?: listOf() + return targets.map { it.getImportableDescriptor() }.toSet() +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt index edd513b7ab3..b57a68b9710 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt @@ -16,14 +16,11 @@ package org.jetbrains.kotlin.idea.util -import com.intellij.psi.PsiElement; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.renderer.DescriptorRenderer; import com.intellij.psi.util.PsiTreeUtil import com.intellij.openapi.util.TextRange -import com.intellij.psi.PsiDocumentManager import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.analyzer.analyzeInContext import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny @@ -41,6 +38,8 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver import org.jetbrains.kotlin.idea.util.ShortenReferences.Options import org.jetbrains.kotlin.idea.imports.* +import org.jetbrains.kotlin.resolve.* +import com.intellij.psi.* public class ShortenReferences(val options: (JetElement) -> Options = { Options.DEFAULT }) { public data class Options( @@ -51,19 +50,14 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. val DEFAULT = Options() } } - + class object { val DEFAULT = ShortenReferences() private fun DeclarationDescriptor.asString() = DescriptorRenderer.FQ_NAMES_IN_TYPES.render(this) - private fun JetReferenceExpression.targets(context: BindingContext): Collection { - val targets = context[BindingContext.REFERENCE_TARGET, this]?.let { listOf(it) } - ?: context[BindingContext.AMBIGUOUS_REFERENCE_TARGET, this] - ?: listOf() - return targets.map { it.getImportableDescriptor() }.toSet() - } + private fun JetReferenceExpression.targets(context: BindingContext) = getImportableTargets(context) private fun mayImport(descriptor: DeclarationDescriptor, file: JetFile): Boolean { return descriptor.canBeReferencedViaImport() @@ -152,10 +146,11 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. while (true) { // Visitor order is important here so that enclosing elements are not shortened before their children are, e.g. // test.foo(this@A) -> foo(this) - val visitors = listOf( + val visitors: List> = listOf( ShortenTypesVisitor(file, elementFilter, failedToImportDescriptors), ShortenThisExpressionsVisitor(file, elementFilter, failedToImportDescriptors), - ShortenQualifiedExpressionsVisitor(file, elementFilter, failedToImportDescriptors) + ShortenQualifiedExpressionsVisitor(file, elementFilter, failedToImportDescriptors), + RemoveExplicitDefaultObjectReferenceVisitor(file, elementFilter, failedToImportDescriptors) ) val descriptorsToImport = visitors.flatMap { analyzeReferences(elementsToUse, it) }.toSet() visitors.forEach { it.shortenElements(elementsToUse) } @@ -201,7 +196,7 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. protected val failedToImportDescriptors: Set ) : JetVisitorVoid() { var options: Options = Options.DEFAULT - + private val elementsToShorten = ArrayList() private val descriptorsToImport = LinkedHashSet() @@ -209,7 +204,7 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. protected fun processQualifiedElement(element: T, target: DeclarationDescriptor, canShortenNow: Boolean) { if (canShortenNow) { - elementsToShorten.add(element) + addElementToShorten(element) } else if (target !in failedToImportDescriptors && mayImport(target, file)) { descriptorsToImport.add(target) @@ -219,6 +214,10 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. } } + protected fun addElementToShorten(element: T) { + elementsToShorten.add(element) + } + protected abstract fun qualifier(element: T): JetElement protected abstract fun shortenElement(element: T): JetElement @@ -257,7 +256,7 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. if (filterResult == FilterResult.PROCESS) { processType(userType) } - else{ + else { userType.getQualifier()?.accept(this) } } @@ -286,12 +285,11 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. } } - private class ShortenQualifiedExpressionsVisitor( + private abstract class QualifiedExpressionShorteningVisitor( file: JetFile, elementFilter: (PsiElement) -> FilterResult, failedToImportDescriptors: Set - ) : ShorteningVisitor(file, elementFilter, failedToImportDescriptors) { - + ) : ShorteningVisitor(file, elementFilter, failedToImportDescriptors) { override fun visitDotQualifiedExpression(expression: JetDotQualifiedExpression) { val filterResult = elementFilter(expression) if (filterResult == FilterResult.SKIP) return @@ -305,7 +303,18 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. expression.getReceiverExpression().accept(this) } - private fun process(qualifiedExpression: JetDotQualifiedExpression): Boolean { + abstract fun process(qualifiedExpression: JetDotQualifiedExpression): Boolean + + override fun qualifier(element: JetDotQualifiedExpression) = element.getReceiverExpression() + } + + private class ShortenQualifiedExpressionsVisitor( + file: JetFile, + elementFilter: (PsiElement) -> FilterResult, + failedToImportDescriptors: Set + ) : QualifiedExpressionShorteningVisitor(file, elementFilter, failedToImportDescriptors) { + + override fun process(qualifiedExpression: JetDotQualifiedExpression): Boolean { val bindingContext = resolutionFacade.analyze(qualifiedExpression) val receiver = qualifiedExpression.getReceiverExpression() @@ -317,7 +326,7 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. if (bindingContext[BindingContext.QUALIFIER, receiver] == null) return false } } - + if (PsiTreeUtil.getParentOfType( qualifiedExpression, javaClass(), javaClass()) != null) return true @@ -338,10 +347,10 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. val newCall = selectorCopy.getResolvedCall(newContext) ?: return false val receiverKind = originalCall.getExplicitReceiverKind() val newReceiver = when (receiverKind) { - ExplicitReceiverKind.BOTH_RECEIVERS, ExplicitReceiverKind.EXTENSION_RECEIVER -> newCall.getExtensionReceiver() - ExplicitReceiverKind.DISPATCH_RECEIVER -> newCall.getDispatchReceiver() - else -> return false - } as? ThisReceiver ?: return false + ExplicitReceiverKind.BOTH_RECEIVERS, ExplicitReceiverKind.EXTENSION_RECEIVER -> newCall.getExtensionReceiver() + ExplicitReceiverKind.DISPATCH_RECEIVER -> newCall.getDispatchReceiver() + else -> return false + } as? ThisReceiver ?: return false val thisTarget = receiver.getInstanceReference().targets(bindingContext).singleOrNull() if (newReceiver.getDeclarationDescriptor().asString() != thisTarget?.asString()) return false @@ -356,9 +365,7 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. return true } - override fun qualifier(element: JetQualifiedExpression) = element.getReceiverExpression() - - override fun shortenElement(element: JetQualifiedExpression): JetElement { + override fun shortenElement(element: JetDotQualifiedExpression): JetElement { return element.replace(element.getSelectorExpression()!!) as JetElement } } @@ -380,7 +387,7 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. val newContext = simpleThis.analyzeInContext(scope) val targetAfter = simpleThis.getInstanceReference().targets(newContext).singleOrNull() if (targetBefore == targetAfter) { - processQualifiedElement(thisExpression, targetBefore, true) + addElementToShorten(thisExpression) } } @@ -398,6 +405,51 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. } } + private class RemoveExplicitDefaultObjectReferenceVisitor( + file: JetFile, + elementFilter: (PsiElement) -> FilterResult, + failedToImportDescriptors: Set + ) : QualifiedExpressionShorteningVisitor(file, elementFilter, failedToImportDescriptors) { + + private fun JetExpression.singleTarget(context: BindingContext): DeclarationDescriptor? { + return (getCalleeExpressionIfAny() as? JetReferenceExpression)?.targets(context)?.singleOrNull() + } + + override fun process(qualifiedExpression: JetDotQualifiedExpression): Boolean { + val bindingContext = resolutionFacade.analyze(qualifiedExpression) + + val receiver = qualifiedExpression.getReceiverExpression() + + if (PsiTreeUtil.getParentOfType( + qualifiedExpression, + javaClass(), javaClass()) != null) return false + + val receiverTarget = receiver.singleTarget(bindingContext) ?: return false + if (receiverTarget !is ClassDescriptor) return false + + val selectorExpression = qualifiedExpression.getSelectorExpression() ?: return false + val selectorTarget = selectorExpression.singleTarget(bindingContext) ?: return false + + if (receiverTarget.getDefaultObjectDescriptor() != selectorTarget) return false + + val selectorsSelector = (qualifiedExpression.getParent() as? JetDotQualifiedExpression)?.getSelectorExpression() + if (selectorsSelector == null) { + addElementToShorten(qualifiedExpression) + return true + } + + val selectorsSelectorTarget = selectorsSelector.singleTarget(bindingContext) ?: return false + if (selectorsSelectorTarget is ClassDescriptor) return false + + addElementToShorten(qualifiedExpression) + return true + } + + override fun shortenElement(element: JetDotQualifiedExpression): JetElement { + return element.replace(element.getReceiverExpression()) as JetElement + } + } + // this class is needed to optimize imports only when we actually insert any import (optimization) private class ImportInserter(val file: JetFile) { private var optimizeImports = true diff --git a/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt b/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt index 77495c377c5..1d80ee33be1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PackageViewDescriptor -import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.formatter.JetCodeStyleSettings import org.jetbrains.kotlin.idea.references.JetReference import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers @@ -36,13 +35,13 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression import org.jetbrains.kotlin.psi.psiUtil.isAncestor -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -import org.jetbrains.kotlin.resolve.ImportPath import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import java.util.ArrayList import java.util.HashMap import java.util.HashSet +import org.jetbrains.kotlin.idea.caches.resolve.* +import org.jetbrains.kotlin.resolve.* public class KotlinImportOptimizer() : ImportOptimizer { @@ -182,12 +181,19 @@ public class KotlinImportOptimizer() : ImportOptimizer { override fun visitPackageDirective(directive: JetPackageDirective) { } + + private fun JetElement.classForDefaultObjectReference(): ClassDescriptor? { + return analyze()[BindingContext.SHORT_REFERENCE_TO_DEFAULT_OBJECT, this as? JetReferenceExpression] + } + override fun visitJetElement(element: JetElement) { val reference = element.getReference() if (reference is JetReference) { val referencedName = (element as? JetNameReferenceExpression)?.getReferencedNameAsName() //TODO: other types of references - val targets = reference.resolveToDescriptors() + //class qualifiers that refer to default objects should be considered (containing) class references + val targets = element.classForDefaultObjectReference()?.let { listOf(it) } + ?: reference.resolveToDescriptors() for (target in targets) { if (!target.canBeReferencedViaImport()) continue if (target is PackageViewDescriptor && target.getFqName().parent() == FqName.ROOT) continue // no need to import top-level packages diff --git a/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt b/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt index 09ecf1b17a5..0574a497c8a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt +++ b/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt @@ -39,8 +39,6 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered import org.jetbrains.kotlin.descriptors.ClassifierDescriptor -import org.jetbrains.kotlin.idea.imports.importableFqName -import org.jetbrains.kotlin.idea.imports.importableFqNameSafe import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.descriptors.ModuleDescriptor @@ -54,6 +52,7 @@ import org.jetbrains.kotlin.idea.util.ImportInsertHelper.ImportDescriptorResult import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.idea.refactoring.fqName.isImported import java.util.* +import org.jetbrains.kotlin.idea.imports.* public class ImportInsertHelperImpl(private val project: Project) : ImportInsertHelper() { @@ -374,10 +373,7 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert } private fun JetReferenceExpression.resolveTargets(): Collection { - val bindingContext = resolutionFacade.analyze(this, BodyResolveMode.PARTIAL) - return bindingContext[BindingContext.REFERENCE_TARGET, this]?.let { listOf(it) } - ?: bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, this] - ?: return listOf() + return this.getImportableTargets(resolutionFacade.analyze(this, BodyResolveMode.PARTIAL)) } private fun addImport(fqName: FqName, allUnder: Boolean): JetImportDirective { diff --git a/idea/testData/copyPaste/imports/ClassObject.expected.kt b/idea/testData/copyPaste/imports/ClassObject.expected.kt index d9146d8e4de..bb467d4cf2f 100644 --- a/idea/testData/copyPaste/imports/ClassObject.expected.kt +++ b/idea/testData/copyPaste/imports/ClassObject.expected.kt @@ -7,4 +7,8 @@ import a.T fun g(t: T): Int { g(A) B.f() + A + B + A.Default + B.Default } \ No newline at end of file diff --git a/idea/testData/copyPaste/imports/ClassObject.kt b/idea/testData/copyPaste/imports/ClassObject.kt index 77bcbe0f9a7..945042da459 100644 --- a/idea/testData/copyPaste/imports/ClassObject.kt +++ b/idea/testData/copyPaste/imports/ClassObject.kt @@ -16,6 +16,10 @@ class B { fun g(t: T): Int { g(A) B.f() + A + B + A.Default + B.Default } diff --git a/idea/testData/copyPaste/imports/ClassObjectInner.expected.kt b/idea/testData/copyPaste/imports/ClassObjectInner.expected.kt index 70f5baa69eb..76f3ce9c1c9 100644 --- a/idea/testData/copyPaste/imports/ClassObjectInner.expected.kt +++ b/idea/testData/copyPaste/imports/ClassObjectInner.expected.kt @@ -2,5 +2,5 @@ package to import a.Outer -fun f(i: Outer.Inner, n: Outer.Nested, e: Outer.NestedEnum, o: Outer.NestedObj, t: Outer.NestedTrait, a: Outer.NestedAnnotation) { +fun f(n: Outer.Default.Nested, e: Outer.Default.NestedEnum, o: Outer.Default.NestedObj, t: Outer.Default.NestedTrait, a: Outer.Default.NestedAnnotation) { } \ No newline at end of file diff --git a/idea/testData/copyPaste/imports/ClassObjectInner.kt b/idea/testData/copyPaste/imports/ClassObjectInner.kt index e3dcb57870a..8edb31eeadd 100644 --- a/idea/testData/copyPaste/imports/ClassObjectInner.kt +++ b/idea/testData/copyPaste/imports/ClassObjectInner.kt @@ -1,11 +1,13 @@ package a -import a.Outer.* +import a.Outer.Default.Nested +import a.Outer.Default.NestedEnum +import a.Outer.Default.NestedObj +import a.Outer.Default.NestedTrait +import a.Outer.Default.NestedAnnotation class Outer { class object { - inner class Inner { - } class Nested { } enum class NestedEnum { @@ -18,5 +20,5 @@ class Outer { } } -fun f(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) { +fun f(n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) { } \ No newline at end of file diff --git a/idea/testData/diagnosticMessage/nestedClassShouldBeQualified3.txt b/idea/testData/diagnosticMessage/nestedClassShouldBeQualified3.txt index 5f6d147ef98..4ee0498f173 100644 --- a/idea/testData/diagnosticMessage/nestedClassShouldBeQualified3.txt +++ b/idea/testData/diagnosticMessage/nestedClassShouldBeQualified3.txt @@ -1,2 +1,2 @@ -Nested class 'Nested' should be qualified as 'C.D.Nested' \ No newline at end of file +Nested class 'Nested' should be qualified as 'C.Default.D.Nested' \ No newline at end of file diff --git a/idea/testData/diagnosticMessage/nestedClassShouldBeQualified4.txt b/idea/testData/diagnosticMessage/nestedClassShouldBeQualified4.txt index 2fae93db633..6b0d2a80c71 100644 --- a/idea/testData/diagnosticMessage/nestedClassShouldBeQualified4.txt +++ b/idea/testData/diagnosticMessage/nestedClassShouldBeQualified4.txt @@ -1,2 +1,2 @@ -Nested class 'Nested' should be qualified as 'C.D::Nested' \ No newline at end of file +Nested class 'Nested' should be qualified as 'C.Default.D::Nested' \ No newline at end of file diff --git a/idea/testData/diagnosticMessage/nestedClassShouldBeQualified5.txt b/idea/testData/diagnosticMessage/nestedClassShouldBeQualified5.txt index d662eec3e52..6a7d0009c45 100644 --- a/idea/testData/diagnosticMessage/nestedClassShouldBeQualified5.txt +++ b/idea/testData/diagnosticMessage/nestedClassShouldBeQualified5.txt @@ -1,2 +1,2 @@ -Nested class object of 'F' should be qualified as 'E.F' \ No newline at end of file +Nested class object of 'F' should be qualified as 'E.F.Default' \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/DefaultObjectReference.dependency.kt b/idea/testData/editor/optimizeImports/DefaultObjectReference.dependency.kt new file mode 100644 index 00000000000..b1ad51eec1b --- /dev/null +++ b/idea/testData/editor/optimizeImports/DefaultObjectReference.dependency.kt @@ -0,0 +1,13 @@ +package d + +class A { + class object E { + val c: Int + } +} + +class B { + class object F { + val c: Int + } +} \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/DefaultObjectReference.kt b/idea/testData/editor/optimizeImports/DefaultObjectReference.kt new file mode 100644 index 00000000000..d9ea86c295e --- /dev/null +++ b/idea/testData/editor/optimizeImports/DefaultObjectReference.kt @@ -0,0 +1,11 @@ +package p + +import d.A +import d.A.E +import d.B.F +import d.B + +fun main(args: Array) { + F.c + A.c +} \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/DefaultObjectReference.kt.after b/idea/testData/editor/optimizeImports/DefaultObjectReference.kt.after new file mode 100644 index 00000000000..9fed98bd089 --- /dev/null +++ b/idea/testData/editor/optimizeImports/DefaultObjectReference.kt.after @@ -0,0 +1,9 @@ +package p + +import d.A +import d.B.F + +fun main(args: Array) { + F.c + A.c +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/privateMemberInClassObject.kt.conflicts b/idea/testData/refactoring/extractFunction/basic/privateMemberInClassObject.kt.conflicts index cd10b5c7925..8aabc42af8a 100644 --- a/idea/testData/refactoring/extractFunction/basic/privateMemberInClassObject.kt.conflicts +++ b/idea/testData/refactoring/extractFunction/basic/privateMemberInClassObject.kt.conflicts @@ -1 +1 @@ -Property A.t will become invisible after extraction \ No newline at end of file +Property A.Default.t will become invisible after extraction \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/after/source/Foo.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/after/source/Foo.kt index daeab71966c..b44781436e9 100644 --- a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/after/source/Foo.kt +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/after/source/Foo.kt @@ -3,5 +3,7 @@ package source import library.* class Bar { - + class object { + val c : Int + } } \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/after/target/Foo.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/after/target/Foo.kt index 545ab700bca..493bc989933 100644 --- a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/after/target/Foo.kt +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/after/target/Foo.kt @@ -3,6 +3,7 @@ package target import library.JavaClass import library.KtClass import library.KtObject +import source.Bar class Foo { val jv1 = JavaClass.foo() @@ -13,4 +14,11 @@ class Foo { val kt2 = KtObject.foo() val kt3 = KtClass.Inner.foo() val kt4 = KtObject.Inner.foo() + val kt5 = KtClass.foo() + val kt6 = KtClass + val kt7 = KtClass + + val kt8 = Bar + val kt9 = Bar + val kt10 = Bar.c } \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/before/source/Foo.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/before/source/Foo.kt index 53b18972c6b..ef43945e943 100644 --- a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/before/source/Foo.kt +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/before/source/Foo.kt @@ -11,8 +11,17 @@ class Foo { val kt2 = KtObject.foo() val kt3 = KtClass.Inner.foo() val kt4 = KtObject.Inner.foo() + val kt5 = KtClass.Default.foo() + val kt6 = KtClass.Default + val kt7 = KtClass + + val kt8 = Bar + val kt9 = Bar.Default + val kt10 = Bar.Default.c } class Bar { - + class object { + val c : Int + } } \ No newline at end of file diff --git a/idea/testData/shortenRefs/classObject.kt b/idea/testData/shortenRefs/classObject.kt index 6cacac6fee7..013fa3172ef 100644 --- a/idea/testData/shortenRefs/classObject.kt +++ b/idea/testData/shortenRefs/classObject.kt @@ -1,16 +1,34 @@ package p.q -fun foo(): Int { +fun foo(myC: p.q.MyClass, def: p.q.MyClass.Default, nes: p.q.MyClass.Default.Nested) { + p.q.MyClass.Default.foo() + p.q.MyClass.Default.coProp + p.q.MyClass.Default + p.q.MyClass + p.q.MyClass.coProp p.q.MyClass.foo() - return p.q.MyClass.coProp + 10 + p.q.MyClass.bar(p.q.MyClass.Default) + p.q.MyClass.bar(p.q.MyClass) + p.q.MyClass.Default.Nested.Default + p.q.MyClass.Default.Nested.Default.c + MyClass.Default } class MyClass { class object { val coProp = 1 + class Nested { + class object { + val c: Int = 1 + } + } + fun foo() { } + + fun bar(p: MyClass.Default) { + } } } \ No newline at end of file diff --git a/idea/testData/shortenRefs/classObject.kt.after b/idea/testData/shortenRefs/classObject.kt.after index 74dbf912285..5425f4f920b 100644 --- a/idea/testData/shortenRefs/classObject.kt.after +++ b/idea/testData/shortenRefs/classObject.kt.after @@ -1,16 +1,34 @@ package p.q -fun foo(): Int { +fun foo(myC: MyClass, def: MyClass.Default, nes: MyClass.Default.Nested) { MyClass.foo() - return MyClass.coProp + 10 + MyClass.coProp + MyClass + MyClass + MyClass.coProp + MyClass.foo() + MyClass.bar(MyClass) + MyClass.bar(MyClass) + MyClass.Default.Nested + MyClass.Default.Nested.c + MyClass } class MyClass { class object { val coProp = 1 + class Nested { + class object { + val c: Int = 1 + } + } + fun foo() { } + + fun bar(p: MyClass.Default) { + } } } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java index 0abf001a862..8945a048f70 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java @@ -75,6 +75,12 @@ public class OptimizeImportsTestGenerated extends AbstractOptimizeImportsTest { doTest(fileName); } + @TestMetadata("DefaultObjectReference.kt") + public void testDefaultObjectReference() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/optimizeImports/DefaultObjectReference.kt"); + doTest(fileName); + } + @TestMetadata("DuplicatedImports.kt") public void testDuplicatedImports() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/optimizeImports/DuplicatedImports.kt");