Fixes and refactorings after review

This commit is contained in:
Ilya Chernikov
2016-08-09 19:35:08 +02:00
parent 295f2fd40a
commit 46a7c706e1
15 changed files with 89 additions and 86 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ and related functionality, except the following parts:
- `@file:ScriptTemplate` annotation is not supported - `@file:ScriptTemplate` annotation is not supported
- the parameters `javaHome` and `scripts` from `KotlinScriptExternalDependencies` are not used yet - the parameters `javaHome` and `scripts` from `KotlinScriptExternalDependencies` are not used yet
- Implement support for custom template-based scripts in IDEA: resolving, completion and navigation to symbols from script classpath and sources - Implement support for custom template-based scripts in IDEA: resolving, completion and navigation to symbols from script classpath and sources
- Implement GradleScriptTemplateProvider extension that supplies a script template if gradle with - Implement GradleScriptTemplatesProvider extension that supplies a script template if gradle with
[kotlin script support](https://github.com/gradle/gradle-script-kotlin) is used in the project [kotlin script support](https://github.com/gradle/gradle-script-kotlin) is used in the project
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.codegen.binding.MutableClosure;
import org.jetbrains.kotlin.codegen.context.*; import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension; import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil; import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter; import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -41,7 +40,6 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
@@ -63,11 +61,12 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.org.objectweb.asm.*; import org.jetbrains.org.objectweb.asm.FieldVisitor;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method; import org.jetbrains.org.objectweb.asm.commons.Method;
@@ -247,18 +246,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Override @Override
protected void generateKotlinMetadataAnnotation() { protected void generateKotlinMetadataAnnotation() {
final DescriptorSerializer serializer = generateKotlinClassMetadataAnnotation(descriptor);
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings(), state));
final ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.CLASS, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, classProto);
return Unit.INSTANCE;
}
});
} }
private void writeEnclosingMethod() { private void writeEnclosingMethod() {
@@ -18,12 +18,15 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import kotlin.Unit;
import kotlin.jvm.functions.Function0; import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.codegen.context.*; import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.inline.*; import org.jetbrains.kotlin.codegen.inline.*;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
@@ -33,10 +36,13 @@ import org.jetbrains.kotlin.fileClasses.FileClasses;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider; import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.load.java.JavaVisibilities; import org.jetbrains.kotlin.load.java.JavaVisibilities;
import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames; import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*; import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
@@ -45,10 +51,13 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt; import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.storage.NotNullLazyValue;
import org.jetbrains.kotlin.types.ErrorUtils; import org.jetbrains.kotlin.types.ErrorUtils;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.Label; import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
@@ -57,8 +66,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*; import java.util.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.calculateInnerClassAccessFlags; import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.kotlin.codegen.ClassBuilderModeUtilKt.shouldGenerateMetadata; import static org.jetbrains.kotlin.codegen.ClassBuilderModeUtilKt.shouldGenerateMetadata;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE; import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE;
@@ -698,4 +706,20 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
return StackValue.onStack(callableMethod.getReturnType()); return StackValue.onStack(callableMethod.getReturnType());
} }
protected void generateKotlinClassMetadataAnnotation(ClassDescriptor descriptor) {
final DescriptorSerializer serializer =
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings(), state));
final ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.CLASS, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, classProto);
return Unit.INSTANCE;
}
});
}
} }
@@ -123,18 +123,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
@Override @Override
protected void generateKotlinMetadataAnnotation() { protected void generateKotlinMetadataAnnotation() {
// TODO: copypaste from ImplementationBodyCodegen, so the script is seen as a KClass by reflection; implement separate kind with proper API // TODO: copypaste from ImplementationBodyCodegen, so the script is seen as a KClass by reflection; implement separate kind with proper API
final DescriptorSerializer serializer = generateKotlinClassMetadataAnnotation(scriptDescriptor);
DescriptorSerializer.create(scriptDescriptor, new JvmSerializerExtension(v.getSerializationBindings(), state));
final ProtoBuf.Class classProto = serializer.classProto(scriptDescriptor).build();
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.CLASS, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, classProto);
return Unit.INSTANCE;
}
});
} }
private void genConstructor( private void genConstructor(
@@ -52,8 +52,8 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
public boolean script; public boolean script;
@Argument(value = "script-templates", description = "Script definition template classes") @Argument(value = "script-templates", description = "Script definition template classes")
@ValueDescription("<comma separated class names>") @ValueDescription("<fully qualified class name[,]>")
public String scriptTemplates; public String[] scriptTemplates;
@Argument(value = "kotlin-home", description = "Path to Kotlin compiler home directory, used for runtime libraries discovery") @Argument(value = "kotlin-home", description = "Path to Kotlin compiler home directory, used for runtime libraries discovery")
@ValueDescription("<path>") @ValueDescription("<path>")
@@ -162,28 +162,18 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
KotlinToJVMBytecodeCompiler.configureSourceRoots(configuration, moduleScript.modules, directory) KotlinToJVMBytecodeCompiler.configureSourceRoots(configuration, moduleScript.modules, directory)
configuration.put(JVMConfigurationKeys.MODULE_XML_FILE, moduleFile) configuration.put(JVMConfigurationKeys.MODULE_XML_FILE, moduleFile)
val scriptResolverEnv = hashMapOf<String, Any?>() val environment = createEnvironmentWithScriptingSupport(rootDisposable, configuration, arguments, messageCollector)
if (!configureScriptDefinitions(arguments, configuration, messageCollector, scriptResolverEnv)) return COMPILATION_ERROR ?: return COMPILATION_ERROR
val environment = createCoreEnvironment(rootDisposable, configuration)
if (messageCollector.hasErrors()) return COMPILATION_ERROR
scriptResolverEnv.put("projectRoot", environment.project.run { basePath ?: baseDir?.canonicalPath }?.let(::File))
KotlinToJVMBytecodeCompiler.compileModules(environment, directory) KotlinToJVMBytecodeCompiler.compileModules(environment, directory)
} }
else if (arguments.script) { else if (arguments.script) {
val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size) val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size)
val scriptResolverEnv = hashMapOf<String, Any?>()
if (!configureScriptDefinitions(arguments, configuration, messageCollector, scriptResolverEnv)) return COMPILATION_ERROR
configuration.put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true) configuration.put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
val environment = createCoreEnvironment(rootDisposable, configuration) val environment = createEnvironmentWithScriptingSupport(rootDisposable, configuration, arguments, messageCollector)
if (messageCollector.hasErrors()) return COMPILATION_ERROR ?: return COMPILATION_ERROR
scriptResolverEnv.put("projectRoot", environment.project.run { basePath ?: baseDir?.canonicalPath }?.let(::File))
return KotlinToJVMBytecodeCompiler.compileAndExecuteScript(environment, paths, scriptArgs) return KotlinToJVMBytecodeCompiler.compileAndExecuteScript(environment, paths, scriptArgs)
} }
@@ -197,13 +187,8 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
} }
} }
val scriptResolverEnv = hashMapOf<String, Any?>() val environment = createEnvironmentWithScriptingSupport(rootDisposable, configuration, arguments, messageCollector)
if (!configureScriptDefinitions(arguments, configuration, messageCollector, scriptResolverEnv)) return COMPILATION_ERROR ?: return COMPILATION_ERROR
val environment = createCoreEnvironment(rootDisposable, configuration)
if (messageCollector.hasErrors()) return COMPILATION_ERROR
scriptResolverEnv.put("projectRoot", environment.project.run { basePath ?: baseDir?.canonicalPath }?.let(::File))
if (environment.getSourceFiles().isEmpty()) { if (environment.getSourceFiles().isEmpty()) {
if (arguments.version) { if (arguments.version) {
@@ -233,30 +218,47 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
} }
} }
private fun createEnvironmentWithScriptingSupport(rootDisposable: Disposable,
configuration: CompilerConfiguration,
arguments: K2JVMCompilerArguments,
messageCollector: MessageCollector
): KotlinCoreEnvironment? {
val scriptResolverEnv = hashMapOf<String, Any?>()
configureScriptDefinitions(arguments, configuration, messageCollector, scriptResolverEnv)
if (!messageCollector.hasErrors()) {
val environment = createCoreEnvironment(rootDisposable, configuration)
if (!messageCollector.hasErrors()) {
scriptResolverEnv.put("projectRoot", environment.project.run { basePath ?: baseDir?.canonicalPath }?.let(::File))
return environment
}
}
return null
}
private fun configureScriptDefinitions(arguments: K2JVMCompilerArguments, private fun configureScriptDefinitions(arguments: K2JVMCompilerArguments,
configuration: CompilerConfiguration, configuration: CompilerConfiguration,
messageCollector: MessageCollector, messageCollector: MessageCollector,
scriptResolverEnv: HashMap<String, Any?>): Boolean { scriptResolverEnv: HashMap<String, Any?>) {
val classpath = configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS).filterIsInstance(JvmClasspathRoot::class.java).mapNotNull { it.file } val classpath = configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS).filterIsInstance(JvmClasspathRoot::class.java).mapNotNull { it.file }
// TODO: consider using escaping to allow kotlin escaped names in class names // TODO: consider using escaping to allow kotlin escaped names in class names
val scriptTemplates = arguments.scriptTemplates?.split(',', ' ') if (arguments.scriptTemplates != null && arguments.scriptTemplates.isNotEmpty()) {
if (scriptTemplates != null && scriptTemplates.isNotEmpty()) {
val classloader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), this.javaClass.classLoader) val classloader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), this.javaClass.classLoader)
var hasErrors = false var hasErrors = false
for (template in scriptTemplates) { for (template in arguments.scriptTemplates) {
try { try {
val cls = classloader.loadClass(template) val cls = classloader.loadClass(template)
val def = KotlinScriptDefinitionFromTemplate(cls.kotlin, null, null, scriptResolverEnv) val def = KotlinScriptDefinitionFromTemplate(cls.kotlin, null, null, scriptResolverEnv)
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, def) configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, def)
messageCollector.report( messageCollector.report(
CompilerMessageSeverity.INFO, CompilerMessageSeverity.INFO,
"Added script definition $template to configuration: files pattern: \"${def.scriptFilePattern}\", resolver: ${def.resolver?.javaClass?.name}", "Added script definition $template to configuration: files pattern = \"${def.scriptFilePattern}\", resolver = ${def.resolver?.javaClass?.name}",
CompilerMessageLocation.NO_LOCATION CompilerMessageLocation.NO_LOCATION
) )
} }
catch (ex: ClassNotFoundException) { catch (ex: ClassNotFoundException) {
messageCollector.report( messageCollector.report(
CompilerMessageSeverity.ERROR, "Cannot find script definition template class $template (used classpath: ${classloader.urLs.joinToString()})", CompilerMessageLocation.NO_LOCATION CompilerMessageSeverity.ERROR, "Cannot find script definition template class $template", CompilerMessageLocation.NO_LOCATION
) )
hasErrors = true hasErrors = true
} }
@@ -272,11 +274,10 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
messageCollector.report( messageCollector.report(
CompilerMessageSeverity.LOGGING, "(Classpath used for templates loading: $classpath)", CompilerMessageLocation.NO_LOCATION CompilerMessageSeverity.LOGGING, "(Classpath used for templates loading: $classpath)", CompilerMessageLocation.NO_LOCATION
) )
return false return
} }
} }
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition) configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition)
return true
} }
private fun createCoreEnvironment(rootDisposable: Disposable, configuration: CompilerConfiguration): KotlinCoreEnvironment { private fun createCoreEnvironment(rootDisposable: Disposable, configuration: CompilerConfiguration): KotlinCoreEnvironment {
@@ -42,24 +42,24 @@ interface ScriptTemplatesProvider {
val environment: Map<String, Any?>? val environment: Map<String, Any?>?
companion object { companion object {
val EP_NAME = ExtensionPointName.create<ScriptTemplatesProvider>("org.jetbrains.kotlin.scriptTemplateProvider") val EP_NAME = ExtensionPointName.create<ScriptTemplatesProvider>("org.jetbrains.kotlin.scriptTemplatesProvider")
} }
} }
fun makeScriptDefsFromTemplateProviderExtensions(project: Project, fun makeScriptDefsFromTemplatesProviderExtensions(project: Project,
errorsHandler: ((ScriptTemplatesProvider, Exception) -> Unit) = { ep, ex -> throw ex } errorsHandler: ((ScriptTemplatesProvider, Exception) -> Unit) = { ep, ex -> throw ex }
): List<KotlinScriptDefinitionFromTemplate> = ): List<KotlinScriptDefinitionFromTemplate> =
makeScriptDefsFromTemplateProviders(Extensions.getArea(project).getExtensionPoint(ScriptTemplatesProvider.EP_NAME).extensions.asIterable(), makeScriptDefsFromTemplatesProviders(Extensions.getArea(project).getExtensionPoint(ScriptTemplatesProvider.EP_NAME).extensions.asIterable(),
errorsHandler) errorsHandler)
fun makeScriptDefsFromTemplateProviders(providers: Iterable<ScriptTemplatesProvider>, fun makeScriptDefsFromTemplatesProviders(providers: Iterable<ScriptTemplatesProvider>,
errorsHandler: ((ScriptTemplatesProvider, Exception) -> Unit) = { ep, ex -> throw ex } errorsHandler: ((ScriptTemplatesProvider, Exception) -> Unit) = { ep, ex -> throw ex }
): List<KotlinScriptDefinitionFromTemplate> { ): List<KotlinScriptDefinitionFromTemplate> {
val idToVersion = hashMapOf<String, Int>() val idToVersion = hashMapOf<String, Int>()
return providers.filter { it.isValid }.sortedByDescending { it.version }.flatMap { provider -> return providers.filter { it.isValid }.sortedByDescending { it.version }.flatMap { provider ->
try { try {
idToVersion.get(provider.id)?.let { ver -> errorsHandler(provider, RuntimeException("Conflicting scriptTemplateProvider ${provider.id}, using one with version $ver")) } idToVersion.get(provider.id)?.let { ver -> errorsHandler(provider, RuntimeException("Conflicting scriptTemplatesProvider ${provider.id}, using one with version $ver")) }
Logger.getInstance("makeScriptDefsFromTemplateProviders") Logger.getInstance("makeScriptDefsFromTemplatesProviders")
.info("[kts] loading script definitions ${provider.templateClassNames} using cp: ${provider.dependenciesClasspath.joinToString(File.pathSeparator)}") .info("[kts] loading script definitions ${provider.templateClassNames} using cp: ${provider.dependenciesClasspath.joinToString(File.pathSeparator)}")
val loader = URLClassLoader(provider.dependenciesClasspath.map { File(it).toURI().toURL() }.toTypedArray(), ScriptTemplatesProvider::class.java.classLoader) val loader = URLClassLoader(provider.dependenciesClasspath.map { File(it).toURI().toURL() }.toTypedArray(), ScriptTemplatesProvider::class.java.classLoader)
provider.templateClassNames.map { provider.templateClassNames.map {
+1 -1
View File
@@ -9,7 +9,7 @@ where possible options include:
-no-reflect Don't include Kotlin reflection implementation into classpath -no-reflect Don't include Kotlin reflection implementation into classpath
-module <path> Path to the module file to compile -module <path> Path to the module file to compile
-script Evaluate the script file -script Evaluate the script file
-script-templates <comma separated class names> -script-templates <fully qualified class name[,]>
Script definition template classes Script definition template classes
-kotlin-home <path> Path to Kotlin compiler home directory, used for runtime libraries discovery -kotlin-home <path> Path to Kotlin compiler home directory, used for runtime libraries discovery
-module-name Module name -module-name Module name
+1 -1
View File
@@ -10,7 +10,7 @@ where possible options include:
-no-reflect Don't include Kotlin reflection implementation into classpath -no-reflect Don't include Kotlin reflection implementation into classpath
-module <path> Path to the module file to compile -module <path> Path to the module file to compile
-script Evaluate the script file -script Evaluate the script file
-script-templates <comma separated class names> -script-templates <fully qualified class name[,]>
Script definition template classes Script definition template classes
-kotlin-home <path> Path to Kotlin compiler home directory, used for runtime libraries discovery -kotlin-home <path> Path to Kotlin compiler home directory, used for runtime libraries discovery
-module-name Module name -module-name Module name
@@ -100,7 +100,7 @@ class KotlinScriptConfigurationManager(
fun getAllLibrarySourcesScope() = NonClasspathDirectoriesScope(getAllLibrarySources()) fun getAllLibrarySourcesScope() = NonClasspathDirectoriesScope(getAllLibrarySources())
private fun reloadScriptDefinitions() { private fun reloadScriptDefinitions() {
(makeScriptDefsFromTemplateProviderExtensions(project, { ep, ex -> log.warn("[kts] Error loading definition from ${ep.id}", ex) }) + (makeScriptDefsFromTemplatesProviderExtensions(project, { ep, ex -> log.warn("[kts] Error loading definition from ${ep.id}", ex) }) +
loadScriptConfigsFromProjectRoot(File(project.basePath ?: "")).map { KotlinConfigurableScriptDefinition(it, kotlinEnvVars) }).let { loadScriptConfigsFromProjectRoot(File(project.basePath ?: "")).map { KotlinConfigurableScriptDefinition(it, kotlinEnvVars) }).let {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
scriptDefinitionProvider.setScriptDefinitions(it + StandardScriptDefinition) scriptDefinitionProvider.setScriptDefinitions(it + StandardScriptDefinition)
@@ -29,7 +29,7 @@ import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
import java.io.File import java.io.File
import java.util.* import java.util.*
class GradleScriptTemplateProvider(project: Project): ScriptTemplatesProvider { class GradleScriptTemplatesProvider(project: Project): ScriptTemplatesProvider {
private val gradleExeSettings: GradleExecutionSettings? by lazy { private val gradleExeSettings: GradleExecutionSettings? by lazy {
try { try {
@@ -40,11 +40,11 @@ class GradleScriptTemplateProvider(project: Project): ScriptTemplatesProvider {
} }
catch (e: NoClassDefFoundError) { catch (e: NoClassDefFoundError) {
// TODO: consider displaying the warning to the user // TODO: consider displaying the warning to the user
Logger.getInstance(GradleScriptTemplateProvider::class.java).error("[kts] Cannot get gradle execution settings", e) Logger.getInstance(GradleScriptTemplatesProvider::class.java).error("[kts] Cannot get gradle execution settings", e)
null null
} }
catch (e: ClassNotFoundException) { catch (e: ClassNotFoundException) {
Logger.getInstance(GradleScriptTemplateProvider::class.java).error("[kts] Cannot get gradle execution settings", e) Logger.getInstance(GradleScriptTemplatesProvider::class.java).error("[kts] Cannot get gradle execution settings", e)
null // see todo above null // see todo above
} }
} }
+1 -1
View File
@@ -34,7 +34,7 @@
<extensionPoint name="storageComponentContainerContributor" <extensionPoint name="storageComponentContainerContributor"
interface="org.jetbrains.kotlin.extensions.StorageComponentContainerContributor" interface="org.jetbrains.kotlin.extensions.StorageComponentContainerContributor"
area="IDEA_PROJECT"/> area="IDEA_PROJECT"/>
<extensionPoint name="scriptTemplateProvider" <extensionPoint name="scriptTemplatesProvider"
interface="org.jetbrains.kotlin.script.ScriptTemplatesProvider" interface="org.jetbrains.kotlin.script.ScriptTemplatesProvider"
area="IDEA_PROJECT"/> area="IDEA_PROJECT"/>
</extensionPoints> </extensionPoints>
+2 -2
View File
@@ -11,7 +11,7 @@
<!-- diagnosticSuppressor decelerated in common.xml --> <!-- diagnosticSuppressor decelerated in common.xml -->
<diagnosticSuppressor implementation="org.jetbrains.kotlin.idea.debugger.DiagnosticSuppressorForDebugger"/> <diagnosticSuppressor implementation="org.jetbrains.kotlin.idea.debugger.DiagnosticSuppressorForDebugger"/>
<scriptTemplateProvider implementation="org.jetbrains.kotlin.idea.core.script.GradleScriptTemplateProvider"/> <scriptTemplatesProvider implementation="org.jetbrains.kotlin.idea.core.script.GradleScriptTemplatesProvider"/>
<scriptTemplateProvider implementation="org.jetbrains.kotlin.idea.script.ScriptTemplatesFromCompilerSettingsProvider"/> <scriptTemplatesProvider implementation="org.jetbrains.kotlin.idea.script.ScriptTemplatesFromCompilerSettingsProvider"/>
</extensions> </extensions>
</idea-plugin> </idea-plugin>
@@ -33,8 +33,7 @@ class ScriptTemplatesFromCompilerSettingsProvider(project: Project): ScriptTempl
override val templateClassNames: Iterable<String> get() = kotlinSettings.scriptTemplates.split(',', ' ') override val templateClassNames: Iterable<String> get() = kotlinSettings.scriptTemplates.split(',', ' ')
override val dependenciesClasspath: Iterable<String> get() = kotlinSettings.scriptTemplatesClasspath.split(File.pathSeparator) override val dependenciesClasspath: Iterable<String> get() = kotlinSettings.scriptTemplatesClasspath.split(File.pathSeparator)
override val environment: Map<String, Any?>? by lazy { mapOf( override val environment: Map<String, Any?>? by lazy { mapOf(
"projectRoot" to (project.basePath ?: project.baseDir.canonicalPath)?.let(::File), "projectRoot" to (project.basePath ?: project.baseDir.canonicalPath)?.let(::File))
"getScriptSectionTokens" to ::topLevelSectionCodeTextTokens)
} }
} }
@@ -192,10 +192,12 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
args.languageVersion = kotlinOptions.languageVersion args.languageVersion = kotlinOptions.languageVersion
args.jvmTarget = kotlinOptions.jvmTarget args.jvmTarget = kotlinOptions.jvmTarget
args.allowKotlinPackage = kotlinOptions.allowKotlinPackage args.allowKotlinPackage = kotlinOptions.allowKotlinPackage
args.reportPerf = kotlinOptions.reportPerf
args.scriptTemplates = kotlinOptions.scriptTemplates args.scriptTemplates = kotlinOptions.scriptTemplates
if (args.scriptTemplates?.isNotBlank() ?: false) { if (args.scriptTemplates?.isNotEmpty() ?: false) {
logger.kotlinDebug { "scriptTemplates = ${args.scriptTemplates}" } logger.kotlinDebug { "scriptTemplates = ${args.scriptTemplates.joinToString()}" }
} }
fun addFriendPathForTestTask(friendKotlinTaskName: String) { fun addFriendPathForTestTask(friendKotlinTaskName: String) {