Implement support for additional receivers for script in frontend
This commit is contained in:
+36
-1
@@ -19,13 +19,21 @@ package org.jetbrains.kotlin.resolve.lazy.descriptors
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorVisitor
|
||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.KtScriptInfo
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
|
||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||
import org.jetbrains.kotlin.script.ScriptHelper
|
||||
@@ -33,9 +41,10 @@ import org.jetbrains.kotlin.script.ScriptPriorities
|
||||
import org.jetbrains.kotlin.script.getScriptDefinition
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class LazyScriptDescriptor(
|
||||
resolveSession: ResolveSession,
|
||||
val resolveSession: ResolveSession,
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
name: Name,
|
||||
internal val scriptInfo: KtScriptInfo
|
||||
@@ -82,4 +91,30 @@ class LazyScriptDescriptor(
|
||||
|
||||
override fun computeSupertypes() =
|
||||
listOf(ScriptHelper.getInstance().getKotlinType(this, scriptDefinition.template)).ifEmpty { listOf(builtIns.anyType) }
|
||||
|
||||
private val scriptOuterScope: () -> LexicalScope = resolveSession.storageManager.createLazyValue {
|
||||
val receivers = scriptDefinition.implicitReceivers
|
||||
var outerScope = super.getOuterScope()
|
||||
for (receiver in receivers.asReversed()) {
|
||||
val receiverClassId = receiver.classifier?.let { it as? KClass<*> }?.java?.classId
|
||||
val receiverClassDescriptor = receiverClassId?.let { module.findClassAcrossModuleDependencies(it) }
|
||||
if (receiverClassDescriptor == null) {
|
||||
resolveSession.trace.report(Errors.MISSING_DEPENDENCY_CLASS.on(scriptInfo.script, receiverClassId?.asSingleFqName() ?: FqName(receiver.toString())))
|
||||
break
|
||||
}
|
||||
outerScope = LexicalScopeImpl(
|
||||
outerScope,
|
||||
receiverClassDescriptor,
|
||||
true,
|
||||
receiverClassDescriptor.thisAsReceiverParameter,
|
||||
LexicalScopeKind.CLASS_MEMBER_SCOPE
|
||||
)
|
||||
}
|
||||
outerScope
|
||||
}
|
||||
|
||||
override fun getOuterScope(): LexicalScope = scriptOuterScope()
|
||||
}
|
||||
|
||||
private val Class<*>.classId: ClassId
|
||||
get() = enclosingClass?.classId?.createNestedClassId(Name.identifier(simpleName)) ?: ClassId.topLevel(FqName(name))
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.name.NameUtils
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.script.experimental.dependencies.DependenciesResolver
|
||||
import kotlin.script.experimental.location.ScriptExpectedLocation
|
||||
import kotlin.script.templates.standard.ScriptTemplateWithArgs
|
||||
@@ -53,6 +54,8 @@ open class KotlinScriptDefinition(val template: KClass<out Any>) : UserDataHolde
|
||||
|
||||
open val scriptExpectedLocations: List<ScriptExpectedLocation> =
|
||||
listOf(ScriptExpectedLocation.SourcesOnly, ScriptExpectedLocation.TestsOnly)
|
||||
|
||||
open val implicitReceivers: List<KType> get() = emptyList()
|
||||
}
|
||||
|
||||
object StandardScriptDefinition : KotlinScriptDefinition(ScriptTemplateWithArgs::class)
|
||||
|
||||
+8
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.name.NameUtils
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.script.experimental.api.ScriptCompileConfigurationParams
|
||||
import kotlin.script.experimental.api.ScriptDefinition
|
||||
import kotlin.script.experimental.api.resultOrNull
|
||||
@@ -47,6 +48,13 @@ class KotlinScriptDefinitionAdapterFromNewAPI(val scriptDefinition: ScriptDefini
|
||||
}.resultOrNull()?.getOrNull(ScriptCompileConfigurationParams.updateConfigurationOnAnnotations)?.toList()
|
||||
?: emptyList()
|
||||
}
|
||||
|
||||
override val implicitReceivers: List<KType> by lazy {
|
||||
runBlocking {
|
||||
scriptDefinition.configurator.baseConfiguration(null)
|
||||
}.resultOrNull()?.getOrNull(ScriptCompileConfigurationParams.scriptSignature)?.providedDeclarations?.implicitReceivers
|
||||
?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user