[scripting] Move earlierScripts to the frontend descriptor
^KT-20488 fixed
This commit is contained in:
+4
@@ -17,4 +17,8 @@ public class ScriptPriorities {
|
||||
Integer priority = script.getUserData(PRIORITY_KEY);
|
||||
return priority == null ? 0 : priority;
|
||||
}
|
||||
|
||||
public static boolean isReplScript(@NotNull KtScript script) {
|
||||
return script.getUserData(PRIORITY_KEY) != null;
|
||||
}
|
||||
}
|
||||
|
||||
+28
-11
@@ -40,10 +40,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.addImportingScope
|
||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptPriorities
|
||||
import org.jetbrains.kotlin.scripting.definitions.findScriptCompilationConfiguration
|
||||
import org.jetbrains.kotlin.scripting.definitions.*
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
@@ -120,6 +117,7 @@ class LazyScriptDescriptor(
|
||||
override fun getSource() = sourceElement
|
||||
|
||||
private val priority: Int = ScriptPriorities.getScriptPriority(scriptInfo.script)
|
||||
private val isReplScript: Boolean = ScriptPriorities.isReplScript(scriptInfo.script)
|
||||
|
||||
override fun getPriority() = priority
|
||||
|
||||
@@ -290,6 +288,7 @@ class LazyScriptDescriptor(
|
||||
|
||||
internal class ConstructorWithParams(
|
||||
val constructor: ClassConstructorDescriptorImpl,
|
||||
val earlierScriptsParameter: ValueParameterDescriptor?,
|
||||
val baseClassConstructorParameters: List<ValueParameterDescriptor>,
|
||||
val implicitReceiversParameters: List<ValueParameterDescriptor>,
|
||||
val scriptProvidedPropertiesParameters: List<ValueParameterDescriptor>
|
||||
@@ -305,46 +304,60 @@ class LazyScriptDescriptor(
|
||||
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
|
||||
Name.identifier(receiverName) to receiver.defaultType
|
||||
}
|
||||
|
||||
val providedPropertiesParamTypes =
|
||||
scriptProvidedProperties().map {
|
||||
it.name.identifier to it.type
|
||||
it.name to it.type
|
||||
}
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.create(this, inheritedAnnotations, true, source)
|
||||
|
||||
var paramsIndexBase = baseExplicitParameters.lastIndex + 1
|
||||
var paramsIndexBase = 0
|
||||
|
||||
fun createValueParameter(param: Pair<String, org.jetbrains.kotlin.types.KotlinType>) =
|
||||
fun createValueParameter(param: Pair<Name, org.jetbrains.kotlin.types.KotlinType>) =
|
||||
ValueParameterDescriptorImpl(
|
||||
constructorDescriptor,
|
||||
null,
|
||||
paramsIndexBase++,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier(param.first),
|
||||
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 earlierScriptsParameter = if (isReplScript) {
|
||||
createValueParameter(Name.special("<earlierScripts>") to builtIns.array.defaultType)
|
||||
} else null
|
||||
|
||||
val explicitParameters = baseExplicitParameters.map { it.copy(constructorDescriptor, it.name, paramsIndexBase++) }
|
||||
val implicitReceiversParameters = implicitReceiversParamTypes.map(::createValueParameter)
|
||||
val providedPropertiesParameters = providedPropertiesParamTypes.map(::createValueParameter)
|
||||
|
||||
constructorDescriptor.initialize(
|
||||
explicitParameters + implicitReceiversParameters + providedPropertiesParameters, DescriptorVisibilities.PUBLIC
|
||||
buildList {
|
||||
earlierScriptsParameter?.let { add(it) }
|
||||
addAll(explicitParameters)
|
||||
addAll(implicitReceiversParameters)
|
||||
addAll(providedPropertiesParameters)
|
||||
},
|
||||
DescriptorVisibilities.PUBLIC
|
||||
)
|
||||
constructorDescriptor.returnType = defaultType()
|
||||
|
||||
ConstructorWithParams(
|
||||
constructorDescriptor,
|
||||
earlierScriptsParameter = earlierScriptsParameter,
|
||||
baseClassConstructorParameters = explicitParameters,
|
||||
implicitReceiversParameters = implicitReceiversParameters,
|
||||
scriptProvidedPropertiesParameters = providedPropertiesParameters
|
||||
)
|
||||
}
|
||||
|
||||
override fun getEarlierScriptsConstructorParameter(): ValueParameterDescriptor? =
|
||||
scriptPrimaryConstructorWithParams().earlierScriptsParameter
|
||||
|
||||
override fun getExplicitConstructorParameters(): List<ValueParameterDescriptor> =
|
||||
scriptPrimaryConstructorWithParams().baseClassConstructorParameters
|
||||
|
||||
@@ -384,4 +397,8 @@ class LazyScriptDescriptor(
|
||||
|
||||
override val annotations: Annotations
|
||||
get() = scriptClassAnnotations()
|
||||
|
||||
override fun isReplScript(): Boolean {
|
||||
return isReplScript
|
||||
}
|
||||
}
|
||||
|
||||
+11
-7
@@ -100,12 +100,20 @@ open class ReplCodeAnalyzerBase(
|
||||
|
||||
fun reset(): List<SourceCodeByReplLine> = replState.reset()
|
||||
|
||||
fun analyzeReplLine(psiFile: KtFile, codeLine: ReplCodeLine): ReplLineAnalysisResult {
|
||||
protected fun prepareForAnalyze(
|
||||
psiFile: KtFile,
|
||||
priority: Int
|
||||
) {
|
||||
topDownAnalysisContext.scripts.clear()
|
||||
trace.clearDiagnostics()
|
||||
|
||||
psiFile.script!!.putUserData(ScriptPriorities.PRIORITY_KEY, codeLine.no)
|
||||
val script = psiFile.script!!
|
||||
|
||||
script.putUserData(ScriptPriorities.PRIORITY_KEY, priority)
|
||||
}
|
||||
|
||||
fun analyzeReplLine(psiFile: KtFile, codeLine: ReplCodeLine): ReplLineAnalysisResult {
|
||||
prepareForAnalyze(psiFile, codeLine.no)
|
||||
return doAnalyze(psiFile, emptyList(), codeLine.toSourceCode())
|
||||
}
|
||||
|
||||
@@ -115,11 +123,7 @@ open class ReplCodeAnalyzerBase(
|
||||
codeLine: SourceCode,
|
||||
priority: Int
|
||||
): ReplLineAnalysisResult {
|
||||
topDownAnalysisContext.scripts.clear()
|
||||
trace.clearDiagnostics()
|
||||
|
||||
psiFile.script!!.putUserData(ScriptPriorities.PRIORITY_KEY, priority)
|
||||
|
||||
prepareForAnalyze(psiFile, priority)
|
||||
return doAnalyze(psiFile, importedScripts, codeLine.addNo(priority))
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ dependencies {
|
||||
|
||||
testImplementation(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
|
||||
testImplementation(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm"))
|
||||
testImplementation(project(":kotlin-reflect"))
|
||||
testRuntimeOnly(project(":kotlin-compiler"))
|
||||
testRuntimeOnly(commonDep("org.jetbrains.intellij.deps", "trove4j"))
|
||||
testRuntimeOnly(project(":kotlin-scripting-ide-common")) { isTransitive = false }
|
||||
|
||||
+15
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.scripting.ide_services.test_util.*
|
||||
import java.io.File
|
||||
import kotlin.io.path.*
|
||||
import kotlin.reflect.full.isSubclassOf
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
||||
import kotlin.script.experimental.jvm.jvm
|
||||
@@ -325,6 +326,20 @@ class JvmIdeServicesTest : TestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
fun testAnonymousObjectReflection() {
|
||||
JvmTestRepl()
|
||||
.use { repl ->
|
||||
assertEvalResult(repl, "42", 42)
|
||||
assertEvalUnit(repl, "val sim = object : ArrayList<String>() {}")
|
||||
|
||||
val compiledSnippet = checkCompile(repl, "sim")
|
||||
val evalResult = repl.eval(compiledSnippet!!)
|
||||
|
||||
val a = (evalResult.valueOrThrow().get().result as ResultValue.Value).value!!
|
||||
assertTrue(a::class.isSubclassOf(List::class))
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalPathApi::class)
|
||||
companion object {
|
||||
private const val MODULE_PATH = "plugins/scripting/scripting-ide-services-test"
|
||||
|
||||
+1
-6
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFil
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzerBase
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptPriorities
|
||||
|
||||
class IdeLikeReplCodeAnalyzer(
|
||||
private val environment: KotlinCoreEnvironment,
|
||||
@@ -44,11 +43,7 @@ class IdeLikeReplCodeAnalyzer(
|
||||
importedScripts: List<KtFile>,
|
||||
priority: Int
|
||||
): ReplLineAnalysisResultWithStateless {
|
||||
topDownAnalysisContext.scripts.clear()
|
||||
trace.clearDiagnostics()
|
||||
|
||||
psiFile.script!!.putUserData(ScriptPriorities.PRIORITY_KEY, priority)
|
||||
|
||||
prepareForAnalyze(psiFile, priority)
|
||||
return doStatelessAnalyze(psiFile, importedScripts)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user