Expose script parameters from descriptor explicitly...
and universally as ValueParameterDescriptors; update implementation accordingly
This commit is contained in:
@@ -724,7 +724,7 @@ open class WrappedScriptDescriptor : ScriptDescriptor, WrappedDeclarationDescrip
|
||||
}
|
||||
|
||||
override fun getDefaultFunctionTypeForSamInterface(): SimpleType? {
|
||||
TODO("not implemented")
|
||||
TODO("not yet implemented")
|
||||
}
|
||||
|
||||
override fun isDefinitelyNotSamInterface(): Boolean {
|
||||
@@ -735,6 +735,18 @@ open class WrappedScriptDescriptor : ScriptDescriptor, WrappedDeclarationDescrip
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getExplicitConstructorParameters(): MutableList<ValueParameterDescriptor> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getImplicitReceiversParameters(): MutableList<ValueParameterDescriptor> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getScriptProvidedPropertiesParameters(): MutableList<ValueParameterDescriptor> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getImplicitReceivers(): MutableList<ClassDescriptor> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
@@ -36,4 +36,13 @@ public interface ScriptDescriptor extends ClassDescriptor {
|
||||
|
||||
@Nullable
|
||||
PropertyDescriptor getResultValue();
|
||||
|
||||
@NotNull
|
||||
List<ValueParameterDescriptor> getExplicitConstructorParameters();
|
||||
|
||||
@NotNull
|
||||
List<ValueParameterDescriptor> getImplicitReceiversParameters();
|
||||
|
||||
@NotNull
|
||||
List<ValueParameterDescriptor> getScriptProvidedPropertiesParameters();
|
||||
}
|
||||
|
||||
+8
-62
@@ -5,18 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.scripting.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassMemberScope
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.KotlinTypeFactory
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
|
||||
class LazyScriptClassMemberScope(
|
||||
resolveSession: ResolveSession,
|
||||
@@ -28,65 +23,17 @@ class LazyScriptClassMemberScope(
|
||||
private val _variableNames: MutableSet<Name>
|
||||
by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
super.getVariableNames().apply {
|
||||
scriptDescriptor.scriptProvidedProperties.forEach {
|
||||
add(it.name)
|
||||
}
|
||||
scriptDescriptor.resultFieldName()?.let {
|
||||
add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val scriptPrimaryConstructor: () -> ClassConstructorDescriptorImpl? = resolveSession.storageManager.createNullableLazyValue {
|
||||
val baseClass = scriptDescriptor.baseClassDescriptor()
|
||||
val baseConstructorDescriptor = baseClass?.unsubstitutedPrimaryConstructor
|
||||
if (baseConstructorDescriptor != null) {
|
||||
val implicitReceiversParamTypes =
|
||||
scriptDescriptor.implicitReceivers.mapIndexed { idx, receiver ->
|
||||
val name =
|
||||
if (receiver is ScriptDescriptor) "$IMPORTED_SCRIPT_PARAM_NAME_PREFIX${receiver.name}"
|
||||
else "$IMPLICIT_RECEIVER_PARAM_NAME_PREFIX$idx"
|
||||
name to receiver.defaultType
|
||||
}
|
||||
val providedPropertiesParamTypes =
|
||||
scriptDescriptor.scriptProvidedProperties.map {
|
||||
it.name.identifier to it.type
|
||||
}
|
||||
val annotations = baseConstructorDescriptor.annotations
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.create(
|
||||
scriptDescriptor, annotations, baseConstructorDescriptor.isPrimary, scriptDescriptor.source
|
||||
)
|
||||
var paramsIndexBase = baseConstructorDescriptor.valueParameters.lastIndex + 1
|
||||
val syntheticParameters =
|
||||
(implicitReceiversParamTypes + providedPropertiesParamTypes).map { param: Pair<String, KotlinType> ->
|
||||
ValueParameterDescriptorImpl(
|
||||
constructorDescriptor,
|
||||
null,
|
||||
paramsIndexBase++,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier(param.first),
|
||||
param.second,
|
||||
false, false, false, null, SourceElement.NO_SOURCE
|
||||
)
|
||||
}
|
||||
val parameters = baseConstructorDescriptor.valueParameters.map { it.copy(constructorDescriptor, it.name, it.index) } +
|
||||
syntheticParameters
|
||||
constructorDescriptor.initialize(parameters, baseConstructorDescriptor.visibility)
|
||||
constructorDescriptor.returnType = scriptDescriptor.defaultType
|
||||
constructorDescriptor
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolvePrimaryConstructor(): ClassConstructorDescriptor? {
|
||||
val constructor = scriptPrimaryConstructor()
|
||||
?: ClassConstructorDescriptorImpl.create(
|
||||
scriptDescriptor,
|
||||
Annotations.EMPTY,
|
||||
true,
|
||||
SourceElement.NO_SOURCE
|
||||
).initialize(
|
||||
emptyList(),
|
||||
DescriptorVisibilities.PUBLIC
|
||||
)
|
||||
override fun resolvePrimaryConstructor(): ClassConstructorDescriptor {
|
||||
val constructor = scriptDescriptor.scriptPrimaryConstructorWithParams().constructor
|
||||
setDeferredReturnType(constructor)
|
||||
return constructor
|
||||
}
|
||||
@@ -100,6 +47,7 @@ class LazyScriptClassMemberScope(
|
||||
result.add(it)
|
||||
}
|
||||
}
|
||||
scriptDescriptor.scriptProvidedProperties.forEach { if (it.name == name) result.add(it) }
|
||||
}
|
||||
|
||||
override fun createPropertiesFromPrimaryConstructorParameters(name: Name, result: MutableSet<PropertyDescriptor>) {
|
||||
@@ -111,5 +59,3 @@ class LazyScriptClassMemberScope(
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassDescriptor.substitute(vararg types: KotlinType): KotlinType? =
|
||||
KotlinTypeFactory.simpleType(this.defaultType, arguments = types.map { it.asTypeProjection() })
|
||||
|
||||
+88
-13
@@ -7,11 +7,14 @@ package org.jetbrains.kotlin.scripting.resolve
|
||||
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.MISSING_IMPORTED_SCRIPT_FILE
|
||||
@@ -53,6 +56,7 @@ import kotlin.script.experimental.host.GetScriptingClass
|
||||
import kotlin.script.experimental.host.ScriptingHostConfiguration
|
||||
import kotlin.script.experimental.host.getScriptingClass
|
||||
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
||||
import kotlin.script.experimental.jvm.util.toValidJvmIdentifier
|
||||
|
||||
|
||||
class LazyScriptDescriptor(
|
||||
@@ -179,11 +183,11 @@ class LazyScriptDescriptor(
|
||||
|
||||
private inner class ImportedScriptDescriptorsFinder {
|
||||
|
||||
val localFS by lazy {
|
||||
val localFS: VirtualFileSystem by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
val fileManager = VirtualFileManager.getInstance()
|
||||
fileManager.getFileSystem(StandardFileSystems.FILE_PROTOCOL)
|
||||
}
|
||||
val psiManager by lazy { PsiManager.getInstance(scriptInfo.script.project) }
|
||||
val psiManager by lazy(LazyThreadSafetyMode.PUBLICATION) { PsiManager.getInstance(scriptInfo.script.project) }
|
||||
|
||||
operator fun invoke(importedScript: SourceCode): ScriptDescriptor? {
|
||||
// Note: is not an error now - if import references other valid source file, it is simply compiled along with script
|
||||
@@ -264,22 +268,93 @@ class LazyScriptDescriptor(
|
||||
|
||||
override fun getImplicitReceivers(): List<ClassDescriptor> = scriptImplicitReceivers()
|
||||
|
||||
private val scriptProvidedProperties: () -> ScriptProvidedPropertiesDescriptor = resolveSession.storageManager.createLazyValue {
|
||||
ScriptProvidedPropertiesDescriptor(this)
|
||||
private val scriptProvidedProperties: () -> List<ScriptProvidedPropertyDescriptor> = resolveSession.storageManager.createLazyValue {
|
||||
scriptCompilationConfiguration()[ScriptCompilationConfiguration.providedProperties].orEmpty()
|
||||
.mapNotNull { (name, type) ->
|
||||
findTypeDescriptor(getScriptingClass(type), Errors.MISSING_SCRIPT_PROVIDED_PROPERTY_CLASS)
|
||||
?.let { name.toValidJvmIdentifier() to it }
|
||||
}.map { (name, classDescriptor) ->
|
||||
ScriptProvidedPropertyDescriptor(
|
||||
Name.identifier(name),
|
||||
classDescriptor,
|
||||
thisAsReceiverParameter,
|
||||
true,
|
||||
this
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getScriptProvidedProperties(): List<PropertyDescriptor> = scriptProvidedProperties().properties()
|
||||
override fun getScriptProvidedProperties(): List<PropertyDescriptor> = scriptProvidedProperties()
|
||||
|
||||
internal class ConstructorWithParams(
|
||||
val constructor: ClassConstructorDescriptorImpl,
|
||||
val explicitConstructorParameters: List<ValueParameterDescriptor>,
|
||||
val implicitReceiversParameters: List<ValueParameterDescriptor>,
|
||||
val scriptProvidedPropertiesParameters: List<ValueParameterDescriptor>
|
||||
)
|
||||
|
||||
internal val scriptPrimaryConstructorWithParams: () -> ConstructorWithParams = resolveSession.storageManager.createLazyValue {
|
||||
val baseConstructorDescriptor = baseClassDescriptor()?.unsubstitutedPrimaryConstructor
|
||||
val inheritedAnnotations = baseConstructorDescriptor?.annotations ?: Annotations.EMPTY
|
||||
val baseExplicitParameters = baseConstructorDescriptor?.valueParameters ?: emptyList()
|
||||
|
||||
val implicitReceiversParamTypes =
|
||||
implicitReceivers.mapIndexed { idx, receiver ->
|
||||
val receiverName =
|
||||
if (receiver is ScriptDescriptor) "${LazyScriptClassMemberScope.IMPORTED_SCRIPT_PARAM_NAME_PREFIX}${receiver.name}"
|
||||
else "${LazyScriptClassMemberScope.IMPLICIT_RECEIVER_PARAM_NAME_PREFIX}$idx"
|
||||
receiverName to receiver.defaultType
|
||||
}
|
||||
|
||||
val providedPropertiesParamTypes =
|
||||
scriptProvidedProperties().map {
|
||||
it.name.identifier to it.type
|
||||
}
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.create(this, inheritedAnnotations, true, source)
|
||||
|
||||
var paramsIndexBase = baseExplicitParameters.lastIndex + 1
|
||||
|
||||
fun createValueParameter(param: Pair<String, org.jetbrains.kotlin.types.KotlinType>) =
|
||||
ValueParameterDescriptorImpl(
|
||||
constructorDescriptor,
|
||||
null,
|
||||
paramsIndexBase++,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier(param.first),
|
||||
param.second,
|
||||
declaresDefaultValue = false, isCrossinline = false, isNoinline = false, varargElementType = null,
|
||||
source = SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
val explicitParameters = baseExplicitParameters.map { it.copy(constructorDescriptor, it.name, it.index) }
|
||||
val implicitReceiversParameters = implicitReceiversParamTypes.map(::createValueParameter)
|
||||
val providedPropertiesParameters = providedPropertiesParamTypes.map(::createValueParameter)
|
||||
|
||||
constructorDescriptor.initialize(
|
||||
explicitParameters + implicitReceiversParameters + providedPropertiesParameters, DescriptorVisibilities.PUBLIC
|
||||
)
|
||||
constructorDescriptor.returnType = defaultType()
|
||||
|
||||
ConstructorWithParams(
|
||||
constructorDescriptor,
|
||||
explicitConstructorParameters = explicitParameters,
|
||||
implicitReceiversParameters = implicitReceiversParameters,
|
||||
scriptProvidedPropertiesParameters = providedPropertiesParameters
|
||||
)
|
||||
}
|
||||
|
||||
override fun getExplicitConstructorParameters(): List<ValueParameterDescriptor> =
|
||||
scriptPrimaryConstructorWithParams().explicitConstructorParameters
|
||||
|
||||
override fun getImplicitReceiversParameters(): List<ValueParameterDescriptor> =
|
||||
scriptPrimaryConstructorWithParams().implicitReceiversParameters
|
||||
|
||||
override fun getScriptProvidedPropertiesParameters(): List<ValueParameterDescriptor> =
|
||||
scriptPrimaryConstructorWithParams().scriptProvidedPropertiesParameters
|
||||
|
||||
private val scriptOuterScope: () -> LexicalScope = resolveSession.storageManager.createLazyValue {
|
||||
var outerScope = super.getOuterScope()
|
||||
val outerScopeReceivers = implicitReceivers.let {
|
||||
if (scriptCompilationConfiguration()[ScriptCompilationConfiguration.providedProperties]?.isNotEmpty() == true) {
|
||||
it + ScriptProvidedPropertiesDescriptor(this)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
for (receiverClassDescriptor in outerScopeReceivers.asReversed()) {
|
||||
for (receiverClassDescriptor in implicitReceivers.asReversed()) {
|
||||
outerScope = LexicalScopeImpl(
|
||||
outerScope,
|
||||
receiverClassDescriptor,
|
||||
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.scripting.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutableClassDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import kotlin.script.experimental.api.ScriptCompilationConfiguration
|
||||
import kotlin.script.experimental.api.providedProperties
|
||||
import kotlin.script.experimental.jvm.util.toValidJvmIdentifier
|
||||
|
||||
class ScriptProvidedPropertiesDescriptor(script: LazyScriptDescriptor) :
|
||||
MutableClassDescriptor(
|
||||
script,
|
||||
ClassKind.CLASS, false, false,
|
||||
Name.special("<synthetic script provided properties for ${script.name}>"),
|
||||
SourceElement.NO_SOURCE,
|
||||
LockBasedStorageManager.NO_LOCKS
|
||||
) {
|
||||
|
||||
init {
|
||||
modality = Modality.FINAL
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
setTypeParameterDescriptors(emptyList())
|
||||
createTypeConstructor()
|
||||
}
|
||||
|
||||
private val memberScope: () -> ScriptProvidedPropertiesMemberScope = script.resolveSession.storageManager.createLazyValue {
|
||||
ScriptProvidedPropertiesMemberScope(
|
||||
script.name.identifier,
|
||||
properties()
|
||||
)
|
||||
}
|
||||
|
||||
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope = memberScope()
|
||||
|
||||
val properties: () -> List<ScriptProvidedPropertyDescriptor> = script.resolveSession.storageManager.createLazyValue {
|
||||
script.scriptCompilationConfiguration()[ScriptCompilationConfiguration.providedProperties].orEmpty().mapNotNull { (name, type) ->
|
||||
script.findTypeDescriptor(script.getScriptingClass(type), Errors.MISSING_SCRIPT_PROVIDED_PROPERTY_CLASS)
|
||||
?.let { name.toValidJvmIdentifier() to it }
|
||||
}.map { (name, classDescriptor) ->
|
||||
ScriptProvidedPropertyDescriptor(
|
||||
Name.identifier(name),
|
||||
classDescriptor,
|
||||
thisAsReceiverParameter,
|
||||
true,
|
||||
script
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class ScriptProvidedPropertiesMemberScope(
|
||||
private val scriptId: String,
|
||||
private val providedProperties: List<PropertyDescriptor>
|
||||
) : MemberScopeImpl() {
|
||||
override fun getContributedDescriptors(
|
||||
kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean
|
||||
): Collection<DeclarationDescriptor> =
|
||||
providedProperties
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> =
|
||||
providedProperties.filter { it.name == name }
|
||||
|
||||
override fun printScopeStructure(p: Printer) {
|
||||
p.println("Scope of script provided properties: $scriptId")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user