[LL API] Fix on-air analysis for scripts (KTIJ-21108)
The implementation is rather limited. Advanced cases, such as replacing a script with another one with different import directives, won't work because of non-trivial relationship between 'FirFile' and 'FirScript'.
This commit is contained in:
@@ -1049,7 +1049,11 @@ open class RawFirBuilder(
|
||||
declarations += when (declaration) {
|
||||
is KtScript -> {
|
||||
require(file.declarations.size == 1) { "Expect the script to be the only declaration in the file $name" }
|
||||
convertScript(declaration, this)
|
||||
convertScript(declaration, this.name) {
|
||||
for (configurator in baseSession.extensionService.scriptConfigurators) {
|
||||
with(configurator) { configure(this@buildFile) }
|
||||
}
|
||||
}
|
||||
}
|
||||
is KtDestructuringDeclaration -> buildErrorTopLevelDestructuringDeclaration(declaration.toFirSourceElement())
|
||||
else -> declaration.convert()
|
||||
@@ -1062,12 +1066,12 @@ open class RawFirBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertScript(script: KtScript, containingFile: FirFileBuilder): FirScript {
|
||||
private fun convertScript(script: KtScript, fileName: String, setup: FirScriptBuilder.() -> Unit = {}): FirScript {
|
||||
return buildScript {
|
||||
source = script.toFirSourceElement()
|
||||
moduleData = baseModuleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
name = Name.special("<script-${containingFile.name}>")
|
||||
name = Name.special("<script-$fileName>")
|
||||
symbol = FirScriptSymbol(context.packageFqName.child(name))
|
||||
for (declaration in script.declarations) {
|
||||
when (declaration) {
|
||||
@@ -1079,12 +1083,13 @@ open class RawFirBuilder(
|
||||
}
|
||||
}
|
||||
}
|
||||
baseSession.extensionService.scriptConfigurators.forEach { with(it) { configure(containingFile) } }
|
||||
setup()
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitScript(script: KtScript, data: Unit?): FirElement {
|
||||
error("should not be here")
|
||||
val fileName = script.containingKtFile.name
|
||||
return convertScript(script, fileName)
|
||||
}
|
||||
|
||||
protected fun KtEnumEntry.toFirEnumEntry(
|
||||
|
||||
+20
@@ -70,3 +70,23 @@ inline fun buildScript(init: FirScriptBuilder.() -> Unit): FirScript {
|
||||
}
|
||||
return FirScriptBuilder().apply(init).build()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
inline fun buildScriptCopy(original: FirScript, init: FirScriptBuilder.() -> Unit): FirScript {
|
||||
contract {
|
||||
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
val copyBuilder = FirScriptBuilder()
|
||||
copyBuilder.source = original.source
|
||||
copyBuilder.resolvePhase = original.resolvePhase
|
||||
copyBuilder.annotations.addAll(original.annotations)
|
||||
copyBuilder.moduleData = original.moduleData
|
||||
copyBuilder.origin = original.origin
|
||||
copyBuilder.attributes = original.attributes.copy()
|
||||
copyBuilder.name = original.name
|
||||
copyBuilder.statements.addAll(original.statements)
|
||||
copyBuilder.symbol = original.symbol
|
||||
copyBuilder.parameters.addAll(original.parameters)
|
||||
copyBuilder.contextReceivers.addAll(original.contextReceivers)
|
||||
return copyBuilder.apply(init).build()
|
||||
}
|
||||
|
||||
+4
@@ -357,6 +357,10 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
|
||||
fields from resolvedQualifier
|
||||
}
|
||||
|
||||
builder(script) {
|
||||
withCopy()
|
||||
}
|
||||
|
||||
builder(resolvedQualifier) {
|
||||
parents += abstractResolvedQualifierBuilder
|
||||
defaultFalse("isNullableLHSForCallableReference", "isFullyQualified")
|
||||
|
||||
Reference in New Issue
Block a user