[KT-58817] Implicit receiver for code completion
Prior to this commit code completion for .kts files was supported only partially. Script has an implicit receiver - base class representing a script itself, the point where its basic API resides. The knowledge of this receiver was missing. There are at least two context where this knowledge is crucial: 1. Code highlighting (worked fine) 2. Code completion (failed) `FirScriptConfiguratorExtension` is responsible for filling `FirScriptBuilder` with base script class (in addition to other properties). See usages of [1] in its implementation. The thing is that resolution during the completion works a bit different. Instead of converting the entire `KtFile` it's interested in `KtScript` only. See usages of [2]. `RawFirBuilder.Visitor.visitScript` is where implicit receivers were missing. Code completion and inspections applied to `.kts` files already have `FirScript` and don't require its full reconstruction with expensive `FirScriptConfiguratorExtension`. `RawFirBuilder.Visitor` was modified to support sometimes already existing `FirElement`. ---------------------------------------------------------------- [1]: ScriptCompilationConfiguration.baseClass [2]: RawFirBuilder.Visitor.convertScript
This commit is contained in:
committed by
Space Team
parent
2a1d4a42ae
commit
6535278bd3
+2
-2
@@ -24,8 +24,8 @@ internal fun buildFileFirAnnotation(
|
||||
|
||||
val builder = object : RawFirBuilder(session, baseScopeProvider) {
|
||||
inner class VisitorWithReplacement : Visitor() {
|
||||
override fun convertElement(element: KtElement): FirElement? =
|
||||
super.convertElement(replacementApplier?.tryReplace(element) ?: element)
|
||||
override fun convertElement(element: KtElement, original: FirElement?): FirElement? =
|
||||
super.convertElement(replacementApplier?.tryReplace(element) ?: element, original)
|
||||
}
|
||||
}
|
||||
builder.context.packageFqName = fileAnnotation.containingKtFile.packageFqName
|
||||
|
||||
+8
-8
@@ -177,8 +177,8 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
|
||||
}
|
||||
|
||||
private inner class VisitorWithReplacement(private val containingClass: FirRegularClass?) : Visitor() {
|
||||
override fun convertElement(element: KtElement): FirElement? =
|
||||
super.convertElement(replacementApplier?.tryReplace(element) ?: element)
|
||||
override fun convertElement(element: KtElement, original: FirElement?): FirElement? =
|
||||
super.convertElement(replacementApplier?.tryReplace(element) ?: element, original)
|
||||
|
||||
override fun convertProperty(
|
||||
property: KtProperty,
|
||||
@@ -226,7 +226,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
|
||||
return ConstructorConversionParams(superTypeCallEntry, selfType, typeParameters)
|
||||
}
|
||||
|
||||
override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: Unit?): FirElement {
|
||||
override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: FirElement?): FirElement {
|
||||
val classOrObject = constructor.getContainingClassOrObject()
|
||||
val params = extractContructorConversionParams(classOrObject, constructor)
|
||||
val delegatedTypeRef = (originalDeclaration as FirConstructor).delegatedConstructor?.constructedTypeRef
|
||||
@@ -260,10 +260,10 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
|
||||
return newConstructor
|
||||
}
|
||||
|
||||
override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor, data: Unit?): FirElement =
|
||||
override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor, data: FirElement?): FirElement =
|
||||
processPrimaryConstructor(constructor.getContainingClassOrObject(), constructor)
|
||||
|
||||
override fun visitEnumEntry(enumEntry: KtEnumEntry, data: Unit?): FirElement {
|
||||
override fun visitEnumEntry(enumEntry: KtEnumEntry, data: FirElement?): FirElement {
|
||||
val owner = containingClass ?: buildErrorWithAttachment("Enum entry outside of class") {
|
||||
withPsiEntry("enumEntry", enumEntry, baseSession.llFirModuleData.ktModule)
|
||||
}
|
||||
@@ -310,17 +310,17 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
|
||||
// Constructor outside of class, syntax error, we should not do anything
|
||||
originalDeclaration
|
||||
} else {
|
||||
visitor.convertElement(declarationToBuild)
|
||||
visitor.convertElement(declarationToBuild, originalDeclaration)
|
||||
}
|
||||
}
|
||||
is KtClassOrObject -> {
|
||||
when {
|
||||
originalDeclaration is FirConstructor -> visitor.processPrimaryConstructor(declarationToBuild, null)
|
||||
originalDeclaration is FirField -> visitor.processField(declarationToBuild, originalDeclaration)
|
||||
else -> visitor.convertElement(declarationToBuild)
|
||||
else -> visitor.convertElement(declarationToBuild, originalDeclaration)
|
||||
}
|
||||
}
|
||||
else -> visitor.convertElement(declarationToBuild)
|
||||
else -> visitor.convertElement(declarationToBuild, originalDeclaration)
|
||||
} as FirDeclaration
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve
|
||||
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
|
||||
@@ -17,7 +17,7 @@ internal fun buildFirUserTypeRef(
|
||||
baseScopeProvider: FirScopeProvider
|
||||
): FirUserTypeRef {
|
||||
val builder = object : RawFirBuilder(session, baseScopeProvider) {
|
||||
fun build(): FirUserTypeRef = Visitor().visitTypeReference(typeReference, Unit) as FirUserTypeRef
|
||||
fun build(): FirUserTypeRef = Visitor().visitTypeReference(typeReference, null) as FirUserTypeRef
|
||||
}
|
||||
builder.context.packageFqName = typeReference.containingKtFile.packageFqName
|
||||
return builder.build()
|
||||
|
||||
Reference in New Issue
Block a user