Fixes after review

This commit is contained in:
Ilya Chernikov
2018-07-06 16:36:07 +02:00
parent 5d597eb382
commit 9549736d35
6 changed files with 26 additions and 40 deletions
@@ -111,12 +111,10 @@ class ScriptCodegen private constructor(
fun genFieldFromArrayElement(descriptor: ClassDescriptor, paramIndex: Int, elementIndex: Int, name: String) { fun genFieldFromArrayElement(descriptor: ClassDescriptor, paramIndex: Int, elementIndex: Int, name: String) {
val elementClassType = typeMapper.mapClass(descriptor) val elementClassType = typeMapper.mapClass(descriptor)
iv.load(0, classType) val array = StackValue.local(paramIndex, AsmUtil.getArrayType(OBJECT_TYPE))
iv.load(paramIndex, elementClassType) val value = StackValue.arrayElement(OBJECT_TYPE, null, array, StackValue.constant(elementIndex, Type.INT_TYPE))
iv.aconst(elementIndex) val field = StackValue.field(elementClassType, classType, name, false, StackValue.local(0, classType))
iv.aload(OBJECT_TYPE) field.store(value, iv)
iv.checkcast(elementClassType)
iv.putfield(classType.internalName, name, elementClassType.descriptor)
} }
if (!scriptContext.earlierScripts.isEmpty()) { if (!scriptContext.earlierScripts.isEmpty()) {
@@ -16,9 +16,10 @@
package org.jetbrains.kotlin.script package org.jetbrains.kotlin.script
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.NotFoundClasses
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.descriptors.findNonGenericClassAcrossDependencies
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.lazy.descriptors.script.classId import org.jetbrains.kotlin.resolve.lazy.descriptors.script.classId
@@ -36,22 +37,10 @@ fun KotlinScriptDefinition.getScriptParameters(scriptDescriptor: ScriptDescripto
?: emptyList() ?: emptyList()
fun getKotlinTypeByKClass(scriptDescriptor: ScriptDescriptor, kClass: KClass<out Any>): KotlinType = fun getKotlinTypeByKClass(scriptDescriptor: ScriptDescriptor, kClass: KClass<out Any>): KotlinType =
getClassDescriptorByKClassOrMock(scriptDescriptor, kClass).defaultType
fun getClassDescriptorByKClass(scriptDescriptor: ScriptDescriptor, kClass: KClass<out Any>): ClassDescriptor? =
scriptDescriptor.module.findClassAcrossModuleDependencies(kClass.classId)
fun getMockClassDescriptor(scriptDescriptor: ScriptDescriptor, kClass: KClass<out Any>): ClassDescriptor {
val classId = kClass.classId
val typeParametersCount = generateSequence(classId, ClassId::getOuterClassId).map { 0 }.toList()
return NotFoundClasses(LockBasedStorageManager.NO_LOCKS, scriptDescriptor.module).getClass(classId, typeParametersCount)
}
fun getClassDescriptorByKClassOrMock(scriptDescriptor: ScriptDescriptor, kClass: KClass<out Any>): ClassDescriptor =
scriptDescriptor.module.findNonGenericClassAcrossDependencies( scriptDescriptor.module.findNonGenericClassAcrossDependencies(
kClass.classId, kClass.classId,
NotFoundClasses(LockBasedStorageManager.NO_LOCKS, scriptDescriptor.module) NotFoundClasses(LockBasedStorageManager.NO_LOCKS, scriptDescriptor.module)
) ).defaultType
// TODO: support star projections // TODO: support star projections
// TODO: support annotations on types and type parameters // TODO: support annotations on types and type parameters
@@ -54,7 +54,7 @@ class LazyScriptClassMemberScope(
val constructorDescriptor = ClassConstructorDescriptorImpl.create( val constructorDescriptor = ClassConstructorDescriptorImpl.create(
scriptDescriptor, annotations, baseConstructorDescriptor.isPrimary, scriptDescriptor.source scriptDescriptor, annotations, baseConstructorDescriptor.isPrimary, scriptDescriptor.source
) )
var paramsIndexBase = baseConstructorDescriptor.valueParameters.let { if (it.isEmpty()) 0 else it.last().index + 1 } var paramsIndexBase = baseConstructorDescriptor.valueParameters.lastIndex + 1
val syntheticParameters = val syntheticParameters =
listOf(implicitReceiversParamType, environmentVarsParamType).mapNotNull { param: Pair<String, KotlinType>? -> listOf(implicitReceiversParamType, environmentVarsParamType).mapNotNull { param: Pair<String, KotlinType>? ->
if (param == null) null if (param == null) null
@@ -20,9 +20,6 @@ import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_MISC_JAR
import java.io.File import java.io.File
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.script.experimental.annotations.KotlinScript import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.annotations.KotlinScriptDefaultCompilationConfiguration
import kotlin.script.experimental.api.ScriptCompileConfigurationProperties
import kotlin.script.experimental.util.TypedKey
class CustomScriptCodegenTest : CodegenTestCase() { class CustomScriptCodegenTest : CodegenTestCase() {
@@ -54,7 +51,7 @@ class CustomScriptCodegenTest : CodegenTestCase() {
arrayOf( arrayOf(
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR, KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
KOTLIN_SCRIPTING_JVM_JAR, KOTLIN_SCRIPTING_MISC_JAR KOTLIN_SCRIPTING_JVM_JAR, KOTLIN_SCRIPTING_MISC_JAR
).mapNotNull { File(libPath, it).takeIf { it.exists() } } ).mapNotNull { File(libPath, it).also { assertTrue("$it not found", it.exists()) } }
} }
val configuration = createConfiguration( val configuration = createConfiguration(
@@ -65,7 +65,7 @@ internal fun discoverScriptTemplatesInClasspath(
if (it.isDirectory || !it.name.startsWith(SCRIPT_DEFINITION_MARKERS_PATH)) null if (it.isDirectory || !it.name.startsWith(SCRIPT_DEFINITION_MARKERS_PATH)) null
else it.name.removePrefix(SCRIPT_DEFINITION_MARKERS_PATH) else it.name.removePrefix(SCRIPT_DEFINITION_MARKERS_PATH)
}.toList() }.toList()
val (loadedDefinitions, _, notFoundClasses) = val (loadedDefinitions, notFoundClasses) =
definitionNames.partitionLoadJarDefinitions(jar, loader, scriptResolverEnv, messageCollector) definitionNames.partitionLoadJarDefinitions(jar, loader, scriptResolverEnv, messageCollector)
if (notFoundClasses.isNotEmpty()) { if (notFoundClasses.isNotEmpty()) {
messageCollector.report( messageCollector.report(
@@ -83,7 +83,7 @@ internal fun discoverScriptTemplatesInClasspath(
defferedDirDependencies.add(dep) // there is no way to know that the dependency is fully "used" so we add it to the list anyway defferedDirDependencies.add(dep) // there is no way to know that the dependency is fully "used" so we add it to the list anyway
val discoveryDir = File(dep, SCRIPT_DEFINITION_MARKERS_PATH) val discoveryDir = File(dep, SCRIPT_DEFINITION_MARKERS_PATH)
if (discoveryDir.isDirectory) { if (discoveryDir.isDirectory) {
val (foundDefinitionClasses, _, notFoundDefinitions) = discoveryDir.listFiles().map { it.name } val (foundDefinitionClasses, notFoundDefinitions) = discoveryDir.listFiles().map { it.name }
.partitionLoadDirDefinitions(dep, loader, scriptResolverEnv, messageCollector) .partitionLoadDirDefinitions(dep, loader, scriptResolverEnv, messageCollector)
foundDefinitionClasses.forEach { foundDefinitionClasses.forEach {
yield(it) yield(it)
@@ -97,7 +97,9 @@ internal fun discoverScriptTemplatesInClasspath(
} }
} }
} catch (e: IOException) { } catch (e: IOException) {
messageCollector.report(CompilerMessageSeverity.WARNING, "Configure scripting: unable to process classpath entry $dep: $e") messageCollector.report(
CompilerMessageSeverity.STRONG_WARNING, "Configure scripting: unable to process classpath entry $dep: $e"
)
} }
} }
var remainingDefinitionCandidates: List<String> = defferedDefinitionCandidates var remainingDefinitionCandidates: List<String> = defferedDefinitionCandidates
@@ -111,7 +113,9 @@ internal fun discoverScriptTemplatesInClasspath(
} }
remainingDefinitionCandidates = notFoundDefinitions remainingDefinitionCandidates = notFoundDefinitions
} catch (e: IOException) { } catch (e: IOException) {
messageCollector.report(CompilerMessageSeverity.WARNING, "Configure scripting: unable to process classpath entry $dep: $e") messageCollector.report(
CompilerMessageSeverity.STRONG_WARNING, "Configure scripting: unable to process classpath entry $dep: $e"
)
} }
} }
if (remainingDefinitionCandidates.isNotEmpty()) { if (remainingDefinitionCandidates.isNotEmpty()) {
@@ -147,7 +151,7 @@ internal fun loadScriptTemplatesFromClasspath(
if (remainingTemplates.isEmpty()) break if (remainingTemplates.isEmpty()) break
try { try {
val (loadedDefinitions, _, notFoundTemplates) = when { val (loadedDefinitions, notFoundTemplates) = when {
dep.isFile && dep.extension == "jar" -> { // checking for extension is the compiler current behaviour, so the same logic is implemented here dep.isFile && dep.extension == "jar" -> { // checking for extension is the compiler current behaviour, so the same logic is implemented here
JarFile(dep).use { jar -> JarFile(dep).use { jar ->
remainingTemplates.partitionLoadJarDefinitions(jar, classpathAndLoader, scriptResolverEnv, messageCollector) remainingTemplates.partitionLoadJarDefinitions(jar, classpathAndLoader, scriptResolverEnv, messageCollector)
@@ -159,7 +163,7 @@ internal fun loadScriptTemplatesFromClasspath(
else -> { else -> {
// assuming that invalid classpath entries will be reported elsewhere anyway, so do not spam user with additional warnings here // assuming that invalid classpath entries will be reported elsewhere anyway, so do not spam user with additional warnings here
messageCollector.report(CompilerMessageSeverity.LOGGING, "Configure scripting: Unknown classpath entry $dep") messageCollector.report(CompilerMessageSeverity.LOGGING, "Configure scripting: Unknown classpath entry $dep")
DefinitionsLoadPartitionResult(listOf(), listOf(), remainingTemplates) DefinitionsLoadPartitionResult(listOf(), remainingTemplates)
} }
} }
if (loadedDefinitions.isNotEmpty()) { if (loadedDefinitions.isNotEmpty()) {
@@ -170,7 +174,7 @@ internal fun loadScriptTemplatesFromClasspath(
} }
} catch (e: IOException) { } catch (e: IOException) {
messageCollector.report( messageCollector.report(
CompilerMessageSeverity.WARNING, CompilerMessageSeverity.STRONG_WARNING,
"Configure scripting: unable to process classpath entry $dep: $e" "Configure scripting: unable to process classpath entry $dep: $e"
) )
} }
@@ -186,7 +190,6 @@ internal fun loadScriptTemplatesFromClasspath(
private data class DefinitionsLoadPartitionResult( private data class DefinitionsLoadPartitionResult(
val loaded: List<KotlinScriptDefinition>, val loaded: List<KotlinScriptDefinition>,
val notLoaded: List<String>,
val notFound: List<String> val notFound: List<String>
) )
@@ -197,7 +200,6 @@ private inline fun List<String>.partitionLoadDefinitions(
getBytes: (String) -> ByteArray? getBytes: (String) -> ByteArray?
): DefinitionsLoadPartitionResult { ): DefinitionsLoadPartitionResult {
val loaded = ArrayList<KotlinScriptDefinition>() val loaded = ArrayList<KotlinScriptDefinition>()
val notLoaded = ArrayList<String>()
val notFound = ArrayList<String>() val notFound = ArrayList<String>()
for (definitionName in this) { for (definitionName in this) {
val classBytes = getBytes(definitionName) val classBytes = getBytes(definitionName)
@@ -206,11 +208,11 @@ private inline fun List<String>.partitionLoadDefinitions(
} }
when { when {
definition != null -> loaded.add(definition) definition != null -> loaded.add(definition)
classBytes != null -> notLoaded.add(definitionName) classBytes != null -> {}
else -> notFound.add(definitionName) else -> notFound.add(definitionName)
} }
} }
return DefinitionsLoadPartitionResult(loaded, notLoaded, notFound) return DefinitionsLoadPartitionResult(loaded, notFound)
} }
private fun List<String>.partitionLoadJarDefinitions( private fun List<String>.partitionLoadJarDefinitions(
@@ -302,8 +304,8 @@ private fun loadScriptDefinition(
} }
private class LazyClasspathWithClassLoader(baseClassLoader: ClassLoader, getClasspath: () -> List<File>) { private class LazyClasspathWithClassLoader(baseClassLoader: ClassLoader, getClasspath: () -> List<File>) {
val classpath by lazy(LazyThreadSafetyMode.PUBLICATION) { getClasspath() } val classpath by lazy { getClasspath() }
val classLoader by lazy(LazyThreadSafetyMode.PUBLICATION) { val classLoader by lazy {
URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), baseClassLoader) URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), baseClassLoader)
} }
} }
@@ -1,5 +1,5 @@
import kotlin.script.templates.* import kotlin.script.templates.*
@ScriptTemplateAdditionalCompilerArguments(["-v"]) @ScriptTemplateAdditionalCompilerArguments(["-version"])
abstract class TestScriptWithOtherAnnotation abstract class TestScriptWithOtherAnnotation