diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/NewQualifiedExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/NewQualifiedExpressionResolver.kt index 975335a08c4..f3fa182396b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/NewQualifiedExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/NewQualifiedExpressionResolver.kt @@ -24,9 +24,12 @@ import org.jetbrains.kotlin.incremental.KotlinLookupLocation import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.JetScope +import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue +import org.jetbrains.kotlin.resolve.scopes.utils.getClassifier import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator import org.jetbrains.kotlin.utils.addIfNotNull @@ -43,11 +46,73 @@ public class NewQualifiedExpressionResolver(val symbolUsageValidator: SymbolUsag } } + public fun resolveDescriptorForUserType( + userType: JetUserType, + scope: LexicalScope, + trace: BindingTrace + ): ClassifierDescriptor? { + if (userType.qualifier == null) { // optimization for non-qualified types + return userType.referenceExpression?.let { + val classifier = scope.getClassifier(it.getReferencedNameAsName(), KotlinLookupLocation(it)) + storageResult(trace, it, listOfNotNull(classifier), scope.ownerDescriptor) + classifier + } + } + + val module = scope.ownerDescriptor.module + val (qualifierPartList, hasError) = userType.asQualifierPartList() + if (hasError) { + resolveToPackageOrClass(qualifierPartList, module, trace, scope.ownerDescriptor) + return null + } + assert(qualifierPartList.size() > 1) { + "Too short qualifier list for user type $userType : ${qualifierPartList.joinToString()}" + } + + val qualifier = resolveToPackageOrClass( + qualifierPartList.subList(0, qualifierPartList.size() - 1), module, trace, scope.ownerDescriptor, + firstPartResolver = { + if (userType.isAbsoluteInRootPackage) { + null + } + else { + scope.getClassifier(it.name, it.location) + } + } + ) ?: return null + + val lastPart = qualifierPartList.last() + val classifier = when (qualifier) { + is PackageViewDescriptor -> qualifier.memberScope.getClassifier(lastPart.name, lastPart.location) + is ClassDescriptor -> qualifier.unsubstitutedInnerClassesScope.getClassifier(lastPart.name, lastPart.location) + else -> null + } + storageResult(trace, lastPart.expression, listOfNotNull(classifier), scope.ownerDescriptor) + return classifier + } + + private fun JetUserType.asQualifierPartList(): Pair, Boolean> { + var hasError = false + val result = SmartList() + var userType: JetUserType? = this + while (userType != null) { + val referenceExpression = userType.referenceExpression + if (referenceExpression != null) { + result add QualifierPart(referenceExpression.getReferencedNameAsName(), referenceExpression, userType.typeArgumentList) + } + else { + hasError = true + } + userType = userType.qualifier + } + return result.asReversed() to hasError + } + public fun processImportReference( importDirective: JetImportDirective, moduleDescriptor: ModuleDescriptor, trace: BindingTrace, - shouldBeVisibleFrom: DeclarationDescriptor + shouldBeVisibleFrom: DeclarationDescriptor // todo ): JetScope { val importedReference = importDirective.importedReference ?: return JetScope.Empty val path = importedReference.asQualifierPartList(trace) @@ -185,6 +250,7 @@ public class NewQualifiedExpressionResolver(val symbolUsageValidator: SymbolUsag } val (currentDescriptor, currentIndex) = firstPartResolver(path.first())?.let { + storageResult(trace, path.first().expression, listOf(it), shouldBeVisibleFrom) Pair(it, 1) } ?: moduleDescriptor.quickResolveToPackage(path, trace) return path.subList(currentIndex, path.size()).fold(currentDescriptor) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.java index 96c28164553..5254f8f3855 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.java @@ -17,26 +17,16 @@ package org.jetbrains.kotlin.resolve; import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.intellij.psi.util.PsiTreeUtil; -import org.jetbrains.annotations.Mutable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.diagnostics.Errors; -import org.jetbrains.kotlin.incremental.KotlinLookupLocation; -import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.resolve.scopes.AbstractScopeAdapter; import org.jetbrains.kotlin.resolve.scopes.JetScope; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator; import java.util.Collection; -import java.util.Collections; -import java.util.Set; import static org.jetbrains.kotlin.diagnostics.Errors.*; @@ -74,330 +64,4 @@ public class QualifiedExpressionResolver { // todo fix shouldBeVisibleFrom return newQualifiedExpressionResolver.processImportReference(importDirective, moduleDescriptor, trace, moduleDescriptor); } - - @NotNull - public Collection lookupDescriptorsForUserType( - @NotNull JetUserType userType, - @NotNull JetScope outerScope, - @NotNull BindingTrace trace, - boolean onlyClassifiers - ) { - - if (userType.isAbsoluteInRootPackage()) { - trace.report(Errors.UNSUPPORTED.on(userType, "package")); - return Collections.emptyList(); - } - - JetSimpleNameExpression referenceExpression = userType.getReferenceExpression(); - /* - if (referenceExpression == null) { - return Collections.emptyList(); - } - */ - JetUserType qualifier = userType.getQualifier(); - - // We do not want to resolve the last segment of a user type to a package - JetScope filteredScope = filterOutPackagesIfNeeded(outerScope, onlyClassifiers); - - DeclarationDescriptor shouldBeVisibleFrom = outerScope.getContainingDeclaration(); - if (qualifier == null) { - if (referenceExpression == null) return Collections.emptyList(); - return lookupDescriptorsForSimpleNameReference(referenceExpression, filteredScope, shouldBeVisibleFrom, trace, - LookupMode.ONLY_CLASSES_AND_PACKAGES, - false, true); - } - Collection declarationDescriptors = lookupDescriptorsForUserType(qualifier, outerScope, trace, false); - if (referenceExpression == null) return Collections.emptyList(); - return lookupSelectorDescriptors(referenceExpression, declarationDescriptors, trace, shouldBeVisibleFrom, - LookupMode.ONLY_CLASSES_AND_PACKAGES, true); - } - - private static JetScope filterOutPackagesIfNeeded(final JetScope outerScope, boolean noPackages) { - return !noPackages ? outerScope : new AbstractScopeAdapter() { - - @NotNull - @Override - protected JetScope getWorkerScope() { - return outerScope; - } - - @Nullable - @Override - public PackageViewDescriptor getPackage(@NotNull Name name) { - return null; - } - }; - } - - @NotNull - public Collection lookupSelectorDescriptors( - @NotNull JetSimpleNameExpression selector, - @NotNull Collection declarationDescriptors, - @NotNull BindingTrace trace, - @NotNull DeclarationDescriptor shouldBeVisibleFrom, - @NotNull LookupMode lookupMode, - boolean storeResult - ) { - Set results = Sets.newLinkedHashSet(); - for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) { - if (declarationDescriptor instanceof PackageViewDescriptor) { - results.add(lookupSimpleNameReference(selector, ((PackageViewDescriptor) declarationDescriptor).getMemberScope(), - lookupMode, true)); - } - if (declarationDescriptor instanceof ClassDescriptor) { - addResultsForClass(results, selector, lookupMode, (ClassDescriptor) declarationDescriptor); - } - } - return filterAndStoreResolutionResult(results, selector, trace, shouldBeVisibleFrom, lookupMode, storeResult); - } - - private static void addResultsForClass( - @NotNull @Mutable Set results, - @NotNull JetSimpleNameExpression selector, - @NotNull LookupMode lookupMode, - @NotNull ClassDescriptor descriptor - ) { - JetScope scope = lookupMode == LookupMode.ONLY_CLASSES_AND_PACKAGES - ? descriptor.getUnsubstitutedInnerClassesScope() - : descriptor.getDefaultType().getMemberScope(); - results.add(lookupSimpleNameReference(selector, scope, lookupMode, false)); - - results.add(lookupSimpleNameReference(selector, descriptor.getStaticScope(), lookupMode, true)); - } - - - @NotNull - @SuppressWarnings("MethodMayBeStatic") - public Collection lookupDescriptorsForSimpleNameReference( - @NotNull JetSimpleNameExpression referenceExpression, - @NotNull JetScope outerScope, - @NotNull DeclarationDescriptor shouldBeVisibleFrom, - @NotNull BindingTrace trace, - @NotNull LookupMode lookupMode, - boolean packageLevel, - boolean storeResult - ) { - LookupResult lookupResult = lookupSimpleNameReference(referenceExpression, outerScope, lookupMode, packageLevel); - return filterAndStoreResolutionResult(Collections.singletonList(lookupResult), referenceExpression, trace, shouldBeVisibleFrom, - lookupMode, storeResult); - } - - @NotNull - private static LookupResult lookupSimpleNameReference( - @NotNull JetSimpleNameExpression referenceExpression, - @NotNull JetScope outerScope, - @NotNull LookupMode lookupMode, - boolean packageLevel - ) { - Name referencedName = referenceExpression.getReferencedNameAsName(); - - Collection descriptors = Sets.newLinkedHashSet(); - PackageViewDescriptor packageDescriptor = outerScope.getPackage(referencedName); - if (packageDescriptor != null) { - descriptors.add(packageDescriptor); - } - - KotlinLookupLocation location = new KotlinLookupLocation(referenceExpression); - - ClassifierDescriptor classifierDescriptor = outerScope.getClassifier(referencedName, location); - if (classifierDescriptor != null) { - descriptors.add(classifierDescriptor); - } - - if (lookupMode == LookupMode.EVERYTHING) { - descriptors.addAll(outerScope.getFunctions(referencedName, location)); - descriptors.addAll(outerScope.getProperties(referencedName, location)); - - VariableDescriptor localVariable = outerScope.getLocalVariable(referencedName); - if (localVariable != null) { - descriptors.add(localVariable); - } - } - - return new LookupResult(descriptors, outerScope, packageLevel); - } - - @NotNull - private Collection filterAndStoreResolutionResult( - @NotNull Collection lookupResults, - @NotNull JetSimpleNameExpression referenceExpression, - @NotNull BindingTrace trace, - @NotNull DeclarationDescriptor shouldBeVisibleFrom, - @NotNull LookupMode lookupMode, - boolean storeResult - ) { - if (lookupResults.isEmpty()) { - return Collections.emptyList(); - } - - Collection descriptors = Sets.newLinkedHashSet(); - for (LookupResult lookupResult : lookupResults) { - descriptors.addAll(lookupResult.descriptors); - } - - Collection filteredDescriptors; - if (lookupMode == LookupMode.ONLY_CLASSES_AND_PACKAGES) { - filteredDescriptors = Collections2.filter(descriptors, CLASSIFIERS_AND_PACKAGE_VIEWS); - } - else { - filteredDescriptors = Sets.newLinkedHashSet(); - //functions and properties can be imported if lookupResult.packageLevel == true - for (LookupResult lookupResult : lookupResults) { - if (lookupResult.packageLevel) { - filteredDescriptors.addAll(lookupResult.descriptors); - } - else { - filteredDescriptors.addAll(Collections2.filter(lookupResult.descriptors, CLASSIFIERS_AND_PACKAGE_VIEWS)); - } - } - } - - if (storeResult) { - Collection possibleResolutionScopes = Lists.newArrayList(); - for (LookupResult lookupResult : lookupResults) { - if (!lookupResult.descriptors.isEmpty()) { - possibleResolutionScopes.add(lookupResult.resolutionScope); - } - } - if (possibleResolutionScopes.isEmpty()) { - for (LookupResult lookupResult : lookupResults) { - possibleResolutionScopes.add(lookupResult.resolutionScope); - } - } - - storeResolutionResult(descriptors, filteredDescriptors, referenceExpression, possibleResolutionScopes, trace, - shouldBeVisibleFrom); - } - - return filteredDescriptors; - } - - private void storeResolutionResult( - @NotNull Collection descriptors, - @NotNull Collection canBeImportedDescriptors, - @NotNull JetSimpleNameExpression referenceExpression, - @NotNull Collection possibleResolutionScopes, - @NotNull BindingTrace trace, - @NotNull DeclarationDescriptor shouldBeVisibleFrom - ) { - assert canBeImportedDescriptors.size() <= descriptors.size(); - assert !possibleResolutionScopes.isEmpty(); - //todo completion here needs all possible resolution scopes, if there are many - JetScope resolutionScope = possibleResolutionScopes.iterator().next(); - - // A special case - will fill all trace information - if (resolveClassPackageAmbiguity(canBeImportedDescriptors, referenceExpression, resolutionScope, trace, shouldBeVisibleFrom)) { - return; - } - - // Simple case of no descriptors - if (descriptors.isEmpty()) { - trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope); - trace.report(UNRESOLVED_REFERENCE.on(referenceExpression, referenceExpression)); - return; - } - - // Decide if expression has resolved reference - DeclarationDescriptor descriptor = null; - if (descriptors.size() == 1) { - descriptor = descriptors.iterator().next(); - assert canBeImportedDescriptors.size() <= 1; - } - else if (canBeImportedDescriptors.size() == 1) { - descriptor = canBeImportedDescriptors.iterator().next(); - } - if (descriptor != null) { - trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.iterator().next()); - trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope); - - if (descriptor instanceof ClassifierDescriptor) { - symbolUsageValidator.validateTypeUsage((ClassifierDescriptor) descriptor, trace, referenceExpression); - } - - if (descriptor instanceof DeclarationDescriptorWithVisibility) { - checkVisibility((DeclarationDescriptorWithVisibility) descriptor, trace, referenceExpression, shouldBeVisibleFrom); - } - } - - // Check for more information and additional errors - if (canBeImportedDescriptors.isEmpty()) { - assert descriptors.size() >= 1; - trace.report(CANNOT_BE_IMPORTED.on(referenceExpression, descriptors.iterator().next().getName())); - return; - } - if (canBeImportedDescriptors.size() > 1) { - trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, descriptors); - } - } - - /** - * This method tries to resolve descriptors ambiguity between class descriptor and package descriptor for the same class. - * It's ok choose class for expression reference resolution. - * - * @return true if method has successfully resolved ambiguity - */ - private static boolean resolveClassPackageAmbiguity( - @NotNull Collection filteredDescriptors, - @NotNull JetSimpleNameExpression referenceExpression, - @NotNull JetScope resolutionScope, - @NotNull BindingTrace trace, - @NotNull DeclarationDescriptor shouldBeVisibleFrom - ) { - if (filteredDescriptors.size() == 2) { - PackageViewDescriptor packageView = null; - ClassDescriptor classDescriptor = null; - - for (DeclarationDescriptor filteredDescriptor : filteredDescriptors) { - if (filteredDescriptor instanceof PackageViewDescriptor) { - packageView = (PackageViewDescriptor) filteredDescriptor; - } - else if (filteredDescriptor instanceof ClassDescriptor) { - classDescriptor = (ClassDescriptor) filteredDescriptor; - } - } - - if (packageView != null && classDescriptor != null) { - if (packageView.getFqName().equalsTo(DescriptorUtils.getFqName(classDescriptor))) { - trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, classDescriptor); - trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope); - checkVisibility(classDescriptor, trace, referenceExpression, shouldBeVisibleFrom); - return true; - } - } - } - - return false; - } - - private static void checkVisibility( - @NotNull DeclarationDescriptorWithVisibility descriptor, - @NotNull BindingTrace trace, - @NotNull JetSimpleNameExpression referenceExpression, - @NotNull DeclarationDescriptor shouldBeVisibleFrom - ) { - if (!Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, descriptor, shouldBeVisibleFrom)) { - Visibility visibility = descriptor.getVisibility(); - if (PsiTreeUtil.getParentOfType(referenceExpression, JetImportDirective.class) != null && !visibility.mustCheckInImports()) { - return; - } - //noinspection ConstantConditions - trace.report(INVISIBLE_REFERENCE.on(referenceExpression, descriptor, visibility, descriptor.getContainingDeclaration())); - } - } - - private static class LookupResult { - private final Collection descriptors; - private final JetScope resolutionScope; - private final boolean packageLevel; - - public LookupResult( - @NotNull Collection descriptors, - @NotNull JetScope resolutionScope, - boolean packageLevel - ) { - this.descriptors = descriptors; - this.resolutionScope = resolutionScope; - this.packageLevel = packageLevel; - } - } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index f2245970fb5..8e478506f5d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -44,7 +44,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull public class TypeResolver( private val annotationResolver: AnnotationResolver, - private val qualifiedExpressionResolver: QualifiedExpressionResolver, + private val qualifiedExpressionResolver: NewQualifiedExpressionResolver, private val moduleDescriptor: ModuleDescriptor, private val flexibleTypeCapabilitiesProvider: FlexibleTypeCapabilitiesProvider, private val storageManager: StorageManager, @@ -317,8 +317,7 @@ public class TypeResolver( } } - val classifierDescriptor = qualifiedExpressionResolver.lookupDescriptorsForUserType(userType, scope.asJetScope(), trace, true) - .firstIsInstanceOrNull() + val classifierDescriptor = qualifiedExpressionResolver.resolveDescriptorForUserType(userType, scope, trace) if (classifierDescriptor != null) { PlatformTypesMappedToKotlinChecker.reportPlatformClassMappedToKotlin(moduleDescriptor, trace, userType, classifierDescriptor) } diff --git a/compiler/testData/diagnostics/tests/imports/ClassClash.kt b/compiler/testData/diagnostics/tests/imports/ClassClash.kt index 7e40d56340f..810aea57d1b 100644 --- a/compiler/testData/diagnostics/tests/imports/ClassClash.kt +++ b/compiler/testData/diagnostics/tests/imports/ClassClash.kt @@ -30,6 +30,12 @@ fun test(b: B) { val b_2: B = a.B() b_2.m1() + + val b_3: B = B() + b_3.m1() + + val b_4: B = a.B() + b_4.m1() } @@ -56,6 +62,9 @@ fun test(b: B) { val b_: B = B() b_.m1() + + val b_2 = B() + b_2.m1() } // FILE: top_d.kt @@ -66,4 +75,7 @@ fun test2(b: B) { val b_: B = B() b_.m1() + + val b_2 = B() + b_2.m1() } diff --git a/compiler/testData/diagnostics/tests/imports/ClassClashStarImport.kt b/compiler/testData/diagnostics/tests/imports/ClassClashStarImport.kt index bd6b53a9532..8fd712b72c3 100644 --- a/compiler/testData/diagnostics/tests/imports/ClassClashStarImport.kt +++ b/compiler/testData/diagnostics/tests/imports/ClassClashStarImport.kt @@ -31,6 +31,12 @@ fun test(b: B) { val b_2: B = a.B() b_2.m2() + + val b_3 = B() + b_3.m2() + + val b_4 = a.B() + b_4.m2() } @@ -60,4 +66,10 @@ fun test(b: B) { val b_2 = B() b_2.m2() + + val b_3 = B() + b_3.m2() + + val b_4 = a.B() + b_4.m2() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/PackageVsClass.kt b/compiler/testData/diagnostics/tests/imports/PackageVsClass.kt index 286276c3359..a333f14b679 100644 --- a/compiler/testData/diagnostics/tests/imports/PackageVsClass.kt +++ b/compiler/testData/diagnostics/tests/imports/PackageVsClass.kt @@ -40,6 +40,9 @@ fun test(a_b: b) { val a_bc: b.c = b.c() a_bc.a_bc() + val a_bc2 = b.c() + a_bc2.a_bc() + a_fun() } @@ -49,6 +52,9 @@ fun test2(ab_c: c) { val ab_cd: c.d = c.d() ab_cd.ab_cd() + val ab_cd2 = c.d() + ab_cd2.ab_cd() + ab_fun() } @@ -64,6 +70,9 @@ fun test(a_b: b) { val a_bc: b.c = b.c() a_bc.a_bc() + val a_bc2 = b.c() + a_bc2.a_bc() + a_fun() } @@ -73,6 +82,9 @@ fun test2(ab_c: c) { val ab_cd: c.d = c.d() ab_cd.ab_cd() + val ab_cd2 = c.d() + ab_cd2.ab_cd() + ab_fun() } @@ -91,6 +103,9 @@ fun test(a_b: b) { val a_bc: b.c = b.c() a_bc.a_bc() + val a_bc2 = b.c() + a_bc2.a_bc() + a_fun() } @@ -100,6 +115,9 @@ fun test2(ab_c: c) { val ab_cd: c.d = c.d() ab_cd.ab_cd() + val ab_cd2 = c.d() + ab_cd2.ab_cd() + ab_fun() } @@ -115,6 +133,9 @@ fun test(a_b: b) { val a_bc: b.c = b.c() a_bc.a_bc() + val a_bc2 = b.c() + a_bc2.a_bc() + a_fun() } @@ -124,5 +145,8 @@ fun test2(ab_c: c) { val ab_cd: c.d = c.d() ab_cd.ab_cd() + val ab_cd2 = c.d() + ab_cd2.ab_cd() + ab_fun() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/TopLevelClassVsPackage.kt b/compiler/testData/diagnostics/tests/imports/TopLevelClassVsPackage.kt index 893cbe46e24..0673fb29956 100644 --- a/compiler/testData/diagnostics/tests/imports/TopLevelClassVsPackage.kt +++ b/compiler/testData/diagnostics/tests/imports/TopLevelClassVsPackage.kt @@ -43,7 +43,10 @@ fun test2(_a: a) { _a._a() val _ab: a.b = a.b() - _ab._ab() // todo + _ab._ab() + + val _ab2 = a.b() + _ab2._ab() // todo _fun() } @@ -56,7 +59,10 @@ fun test3(_a: a) { _a._a() val _ab: a.b = a.b() - _ab._ab() // todo + _ab._ab() + + val _ab2 = a.b() + _ab2._ab() // todo _fun() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/GenericClassVsPackage.kt b/compiler/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.kt similarity index 76% rename from compiler/testData/diagnostics/tests/imports/GenericClassVsPackage.kt rename to compiler/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.kt index 314b78e1c2e..82b0e646a79 100644 --- a/compiler/testData/diagnostics/tests/imports/GenericClassVsPackage.kt +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.kt @@ -25,10 +25,14 @@ fun test(ab_c: c) { val ab_c2: a.b.c = a.b.c() ab_c2.ab_c() + + val ab_c3 = a.b.c() + ab_c3.ab_c() } fun test2(a_bc: a.b.c) { a_bc.a_bc() // todo + a_bc.ab_c() // todo } @@ -58,10 +62,14 @@ import a.b fun test(a_b: b) { a_b.a_b() - val a_b2: a.b = a.b() - a_b2.a_b() + val _ab: a.b = a.b() + _ab._ab() + + val _ab2 = a.b() + _ab2._ab() // todo } fun test2(_ab: a.b) { - _ab._ab() // todo + _ab._ab() + _ab.a_b() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/GenericClassVsPackage.txt b/compiler/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.txt similarity index 100% rename from compiler/testData/diagnostics/tests/imports/GenericClassVsPackage.txt rename to compiler/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.txt diff --git a/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsClass.kt b/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsClass.kt new file mode 100644 index 00000000000..53c311808ae --- /dev/null +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsClass.kt @@ -0,0 +1,88 @@ +// MODULE: m1 +// FILE: a.kt +package a.b + +class c { + fun ab_c() {} +} + +// MODULE: m2 +// FILE: b.kt +package a + +fun a_fun() {} + +class b { + fun a_b() {} + + class c { + fun a_bc() {} + } +} + +// MODULE: m3(m1, m2) +// FILE: c.kt + +fun test(a_b: a.b) { + a_b.a_b() + + val ab_c: a.b.c = a.b.c() + ab_c.ab_c() + ab_c.a_bc() + + val ab_c2 = a.b.c() + ab_c2.ab_c() + ab_c2.a_bc() +} + +fun test2(ab_c: a.b.c) { + ab_c.ab_c() +} + +//---- Changed dependence order +// MODULE: _m1 +// FILE: _a.kt +package a.b + +fun ab_fun() {} + +class c { + fun ab_c() {} + + class d { + fun ab_cd() {} + } +} + +// MODULE: _m2 +// FILE: _b.kt +package a + +fun a_fun() {} + +class b { + fun a_b() {} + + class c { + fun a_bc() {} + } +} + +// MODULE: _m3(_m1, _m2) +// FILE: _c.kt + +fun test(a_b: a.b) { + a_b.a_b() + + val ab_c: a.b.c = a.b.c() + ab_c.ab_c() + ab_c.a_bc() + + val ab_c2 = a.b.c() + ab_c2.ab_c() + ab_c2.a_bc() +} + +fun test2(ab_c: a.b.c) { + ab_c.ab_c() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsClass.txt b/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsClass.txt new file mode 100644 index 00000000000..11ba6ed2f24 --- /dev/null +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsClass.txt @@ -0,0 +1,136 @@ +// -- Module: <_m1> -- +package + +package a { + + package a.b { + public fun ab_fun(): kotlin.Unit + + public final class c { + public constructor c() + public final fun ab_c(): kotlin.Unit + 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 d { + public constructor d() + public final fun ab_cd(): kotlin.Unit + 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 + } + } + } +} + + +// -- Module: <_m2> -- +package + +package a { + public fun a_fun(): kotlin.Unit + + public final class b { + public constructor b() + public final fun a_b(): kotlin.Unit + 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 c { + public constructor c() + public final fun a_bc(): kotlin.Unit + 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 + } + } +} + + +// -- Module: <_m3> -- +package + +public fun test(/*0*/ a_b: a.b): kotlin.Unit +public fun test2(/*0*/ ab_c: a.b.c): kotlin.Unit + +package a { + public fun a_fun(): kotlin.Unit + + public final class b { + // -- Module: <_m2> -- + } + + package a.b { + public fun ab_fun(): kotlin.Unit + + public final class c { + // -- Module: <_m1> -- + } + } +} + + +// -- Module: -- +package + +package a { + + package a.b { + + public final class c { + public constructor c() + public final fun ab_c(): kotlin.Unit + 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 + } + } +} + + +// -- Module: -- +package + +package a { + public fun a_fun(): kotlin.Unit + + public final class b { + public constructor b() + public final fun a_b(): kotlin.Unit + 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 c { + public constructor c() + public final fun a_bc(): kotlin.Unit + 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 + } + } +} + + +// -- Module: -- +package + +public fun test(/*0*/ a_b: a.b): kotlin.Unit +public fun test2(/*0*/ ab_c: a.b.c): kotlin.Unit + +package a { + public fun a_fun(): kotlin.Unit + + public final class b { + // -- Module: -- + } + + package a.b { + + public final class c { + // -- Module: -- + } + } +} diff --git a/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsRootClass.kt b/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsRootClass.kt new file mode 100644 index 00000000000..1ec94f8ccf0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsRootClass.kt @@ -0,0 +1,44 @@ +// MODULE: m1 +// FILE: a.kt +package a + +class b { + fun a_b() {} +} + +// MODULE: m2 +// FILE: b.kt +class a { + class b { + fun _ab() {} + } +} + +// MODULE: m3(m1, m2) +// FILE: c1.kt +package some + +fun test(a_b: a.b) { + a_b.a_b() + + val a_b2 = a.b() + a_b2.a_b() +} + +// FILE: c2.kt +package a + +fun test(a_b: a.b) { + a_b.a_b() + + val a_b2 = a.b() + a_b2.a_b() +} + +// FILE: c3.kt +fun test(_ab: a.b) { + _ab._ab() + + val _ab2 = a.b() + _ab2._ab() // todo +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsRootClass.txt b/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsRootClass.txt new file mode 100644 index 00000000000..332e241daa4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsRootClass.txt @@ -0,0 +1,56 @@ +// -- Module: -- +package + +package a { + + public final class b { + public constructor b() + public final fun a_b(): kotlin.Unit + 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 + } +} + + +// -- Module: -- +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 class b { + public constructor b() + public final fun _ab(): kotlin.Unit + 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 + } +} + + +// -- Module: -- +package + +public fun test(/*0*/ _ab: a.b): kotlin.Unit + +public final class a { + // -- Module: -- +} + +package a { + public fun test(/*0*/ a_b: a.b): kotlin.Unit + + public final class b { + // -- Module: -- + } +} + +package some { + public fun test(/*0*/ a_b: a.b): kotlin.Unit +} + + diff --git a/compiler/testData/diagnostics/tests/qualifiedExpression/TypeWithError.kt b/compiler/testData/diagnostics/tests/qualifiedExpression/TypeWithError.kt new file mode 100644 index 00000000000..8ce4d3641d2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/TypeWithError.kt @@ -0,0 +1,31 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -UNREACHABLE_CODE + +class A { + class B { + class C + } +} + +fun test(a: A.): A. { + val aa: A. = null!! +} + +fun test1(a: A.B.): A.B. { + val aa: A.B. = null!! +} + +fun test2(a: A.e.C): A.e.C { + val aa: A.e.C = null!! +} + +fun test3(a: a.A.C): a.A.C { + val aa: a.A.C = null!! +} + +fun test4(a: A.B.ee): A.B.ee { + val aa: A.B.ee = null!! +} + +fun test5(a: A.ee): A.ee { + val aa: A.ee = null!! +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/qualifiedExpression/TypeWithError.txt b/compiler/testData/diagnostics/tests/qualifiedExpression/TypeWithError.txt new file mode 100644 index 00000000000..75e052a5cd7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/TypeWithError.txt @@ -0,0 +1,29 @@ +package + +public fun test(/*0*/ a: [ERROR : A.]): [ERROR : A.] +public fun test1(/*0*/ a: [ERROR : A.B.]): [ERROR : A.B.] +public fun test2(/*0*/ a: [ERROR : A.e.C]): [ERROR : A.e.C] +public fun test3(/*0*/ a: [ERROR : a.A.C]): [ERROR : a.A.C] +public fun test4(/*0*/ a: [ERROR : A.B.ee]): [ERROR : A.B.ee] +public fun test5(/*0*/ a: [ERROR : A.ee]): [ERROR : A.ee] + +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 class B { + 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 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 + } + } +} diff --git a/compiler/testData/diagnostics/tests/qualifiedExpression/visibleClassVsQualifiedClass.kt b/compiler/testData/diagnostics/tests/qualifiedExpression/visibleClassVsQualifiedClass.kt new file mode 100644 index 00000000000..13c29e6792b --- /dev/null +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/visibleClassVsQualifiedClass.kt @@ -0,0 +1,58 @@ +// MODULE: m1 +// FILE: a.kt +package a + +class b { + fun a_b() {} +} + +// MODULE: m2 +// FILE: b.kt +package some + +class a { + class b { + fun some_ab() {} + } +} + +// MODULE: m3(m1, m2) +// FILE: c1.kt +package other + +class a {} + +fun test(a_: a.b) { + a_.a_b() + + val a_2 = a.b() + a_2.a_b() // todo: must be unresolved + a_2.some_ab() + a_2.a_() +} + +// FILE: c2.kt +package other2 + +class a { + class b { + fun other2_ab() {} + } +} + +fun test(_ab: a.b) { + _ab.other2_ab() + + val _ab2 = a.b() + _ab2.other2_ab() // todo +} + +// FILE: c3.kt +package some + +fun test(_ab: a.b) { + _ab.some_ab() + + val _ab2 = a.b() + _ab2.some_ab() // todo +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/qualifiedExpression/visibleClassVsQualifiedClass.txt b/compiler/testData/diagnostics/tests/qualifiedExpression/visibleClassVsQualifiedClass.txt new file mode 100644 index 00000000000..13ebd622262 --- /dev/null +++ b/compiler/testData/diagnostics/tests/qualifiedExpression/visibleClassVsQualifiedClass.txt @@ -0,0 +1,84 @@ +// -- Module: -- +package + +package a { + + public final class b { + public constructor b() + public final fun a_b(): kotlin.Unit + 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 + } +} + + +// -- Module: -- +package + +package some { + + 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 class b { + 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 final fun some_ab(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} + + +// -- Module: -- +package + +package a { + + public final class b { + // -- Module: -- + } +} + +package other { + public fun test(/*0*/ a_: [ERROR : a.b]): kotlin.Unit + + 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 + } +} + +package other2 { + public fun test(/*0*/ _ab: other2.a.b): kotlin.Unit + + 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 class b { + 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 final fun other2_ab(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} + +package some { + public fun test(/*0*/ _ab: some.a.b): kotlin.Unit + + public final class a { + // -- Module: -- + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 2446881113d..1008788cb18 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -6543,12 +6543,6 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } - @TestMetadata("GenericClassVsPackage.kt") - public void testGenericClassVsPackage() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/GenericClassVsPackage.kt"); - doTest(fileName); - } - @TestMetadata("ImportFromCurrentWithDifferentName.kt") public void testImportFromCurrentWithDifferentName() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/ImportFromCurrentWithDifferentName.kt"); @@ -11029,6 +11023,45 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/qualifiedExpression") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class QualifiedExpression extends AbstractJetDiagnosticsTest { + public void testAllFilesPresentInQualifiedExpression() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/qualifiedExpression"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("GenericClassVsPackage.kt") + public void testGenericClassVsPackage() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/qualifiedExpression/GenericClassVsPackage.kt"); + doTest(fileName); + } + + @TestMetadata("PackageVsClass.kt") + public void testPackageVsClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsClass.kt"); + doTest(fileName); + } + + @TestMetadata("PackageVsRootClass.kt") + public void testPackageVsRootClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/qualifiedExpression/PackageVsRootClass.kt"); + doTest(fileName); + } + + @TestMetadata("TypeWithError.kt") + public void testTypeWithError() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/qualifiedExpression/TypeWithError.kt"); + doTest(fileName); + } + + @TestMetadata("visibleClassVsQualifiedClass.kt") + public void testVisibleClassVsQualifiedClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/qualifiedExpression/visibleClassVsQualifiedClass.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/reassignment") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)