From 14ad6284d9d7f910901fbe40b7cd17233e30b08f Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Tue, 27 Aug 2019 16:38:40 +0700 Subject: [PATCH] QualifiedExpressionResolver: add root prefix resolve for IDE analysis --- .../resolve/QualifiedExpressionResolver.kt | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt index b47ccae79aa..9fc3c4fbdb8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt @@ -18,6 +18,8 @@ package org.jetbrains.kotlin.resolve import com.intellij.psi.impl.source.DummyHolder import com.intellij.util.SmartList +import org.jetbrains.kotlin.config.AnalysisFlags +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.incremental.KotlinLookupLocation @@ -43,7 +45,7 @@ import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext import org.jetbrains.kotlin.types.expressions.isWithoutValueArguments -class QualifiedExpressionResolver { +class QualifiedExpressionResolver(val languageVersionSettings: LanguageVersionSettings) { fun resolvePackageHeader( packageDirective: KtPackageDirective, module: ModuleDescriptor, @@ -440,6 +442,9 @@ class QualifiedExpressionResolver { return packageOrClassDescriptor } + private fun resolveInIDEMode(path: List): Boolean = + languageVersionSettings.getFlag(AnalysisFlags.ideMode) && path.size > 1 && path.first().name.asString() == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE + private fun resolveToPackageOrClassPrefix( path: List, moduleDescriptor: ModuleDescriptor, @@ -449,6 +454,18 @@ class QualifiedExpressionResolver { position: QualifierPosition, isValue: ((KtSimpleNameExpression) -> Boolean)? = null ): Pair { + if (resolveInIDEMode(path)) { + return resolveToPackageOrClassPrefix( + path.subList(1, path.size), + moduleDescriptor, + trace, + shouldBeVisibleFrom, + scopeForFirstPart = null, + position = position, + isValue = null + ).let { it.first to it.second + 1 } + } + if (path.isEmpty()) { return Pair(moduleDescriptor.getPackage(FqName.ROOT), 0) } @@ -759,6 +776,26 @@ class QualifiedExpressionResolver { return qualifier } + + companion object { + /** + * Shouldn't be visible to users. + * Used as prefix for [FqName] from non-root to avoid conflicts when resolving in IDE. + * E.g.: + * --------- + * package a + * + * class A + * + * fun test(a: Any) { + * a.A() // invalid code -> incorrect import/completion/etc. + * _Qfadj4tPV.a.A() // OK + * } + * --------- + */ + const val ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE = "_Qfadj4tPV" + const val ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE_WITH_DOT = "$ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE." + } } internal fun isVisible(