mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-05-12 08:31:28 +00:00
Move the rest of script descriptor implementation details to plugin, cleanup
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. 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.compiler.plugin.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.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,
|
||||
declarationProvider: ClassMemberDeclarationProvider,
|
||||
private val scriptDescriptor: LazyScriptDescriptor,
|
||||
trace: BindingTrace
|
||||
) : LazyClassMemberScope(resolveSession, declarationProvider, scriptDescriptor, trace) {
|
||||
|
||||
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(),
|
||||
Visibilities.PUBLIC
|
||||
)
|
||||
setDeferredReturnType(constructor)
|
||||
return constructor
|
||||
}
|
||||
|
||||
override fun getNonDeclaredProperties(name: Name, result: MutableSet<PropertyDescriptor>) {
|
||||
super.getNonDeclaredProperties(name, result)
|
||||
if (scriptDescriptor.resultFieldName() == name.asString()) {
|
||||
scriptDescriptor.resultValue?.let {
|
||||
result.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun createPropertiesFromPrimaryConstructorParameters(name: Name, result: MutableSet<PropertyDescriptor>) {
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val IMPLICIT_RECEIVER_PARAM_NAME_PREFIX = "\$\$implicitReceiver"
|
||||
const val IMPORTED_SCRIPT_PARAM_NAME_PREFIX = "\$\$importedScript"
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassDescriptor.substitute(vararg types: KotlinType): KotlinType? =
|
||||
KotlinTypeFactory.simpleType(this.defaultType, arguments = types.map { it.asTypeProjection() })
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. 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.compiler.plugin.resolve
|
||||
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
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.diagnostics.DiagnosticFactory1
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.MISSING_IMPORTED_SCRIPT_FILE
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.MISSING_IMPORTED_SCRIPT_PSI
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
|
||||
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.lazy.descriptors.LazyClassDescriptor
|
||||
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.ScriptDependenciesProvider
|
||||
import org.jetbrains.kotlin.script.ScriptPriorities
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.io.File
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
|
||||
class LazyScriptDescriptor(
|
||||
val resolveSession: ResolveSession,
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
name: Name,
|
||||
internal val scriptInfo: KtScriptInfo
|
||||
) : ScriptDescriptor, LazyClassDescriptor(
|
||||
resolveSession,
|
||||
containingDeclaration,
|
||||
name,
|
||||
scriptInfo,
|
||||
/* isExternal = */ false
|
||||
) {
|
||||
init {
|
||||
resolveSession.trace.record(BindingContext.SCRIPT, scriptInfo.script, this)
|
||||
}
|
||||
|
||||
override fun getResultValue(): ReplResultPropertyDescriptor? {
|
||||
val expression = scriptInfo.script
|
||||
.getChildOfType<KtBlockExpression>()
|
||||
?.getChildrenOfType<KtScriptInitializer>()?.lastOrNull()
|
||||
?.getChildOfType<KtExpression>()
|
||||
|
||||
val type = expression?.let {
|
||||
resolveSession.trace.bindingContext.getType(it)
|
||||
}
|
||||
|
||||
return if (type != null && !type.isUnit() && !type.isNothing()) {
|
||||
resultFieldName()?.let {
|
||||
ReplResultPropertyDescriptor(
|
||||
Name.identifier(it),
|
||||
type,
|
||||
this.thisAsReceiverParameter,
|
||||
this,
|
||||
expression.toSourceElement()
|
||||
)
|
||||
}
|
||||
} else null
|
||||
}
|
||||
|
||||
fun resultFieldName(): String? {
|
||||
val scriptPriority = scriptInfo.script.getUserData(ScriptPriorities.PRIORITY_KEY)
|
||||
if (scriptPriority != null) {
|
||||
return "res$scriptPriority"
|
||||
}
|
||||
val scriptName = name.asString()
|
||||
return if (scriptName.startsWith("Line_")) {
|
||||
"res${scriptName.split("_")[1]}"
|
||||
} else "\$\$result"
|
||||
}
|
||||
|
||||
private val sourceElement = scriptInfo.script.toSourceElement()
|
||||
|
||||
override fun getSource() = sourceElement
|
||||
|
||||
private val priority: Int = ScriptPriorities.getScriptPriority(scriptInfo.script)
|
||||
|
||||
override fun getPriority() = priority
|
||||
|
||||
val scriptDefinition: () -> KotlinScriptDefinition = resolveSession.storageManager.createLazyValue {
|
||||
val file = scriptInfo.script.containingKtFile
|
||||
scriptInfo.script.kotlinScriptDefinition ?: throw RuntimeException("file ${file.name} is not a script")
|
||||
}
|
||||
|
||||
override fun substitute(substitutor: TypeSubstitutor) = this
|
||||
|
||||
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
|
||||
visitor.visitScriptDescriptor(this, data)
|
||||
|
||||
override fun createMemberScope(c: LazyClassContext, declarationProvider: ClassMemberDeclarationProvider): LazyScriptClassMemberScope =
|
||||
LazyScriptClassMemberScope(
|
||||
// Must be a ResolveSession for scripts
|
||||
c as ResolveSession,
|
||||
declarationProvider,
|
||||
this,
|
||||
c.trace
|
||||
)
|
||||
|
||||
override fun getUnsubstitutedPrimaryConstructor() = super.getUnsubstitutedPrimaryConstructor()!!
|
||||
|
||||
internal val baseClassDescriptor: () -> ClassDescriptor? = resolveSession.storageManager.createNullableLazyValue {
|
||||
val template = scriptDefinition().template
|
||||
findTypeDescriptor(
|
||||
template,
|
||||
if (template.qualifiedName?.startsWith("kotlin.script.templates.standard") == true) Errors.MISSING_SCRIPT_STANDARD_TEMPLATE
|
||||
else Errors.MISSING_SCRIPT_BASE_CLASS
|
||||
)
|
||||
}
|
||||
|
||||
override fun computeSupertypes() = listOf(baseClassDescriptor()?.defaultType ?: builtIns.anyType)
|
||||
|
||||
private inner class ImportedScriptDescriptorsFinder {
|
||||
|
||||
val fileManager = VirtualFileManager.getInstance()
|
||||
val localFS = fileManager.getFileSystem(StandardFileSystems.FILE_PROTOCOL)
|
||||
val psiManager = PsiManager.getInstance(scriptInfo.script.project)
|
||||
|
||||
operator fun invoke(importedScriptFile: File): ScriptDescriptor? {
|
||||
|
||||
fun errorDescriptor(errorDiagnostic: DiagnosticFactory1<PsiElement, String>?): ScriptDescriptor? {
|
||||
reportErrorString1(errorDiagnostic, importedScriptFile.path)
|
||||
return null
|
||||
}
|
||||
|
||||
val vfile = localFS.findFileByPath(importedScriptFile.path)
|
||||
?: return errorDescriptor(MISSING_IMPORTED_SCRIPT_FILE)
|
||||
val psiFile = psiManager.findFile(vfile)
|
||||
?: return errorDescriptor(MISSING_IMPORTED_SCRIPT_PSI)
|
||||
// Note: is not an error now - if import references other valid source file, it is simply compiled along with script
|
||||
// TODO: check if this is the behavior we want to have - see #KT-28916
|
||||
val ktScript = (psiFile as? KtFile)?.declarations?.firstIsInstanceOrNull<KtScript>()
|
||||
?: return null
|
||||
return resolveSession.getScriptDescriptor(ktScript) as ScriptDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
private val scriptImplicitReceivers: () -> List<ClassDescriptor> = resolveSession.storageManager.createLazyValue {
|
||||
val res = ArrayList<ClassDescriptor>()
|
||||
|
||||
val importedScriptsFiles = ScriptDependenciesProvider.getInstance(scriptInfo.script.project)
|
||||
?.getScriptDependencies(scriptInfo.script.containingKtFile)?.scripts
|
||||
if (importedScriptsFiles != null) {
|
||||
val findImportedScriptDescriptor = ImportedScriptDescriptorsFinder()
|
||||
importedScriptsFiles.mapNotNullTo(res) {
|
||||
findImportedScriptDescriptor(it)
|
||||
}
|
||||
}
|
||||
|
||||
scriptDefinition().implicitReceivers.mapNotNullTo(res) { receiver ->
|
||||
findTypeDescriptor(receiver, Errors.MISSING_SCRIPT_RECEIVER_CLASS)
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
internal fun findTypeDescriptor(kClass: KClass<*>, errorDiagnostic: DiagnosticFactory1<PsiElement, String>?): ClassDescriptor? =
|
||||
findTypeDescriptor(kClass.classId, kClass.toString(), errorDiagnostic)
|
||||
|
||||
internal fun findTypeDescriptor(type: KType, errorDiagnostic: DiagnosticFactory1<PsiElement, String>?): ClassDescriptor? =
|
||||
findTypeDescriptor(type.classId, type.toString(), errorDiagnostic)
|
||||
|
||||
internal fun findTypeDescriptor(
|
||||
classId: ClassId?, typeName: String,
|
||||
errorDiagnostic: DiagnosticFactory1<PsiElement, String>?
|
||||
): ClassDescriptor? {
|
||||
val typeDescriptor = classId?.let { module.findClassAcrossModuleDependencies(it) }
|
||||
if (typeDescriptor == null) {
|
||||
reportErrorString1(errorDiagnostic, classId?.asSingleFqName()?.toString() ?: typeName)
|
||||
}
|
||||
return typeDescriptor
|
||||
}
|
||||
|
||||
private fun reportErrorString1(errorDiagnostic: DiagnosticFactory1<PsiElement, String>?, arg: String) {
|
||||
if (errorDiagnostic != null) {
|
||||
// TODO: use PositioningStrategies to highlight some specific place in case of error, instead of treating the whole file as invalid
|
||||
resolveSession.trace.report(
|
||||
errorDiagnostic.on(
|
||||
scriptInfo.script,
|
||||
arg
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getImplicitReceivers(): List<ClassDescriptor> = scriptImplicitReceivers()
|
||||
|
||||
private val scriptProvidedProperties: () -> ScriptProvidedPropertiesDescriptor = resolveSession.storageManager.createLazyValue {
|
||||
ScriptProvidedPropertiesDescriptor(this)
|
||||
}
|
||||
|
||||
override fun getScriptProvidedProperties(): List<PropertyDescriptor> = scriptProvidedProperties().properties()
|
||||
|
||||
private val scriptOuterScope: () -> LexicalScope = resolveSession.storageManager.createLazyValue {
|
||||
var outerScope = super.getOuterScope()
|
||||
val outerScopeReceivers = implicitReceivers.let {
|
||||
if (scriptDefinition().providedProperties.isEmpty()) {
|
||||
it
|
||||
} else {
|
||||
it + ScriptProvidedPropertiesDescriptor(this)
|
||||
}
|
||||
}
|
||||
for (receiverClassDescriptor in outerScopeReceivers.asReversed()) {
|
||||
outerScope = LexicalScopeImpl(
|
||||
outerScope,
|
||||
receiverClassDescriptor,
|
||||
true,
|
||||
receiverClassDescriptor.thisAsReceiverParameter,
|
||||
LexicalScopeKind.CLASS_MEMBER_SCOPE
|
||||
)
|
||||
}
|
||||
outerScope
|
||||
}
|
||||
|
||||
override fun getOuterScope(): LexicalScope = scriptOuterScope()
|
||||
|
||||
private val scriptClassAnnotations: () -> Annotations = resolveSession.storageManager.createLazyValue {
|
||||
baseClassDescriptor()?.annotations?.let { ann ->
|
||||
FilteredAnnotations(ann) { fqname ->
|
||||
val shortName = fqname.shortName().identifier
|
||||
// TODO: consider more precise annotation filtering
|
||||
!shortName.startsWith("KotlinScript") && !shortName.startsWith("ScriptTemplate")
|
||||
}
|
||||
} ?: super.annotations
|
||||
}
|
||||
|
||||
override val annotations: Annotations
|
||||
get() = scriptClassAnnotations()
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.compiler.plugin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class ReplResultPropertyDescriptor(
|
||||
name: Name,
|
||||
kotlinType: KotlinType,
|
||||
receiver: ReceiverParameterDescriptor?,
|
||||
script: ScriptDescriptor,
|
||||
source: SourceElement
|
||||
) : PropertyDescriptorImpl(
|
||||
script,
|
||||
null,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
Visibilities.PUBLIC,
|
||||
false,
|
||||
name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
source,
|
||||
/* lateInit = */ false, /* isConst = */ false, /* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false,
|
||||
/* isDelegated = */ false
|
||||
) {
|
||||
init {
|
||||
setType(kotlinType, emptyList(), receiver, null)
|
||||
initialize(
|
||||
null, null
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. 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.compiler.plugin.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.utils.Printer
|
||||
|
||||
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 = Visibilities.PUBLIC
|
||||
setTypeParameterDescriptors(emptyList())
|
||||
createTypeConstructor()
|
||||
}
|
||||
|
||||
private val memberScope: () -> ScriptProvidedPropertiesMemberScope = script.resolveSession.storageManager.createLazyValue {
|
||||
ScriptProvidedPropertiesMemberScope(
|
||||
script.name.identifier,
|
||||
properties()
|
||||
)
|
||||
}
|
||||
|
||||
override fun getUnsubstitutedMemberScope(): MemberScope = memberScope()
|
||||
|
||||
val properties: () -> List<ScriptProvidedPropertyDescriptor> = script.resolveSession.storageManager.createLazyValue {
|
||||
script.scriptDefinition().providedProperties.mapNotNull { (name, type) ->
|
||||
script.findTypeDescriptor(type, Errors.MISSING_SCRIPT_PROVIDED_PROPERTY_CLASS)?.let {
|
||||
name 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")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.compiler.plugin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class ScriptProvidedPropertyDescriptor(
|
||||
name: Name,
|
||||
typeDescriptor: ClassDescriptor,
|
||||
receiver: ReceiverParameterDescriptor?,
|
||||
isVar: Boolean,
|
||||
script: ScriptDescriptor
|
||||
) : PropertyDescriptorImpl(
|
||||
script,
|
||||
null,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
Visibilities.PRIVATE,
|
||||
isVar,
|
||||
name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE,
|
||||
/* lateInit = */ false, /* isConst = */ false, /* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false,
|
||||
/* isDelegated = */ false
|
||||
) {
|
||||
init {
|
||||
setType(typeDescriptor.defaultType, emptyList(), receiver, null)
|
||||
initialize(
|
||||
makePropertyGetterDescriptor(),
|
||||
if (!isVar) null else makePropertySetterDescriptor()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun PropertyDescriptorImpl.makePropertyGetterDescriptor() =
|
||||
PropertyGetterDescriptorImpl(
|
||||
this,
|
||||
Annotations.EMPTY,
|
||||
this.modality,
|
||||
this.visibility,
|
||||
/* isDefault = */
|
||||
false, /* isExternal = */
|
||||
false, /* isInline = */
|
||||
false,
|
||||
this.kind,
|
||||
null,
|
||||
SourceElement.NO_SOURCE
|
||||
).also {
|
||||
it.initialize(returnType)
|
||||
}
|
||||
|
||||
private fun PropertyDescriptorImpl.makePropertySetterDescriptor() =
|
||||
PropertySetterDescriptorImpl(
|
||||
this,
|
||||
Annotations.EMPTY,
|
||||
this.modality,
|
||||
this.visibility,
|
||||
/* isDefault = */
|
||||
false, /* isExternal = */
|
||||
false, /* isInline = */
|
||||
false,
|
||||
this.kind,
|
||||
null,
|
||||
SourceElement.NO_SOURCE
|
||||
).also {
|
||||
it.initialize(
|
||||
ValueParameterDescriptorImpl(
|
||||
this,
|
||||
null,
|
||||
0,
|
||||
Annotations.EMPTY,
|
||||
Name.special("<set-?>"),
|
||||
returnType,
|
||||
/* declaresDefaultValue = */
|
||||
false, /* isCrossinline = */
|
||||
false, /* isNoinline = */
|
||||
false,
|
||||
null,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.compiler.plugin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
|
||||
val KClass<*>.classId: ClassId
|
||||
get() = this.java.enclosingClass?.kotlin?.classId?.createNestedClassId(Name.identifier(simpleName!!))
|
||||
?: ClassId.topLevel(FqName(qualifiedName!!))
|
||||
|
||||
val KType.classId: ClassId?
|
||||
get() = classifier?.let { it as? KClass<*> }?.classId
|
||||
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
|
||||
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.resolve.LazyScriptDescriptor
|
||||
|
||||
class ScriptingResolveExtension : SyntheticResolveExtension {
|
||||
override fun generateSyntheticClasses(
|
||||
|
||||
Reference in New Issue
Block a user