Fixes and refactorings after review
This commit is contained in:
+1
-1
@@ -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(
|
||||||
|
|||||||
+2
-2
@@ -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 {
|
||||||
|
|||||||
+9
-9
@@ -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 {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -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
@@ -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
|
||||||
|
|||||||
+1
-1
@@ -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)
|
||||||
|
|||||||
+3
-3
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user