From 2373cc3ede23d5760c33ee9fa13963140b62a040 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Thu, 17 Sep 2015 12:50:17 +0300 Subject: [PATCH] Minor. Small refactoring in QualifiedExpressionResolver --- .../resolve/QualifiedExpressionResolver.kt | 83 +++++++++++-------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt index 89a13e748fb..ea2babd6a25 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.resolve -import com.intellij.psi.util.PsiTreeUtil import com.intellij.util.SmartList import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.diagnostics.Errors @@ -32,6 +31,7 @@ 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 +import org.jetbrains.kotlin.utils.addToStdlib.check public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator) { @@ -41,8 +41,10 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa module: ModuleDescriptor, trace: BindingTrace ) { - for (nameExpression in packageDirective.packageNames) { - storageResult(trace, nameExpression, listOf(module.getPackage(packageDirective.getFqName(nameExpression))), null) + val packageNames = packageDirective.packageNames + for ((index, nameExpression) in packageNames.withIndex()) { + storageResult(trace, nameExpression, listOf(module.getPackage(packageDirective.getFqName(nameExpression))), + shouldBeVisibleFrom = null, inImport = false, isQualifier = index != packageNames.lastIndex) } } @@ -54,7 +56,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa if (userType.qualifier == null && !userType.startWithPackage) { // optimization for non-qualified types return userType.referenceExpression?.let { val classifier = scope.getClassifier(it.getReferencedNameAsName(), KotlinLookupLocation(it)) - storageResult(trace, it, listOfNotNull(classifier), scope.ownerDescriptor) + storageResult(trace, it, listOfNotNull(classifier), scope.ownerDescriptor, inImport = false, isQualifier = false) classifier } } @@ -62,7 +64,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa val module = scope.ownerDescriptor.module val (qualifierPartList, hasError) = userType.asQualifierPartList() if (hasError) { - resolveToPackageOrClass(qualifierPartList, module, trace, scope.ownerDescriptor) + resolveToPackageOrClass(qualifierPartList, module, trace, scope.ownerDescriptor, scope, inImport = false) return null } assert(qualifierPartList.size() >= 1) { @@ -70,15 +72,8 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa } val qualifier = resolveToPackageOrClass( - qualifierPartList.subList(0, qualifierPartList.size() - 1), module, trace, scope.ownerDescriptor, - firstPartResolver = { - if (userType.startWithPackage) { - null - } - else { - scope.getClassifier(it.name, it.location) - } - } + qualifierPartList.subList(0, qualifierPartList.size() - 1), module, + trace, scope.ownerDescriptor, scope.check { !userType.startWithPackage }, inImport = false ) ?: return null val lastPart = qualifierPartList.last() @@ -87,7 +82,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa is ClassDescriptor -> qualifier.unsubstitutedInnerClassesScope.getClassifier(lastPart.name, lastPart.location) else -> null } - storageResult(trace, lastPart.expression, listOfNotNull(classifier), scope.ownerDescriptor) + storageResult(trace, lastPart.expression, listOfNotNull(classifier), scope.ownerDescriptor, inImport = false, isQualifier = false) return classifier } @@ -129,7 +124,8 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa val lastPart = path.lastOrNull() ?: return JetScope.Empty if (importDirective.isAllUnder) { - val packageOrClassDescriptor = resolveToPackageOrClass(path, moduleDescriptor, trace, shouldBeVisibleFrom) ?: return JetScope.Empty + val packageOrClassDescriptor = resolveToPackageOrClass(path, moduleDescriptor, trace, shouldBeVisibleFrom, + scopeForFirstPart = null, inImport = true) ?: return JetScope.Empty if (packageOrClassDescriptor is ClassDescriptor && packageOrClassDescriptor.kind.isSingleton) { trace.report(Errors.CANNOT_IMPORT_MEMBERS_FROM_SINGLETON.on(lastPart.expression, packageOrClassDescriptor)) // todo report on star } @@ -140,11 +136,12 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa else { val aliasName = JetPsiUtil.getAliasName(importDirective) if (aliasName == null) { // import kotlin. - resolveToPackageOrClass(path, moduleDescriptor, trace, shouldBeVisibleFrom) + resolveToPackageOrClass(path, moduleDescriptor, trace, shouldBeVisibleFrom, scopeForFirstPart = null, inImport = true) return JetScope.Empty } - val packageOrClassDescriptor = resolveToPackageOrClass(path.subList(0, path.size() - 1), moduleDescriptor, trace, shouldBeVisibleFrom) + val packageOrClassDescriptor = resolveToPackageOrClass(path.subList(0, path.size() - 1), moduleDescriptor, + trace, shouldBeVisibleFrom, scopeForFirstPart = null, inImport = true) ?: return JetScope.Empty val descriptors = SmartList() @@ -170,7 +167,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa else -> throw IllegalStateException("Should be class or package: $packageOrClassDescriptor") } if (descriptors.isNotEmpty()) { - storageResult(trace, lastPart.expression, descriptors, shouldBeVisibleFrom) + storageResult(trace, lastPart.expression, descriptors, shouldBeVisibleFrom, inImport = true, isQualifier = false) } else { tryResolveDescriptorsWhichCannotBeImported(trace, moduleDescriptor, packageOrClassDescriptor, lastPart) @@ -213,7 +210,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa else -> throw IllegalStateException("Should be class or package: $packageOrClassDescriptor") } - storageResult(trace, lastPart.expression, descriptors, shouldBeVisibleFrom = null) + storageResult(trace, lastPart.expression, descriptors, shouldBeVisibleFrom = null, inImport = true, isQualifier = false) } private fun JetExpression.asQualifierPartList(trace: BindingTrace): List { @@ -253,16 +250,23 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa moduleDescriptor: ModuleDescriptor, trace: BindingTrace, shouldBeVisibleFrom: DeclarationDescriptor, - firstPartResolver: (QualifierPart) -> DeclarationDescriptor? = { null } + scopeForFirstPart: LexicalScope?, + inImport: Boolean ): DeclarationDescriptor? { if (path.isEmpty()) { return moduleDescriptor.getPackage(FqName.ROOT) } - val (currentDescriptor, currentIndex) = firstPartResolver(path.first())?.let { - storageResult(trace, path.first().expression, listOf(it), shouldBeVisibleFrom) - Pair(it, 1) - } ?: moduleDescriptor.quickResolveToPackage(path, trace) + val firstDescriptor = scopeForFirstPart?.let { + val firstPart = path.first() + it.getClassifier(firstPart.name, firstPart.location)?.apply { + storageResult(trace, firstPart.expression, listOf(this), shouldBeVisibleFrom, inImport) + } + } + + + val (currentDescriptor, currentIndex) = firstDescriptor?.let { Pair(it, 1) } ?: moduleDescriptor.quickResolveToPackage(path, trace, inImport) + return path.subList(currentIndex, path.size()).fold(currentDescriptor) { descriptor, qualifierPart -> // report unresolved reference only for first unresolved qualifier @@ -286,14 +290,15 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa } else -> null } - storageResult(trace, qualifierPart.expression, listOfNotNull(nextDescriptor), shouldBeVisibleFrom) + storageResult(trace, qualifierPart.expression, listOfNotNull(nextDescriptor), shouldBeVisibleFrom, inImport) nextDescriptor } } private fun ModuleDescriptor.quickResolveToPackage( path: List, - trace: BindingTrace + trace: BindingTrace, + inImport: Boolean ): Pair { val possiblePackagePrefixSize = path.indexOfFirst { it.typeArguments != null }.let { if (it == -1) path.size() else it + 1 } var fqName = path.subList(0, possiblePackagePrefixSize).fold(FqName.ROOT) { fqName, qualifierPart -> @@ -303,7 +308,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa while (!fqName.isRoot) { val packageDescriptor = getPackage(fqName) if (!packageDescriptor.isEmpty()) { - recordPackageViews(path.subList(0, prefixSize), packageDescriptor, trace) + recordPackageViews(path.subList(0, prefixSize), packageDescriptor, trace, inImport) return Pair(packageDescriptor, prefixSize) } fqName = fqName.parent() @@ -315,10 +320,11 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa private fun recordPackageViews( path: List, packageView: PackageViewDescriptor, - trace: BindingTrace + trace: BindingTrace, + inImport: Boolean ) { path.foldRight(packageView) { qualifierPart, currentView -> - storageResult(trace, qualifierPart.expression, listOfNotNull(currentView), null) + storageResult(trace, qualifierPart.expression, listOfNotNull(currentView), shouldBeVisibleFrom = null, inImport = inImport) val parentView = currentView.containingDeclaration assert(parentView != null) { "Containing Declaration must be not null for package with fqName: ${currentView.fqName}, " + @@ -332,7 +338,9 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa trace: BindingTrace, referenceExpression: JetSimpleNameExpression, descriptors: Collection, - shouldBeVisibleFrom: DeclarationDescriptor? + shouldBeVisibleFrom: DeclarationDescriptor?, + inImport: Boolean, + isQualifier: Boolean = true ) { if (descriptors.isEmpty()) { trace.report(Errors.UNRESOLVED_REFERENCE.on(referenceExpression, referenceExpression)) @@ -348,10 +356,11 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa symbolUsageValidator.validateTypeUsage(descriptor, trace, referenceExpression) } if (descriptor is DeclarationDescriptorWithVisibility && shouldBeVisibleFrom != null) { - checkVisibility(descriptor, trace, referenceExpression, shouldBeVisibleFrom) + checkVisibility(descriptor, trace, referenceExpression, shouldBeVisibleFrom, inImport) + } + if (isQualifier) { + storageQualifier(trace, referenceExpression, descriptor) } - - storageQualifier(trace, referenceExpression, descriptor) } } @@ -366,9 +375,11 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa descriptor: DeclarationDescriptorWithVisibility, trace: BindingTrace, referenceExpression: JetSimpleNameExpression, - shouldBeVisibleFrom: DeclarationDescriptor) { + shouldBeVisibleFrom: DeclarationDescriptor, + inImport: Boolean + ) { val visibility = descriptor.visibility - if (PsiTreeUtil.getParentOfType(referenceExpression, JetImportDirective::class.java) != null && !visibility.mustCheckInImports()) { + if (inImport && !visibility.mustCheckInImports()) { return } if (!Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, descriptor, shouldBeVisibleFrom)) {