Script refactoring, backend: scripts are classes now, remove/refactor 'special code' dealing with scripts
This commit is contained in:
@@ -368,13 +368,6 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
iv.invokestatic(REFLECTION, "getOrCreateKotlinPackage",
|
||||
Type.getMethodDescriptor(K_DECLARATION_CONTAINER_TYPE, getType(Class.class), getType(String.class)), false);
|
||||
}
|
||||
else if (container instanceof ScriptDescriptor) {
|
||||
// TODO: correct container for scripts (KScript?)
|
||||
StackValue value = generateClassLiteralReference(
|
||||
state.getTypeMapper(), ((ScriptDescriptor) container).getClassDescriptor().getDefaultType()
|
||||
);
|
||||
value.put(K_CLASS_TYPE, iv);
|
||||
}
|
||||
else {
|
||||
iv.aconst(null);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegen;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ScriptCodeDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
@@ -311,9 +310,28 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
public void gen(KtElement expr, Type type) {
|
||||
StackValue value = Type.VOID_TYPE.equals(type) ? genStatement(expr) : gen(expr);
|
||||
// for repl store the result of the last line into special field
|
||||
if (value.type != Type.VOID_TYPE && state.getShouldGenerateScriptResultValue()) {
|
||||
ScriptContext context = getScriptContext();
|
||||
if (expr == context.getLastStatement()) {
|
||||
StackValue.Field resultValue = StackValue.field(context.getResultFieldInfo(), StackValue.LOCAL_0);
|
||||
resultValue.store(value, v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
value.put(type, v);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ScriptContext getScriptContext() {
|
||||
CodegenContext context = getContext();
|
||||
while (!(context instanceof ScriptContext)) {
|
||||
context = context.getParentContext();
|
||||
}
|
||||
return (ScriptContext) context;
|
||||
}
|
||||
|
||||
public StackValue genLazy(KtElement expr, Type type) {
|
||||
StackValue value = gen(expr);
|
||||
return StackValue.coercion(value, type);
|
||||
@@ -1968,21 +1986,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (localOrCaptured != null) {
|
||||
return localOrCaptured;
|
||||
}
|
||||
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
if (descriptor instanceof ValueParameterDescriptor && container instanceof ScriptCodeDescriptor) {
|
||||
ScriptCodeDescriptor scriptCodeDescriptor = (ScriptCodeDescriptor) container;
|
||||
ScriptDescriptor scriptDescriptor = (ScriptDescriptor) scriptCodeDescriptor.getContainingDeclaration();
|
||||
Type scriptClassType = asmTypeForScriptDescriptor(bindingContext, scriptDescriptor);
|
||||
ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) descriptor;
|
||||
ClassDescriptor scriptClass = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
|
||||
//noinspection ConstantConditions
|
||||
StackValue script = StackValue.thisOrOuter(this, scriptClass, false, false);
|
||||
Type fieldType = typeMapper.mapType(valueParameterDescriptor);
|
||||
return StackValue.field(fieldType, scriptClassType, valueParameterDescriptor.getName().getIdentifier(), false, script,
|
||||
valueParameterDescriptor);
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
|
||||
}
|
||||
|
||||
@@ -2496,14 +2499,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return StackValue.singleton(receiverDescriptor, typeMapper);
|
||||
}
|
||||
}
|
||||
else if (receiverDescriptor instanceof ScriptDescriptor) {
|
||||
return generateScriptReceiver
|
||||
((ScriptDescriptor) receiverDescriptor);
|
||||
}
|
||||
else {
|
||||
return StackValue.thisOrOuter(this, receiverDescriptor, isSuper,
|
||||
receiverValue instanceof CastImplicitClassReceiver || isEnumEntry(receiverDescriptor));
|
||||
}
|
||||
}
|
||||
else if (receiverValue instanceof ScriptReceiver) {
|
||||
return generateScript((ScriptReceiver) receiverValue);
|
||||
}
|
||||
else if (receiverValue instanceof ExtensionReceiver) {
|
||||
return generateReceiver(((ExtensionReceiver) receiverValue).getDeclarationDescriptor());
|
||||
}
|
||||
@@ -2520,7 +2524,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return context.generateReceiver(descriptor, state, false);
|
||||
}
|
||||
|
||||
private StackValue generateScript(@NotNull ScriptReceiver receiver) {
|
||||
@NotNull
|
||||
private StackValue generateScriptReceiver(@NotNull ScriptDescriptor receiver) {
|
||||
CodegenContext cur = context;
|
||||
StackValue result = StackValue.LOCAL_0;
|
||||
boolean inStartConstructorContext = cur instanceof ConstructorContext;
|
||||
@@ -2532,17 +2537,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (cur instanceof ScriptContext) {
|
||||
ScriptContext scriptContext = (ScriptContext) cur;
|
||||
|
||||
ScriptDescriptor receiverDeclarationDescriptor = receiver.getDeclarationDescriptor();
|
||||
if (scriptContext.getScriptDescriptor() == receiverDeclarationDescriptor) {
|
||||
if (scriptContext.getScriptDescriptor() == receiver) {
|
||||
//TODO lazy
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
Type currentScriptType = asmTypeForScriptDescriptor(bindingContext, scriptContext.getScriptDescriptor());
|
||||
Type classType = asmTypeForScriptDescriptor(bindingContext, receiverDeclarationDescriptor);
|
||||
String fieldName = scriptContext.getScriptFieldName(receiverDeclarationDescriptor);
|
||||
return StackValue.field(classType, currentScriptType, fieldName, false, result, receiverDeclarationDescriptor);
|
||||
}
|
||||
Type currentScriptType = typeMapper.mapType(scriptContext.getScriptDescriptor());
|
||||
Type classType = typeMapper.mapType(receiver);
|
||||
String fieldName = scriptContext.getScriptFieldName(receiver);
|
||||
return StackValue.field(classType, currentScriptType, fieldName, false, result, receiver);
|
||||
}
|
||||
|
||||
result = cur.getOuterExpression(result, false);
|
||||
@@ -2558,7 +2560,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public StackValue generateThisOrOuter(@NotNull ClassDescriptor calleeContainingClass, boolean isSuper) {
|
||||
return generateThisOrOuter(calleeContainingClass, isSuper, false);
|
||||
@@ -3321,19 +3322,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
Type varType = asmType(variableDescriptor.getType());
|
||||
|
||||
StackValue storeTo;
|
||||
if (KtPsiUtil.isScriptDeclaration(variableDeclaration)) {
|
||||
KtScript scriptPsi = KtPsiUtil.getScript(variableDeclaration);
|
||||
assert scriptPsi != null;
|
||||
Type scriptClassType = asmTypeForScriptPsi(bindingContext, scriptPsi);
|
||||
storeTo = StackValue.field(varType, scriptClassType, variableDeclaration.getName(), false, StackValue.LOCAL_0, variableDescriptor);
|
||||
}
|
||||
else if (sharedVarType == null) {
|
||||
storeTo = StackValue.local(index, varType);
|
||||
}
|
||||
else {
|
||||
storeTo = StackValue.shared(index, varType);
|
||||
}
|
||||
StackValue storeTo = sharedVarType == null ? StackValue.local(index, varType) : StackValue.shared(index, varType);
|
||||
|
||||
storeTo.store(initializer, v);
|
||||
}
|
||||
|
||||
@@ -24,40 +24,20 @@ import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.psi.KtScript;
|
||||
import org.jetbrains.kotlin.resolve.ScriptNameUtil;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.registerClassNameForScript;
|
||||
|
||||
public class KotlinCodegenFacade {
|
||||
|
||||
public static void prepareForCompilation(@NotNull GenerationState state) {
|
||||
for (KtFile file : state.getFiles()) {
|
||||
if (file.isScript()) {
|
||||
KtScript script = file.getScript();
|
||||
assert script != null;
|
||||
|
||||
FqName name = ScriptNameUtil.classNameForScript(script);
|
||||
Type type = AsmUtil.asmTypeByFqNameWithoutInnerClasses(name);
|
||||
registerClassNameForScript(state.getBindingTrace(), script, type, state.getFileClassesProvider());
|
||||
}
|
||||
}
|
||||
|
||||
state.beforeCompile();
|
||||
}
|
||||
|
||||
public static void compileCorrectFiles(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull CompilationErrorHandler errorHandler
|
||||
) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
|
||||
prepareForCompilation(state);
|
||||
state.beforeCompile();
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
|
||||
|
||||
@@ -273,13 +273,8 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
String outerClassInternalName = null;
|
||||
if (containing instanceof ClassDescriptor) {
|
||||
outerClassInternalName = typeMapper.mapClass((ClassDescriptor) containing).getInternalName();
|
||||
} /* disabled cause of KT-7775
|
||||
else if (containing instanceof ScriptDescriptor) {
|
||||
outerClassInternalName = asmTypeForScriptDescriptor(bindingContext, (ScriptDescriptor) containing).getInternalName();
|
||||
}*/
|
||||
|
||||
}
|
||||
String innerName = innerClass.getName().isSpecial() ? null : innerClass.getName().asString();
|
||||
|
||||
String innerClassInternalName = typeMapper.mapClass(innerClass).getInternalName();
|
||||
v.visitInnerClass(innerClassInternalName, outerClassInternalName, innerName, calculateInnerClassAccessFlags(innerClass));
|
||||
}
|
||||
@@ -320,10 +315,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
return FileClasses.getFileClassType(fileClassesProvider, element.getContainingKtFile());
|
||||
}
|
||||
}
|
||||
/*disabled cause of KT-7775
|
||||
else if (outermost instanceof ScriptContext) {
|
||||
return asmTypeForScriptDescriptor(bindingContext, ((ScriptContext) outermost).getScriptDescriptor());
|
||||
}*/
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ScriptReceiver
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -52,15 +51,7 @@ public class PropertyReferenceCodegen(
|
||||
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
|
||||
private val asmType = typeMapper.mapClass(classDescriptor)
|
||||
|
||||
private val dispatchReceiverType =
|
||||
when {
|
||||
dispatchReceiver is ScriptReceiver -> {
|
||||
// TODO: fix receiver for scripts, see ScriptReceiver#getType
|
||||
dispatchReceiver.declarationDescriptor.classDescriptor.defaultType
|
||||
}
|
||||
dispatchReceiver.exists() -> dispatchReceiver.type
|
||||
else -> null
|
||||
}
|
||||
private val dispatchReceiverType = if (dispatchReceiver.exists()) dispatchReceiver.type else null
|
||||
|
||||
private val extensionReceiverType = target.extensionReceiverParameter?.type
|
||||
|
||||
|
||||
@@ -23,12 +23,11 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.ScriptContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
@@ -38,8 +37,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLASS_FOR_SCRIPT;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForScriptDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -55,18 +52,16 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
ScriptDescriptor scriptDescriptor = bindingContext.get(BindingContext.SCRIPT, declaration);
|
||||
assert scriptDescriptor != null;
|
||||
|
||||
ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
|
||||
assert classDescriptorForScript != null;
|
||||
Type classType = state.getTypeMapper().mapType(scriptDescriptor);
|
||||
|
||||
Type classType = asmTypeForScriptDescriptor(bindingContext, scriptDescriptor);
|
||||
|
||||
ClassBuilder builder = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(declaration, classDescriptorForScript),
|
||||
ClassBuilder builder = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(declaration, scriptDescriptor),
|
||||
classType, declaration.getContainingFile());
|
||||
List<ScriptDescriptor> earlierScripts = state.getEarlierScriptsForReplInterpreter();
|
||||
ScriptContext scriptContext = parentContext.intoScript(
|
||||
scriptDescriptor,
|
||||
earlierScripts == null ? Collections.<ScriptDescriptor>emptyList() : earlierScripts,
|
||||
classDescriptorForScript
|
||||
scriptDescriptor,
|
||||
state.getTypeMapper()
|
||||
);
|
||||
return new ScriptCodegen(declaration, state, scriptContext, builder);
|
||||
}
|
||||
@@ -104,8 +99,8 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
protected void generateBody() {
|
||||
genMembers();
|
||||
genFieldsForParameters(scriptDescriptor, v);
|
||||
genConstructor(scriptDescriptor, context.getContextDescriptor(), v,
|
||||
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()));
|
||||
genConstructor(scriptDescriptor, v,
|
||||
context.intoFunction(scriptDescriptor.getUnsubstitutedPrimaryConstructor()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,22 +110,25 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
|
||||
private void genConstructor(
|
||||
@NotNull ScriptDescriptor scriptDescriptor,
|
||||
@NotNull ClassDescriptor classDescriptorForScript,
|
||||
@NotNull ClassBuilder classBuilder,
|
||||
@NotNull MethodContext methodContext
|
||||
) {
|
||||
//noinspection ConstantConditions
|
||||
Type blockType = typeMapper.mapType(scriptDescriptor.getScriptCodeDescriptor().getReturnType());
|
||||
|
||||
PropertyDescriptor scriptResultProperty = scriptDescriptor.getScriptResultProperty();
|
||||
classBuilder.newField(JvmDeclarationOriginKt.OtherOrigin(scriptResultProperty),
|
||||
ACC_PUBLIC | ACC_FINAL, scriptResultProperty.getName().asString(),
|
||||
blockType.getDescriptor(), null, null);
|
||||
|
||||
JvmMethodSignature jvmSignature = typeMapper.mapScriptSignature(scriptDescriptor, context.getEarlierScripts());
|
||||
|
||||
if (state.getShouldGenerateScriptResultValue()) {
|
||||
FieldInfo resultFieldInfo = context.getResultFieldInfo();
|
||||
classBuilder.newField(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
ACC_PUBLIC | ACC_FINAL,
|
||||
resultFieldInfo.getFieldName(),
|
||||
resultFieldInfo.getFieldType().getDescriptor(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
MethodVisitor mv = classBuilder.newMethod(
|
||||
JvmDeclarationOriginKt.OtherOrigin(scriptDeclaration, scriptDescriptor.getClassDescriptor().getUnsubstitutedPrimaryConstructor()),
|
||||
JvmDeclarationOriginKt.OtherOrigin(scriptDeclaration, scriptDescriptor.getUnsubstitutedPrimaryConstructor()),
|
||||
ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(),
|
||||
null, null);
|
||||
|
||||
@@ -139,7 +137,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
Type classType = typeMapper.mapType(classDescriptorForScript);
|
||||
Type classType = typeMapper.mapType(scriptDescriptor);
|
||||
|
||||
iv.load(0, classType);
|
||||
iv.invokespecial("java/lang/Object", "<init>", "()V", false);
|
||||
@@ -156,22 +154,23 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
Type[] argTypes = jvmSignature.getAsmMethod().getArgumentTypes();
|
||||
int add = 0;
|
||||
|
||||
for (int i = 0; i < scriptDescriptor.getScriptCodeDescriptor().getValueParameters().size(); i++) {
|
||||
ValueParameterDescriptor parameter = scriptDescriptor.getScriptCodeDescriptor().getValueParameters().get(i);
|
||||
List<ValueParameterDescriptor> valueParameters = scriptDescriptor.getUnsubstitutedPrimaryConstructor().getValueParameters();
|
||||
for (int i = 0; i < valueParameters.size(); i++) {
|
||||
ValueParameterDescriptor parameter = valueParameters.get(i);
|
||||
frameMap.enter(parameter, argTypes[i + add]);
|
||||
}
|
||||
|
||||
int offset = 1;
|
||||
|
||||
for (ScriptDescriptor earlierScript : context.getEarlierScripts()) {
|
||||
Type earlierClassType = asmTypeForScriptDescriptor(bindingContext, earlierScript);
|
||||
Type earlierClassType = typeMapper.mapClass(earlierScript);
|
||||
iv.load(0, classType);
|
||||
iv.load(offset, earlierClassType);
|
||||
offset += earlierClassType.getSize();
|
||||
iv.putfield(classType.getInternalName(), context.getScriptFieldName(earlierScript), earlierClassType.getDescriptor());
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : scriptDescriptor.getScriptCodeDescriptor().getValueParameters()) {
|
||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
||||
Type parameterType = typeMapper.mapType(parameter.getType());
|
||||
iv.load(0, classType);
|
||||
iv.load(offset, parameterType);
|
||||
@@ -188,16 +187,6 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
}
|
||||
});
|
||||
|
||||
StackValue stackValue = codegen.gen(scriptDeclaration.getBlockExpression());
|
||||
if (stackValue.type != Type.VOID_TYPE) {
|
||||
StackValue.Field resultValue = StackValue
|
||||
.field(blockType, classType, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, false, StackValue.LOCAL_0);
|
||||
resultValue.store(stackValue, iv);
|
||||
}
|
||||
else {
|
||||
stackValue.put(blockType, iv);
|
||||
}
|
||||
|
||||
iv.areturn(Type.VOID_TYPE);
|
||||
}
|
||||
|
||||
@@ -207,12 +196,12 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
|
||||
private void genFieldsForParameters(@NotNull ScriptDescriptor script, @NotNull ClassBuilder classBuilder) {
|
||||
for (ScriptDescriptor earlierScript : context.getEarlierScripts()) {
|
||||
Type earlierClassName = asmTypeForScriptDescriptor(bindingContext, earlierScript);
|
||||
int access = ACC_PRIVATE | ACC_FINAL;
|
||||
Type earlierClassName = typeMapper.mapType(earlierScript);
|
||||
int access = ACC_PUBLIC | ACC_FINAL;
|
||||
classBuilder.newField(NO_ORIGIN, access, context.getScriptFieldName(earlierScript), earlierClassName.getDescriptor(), null, null);
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : script.getScriptCodeDescriptor().getValueParameters()) {
|
||||
for (ValueParameterDescriptor parameter : script.getUnsubstitutedPrimaryConstructor().getValueParameters()) {
|
||||
Type parameterType = typeMapper.mapType(parameter);
|
||||
int access = ACC_PUBLIC | ACC_FINAL;
|
||||
classBuilder.newField(JvmDeclarationOriginKt.OtherOrigin(parameter), access, parameter.getName().getIdentifier(), parameterType.getDescriptor(), null, null);
|
||||
|
||||
@@ -235,8 +235,8 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Field field(@NotNull FieldInfo info) {
|
||||
return field(info.getFieldType(), Type.getObjectType(info.getOwnerInternalName()), info.getFieldName(), true, none());
|
||||
public static Field field(@NotNull FieldInfo info, @NotNull StackValue receiver) {
|
||||
return field(info.getFieldType(), Type.getObjectType(info.getOwnerInternalName()), info.getFieldName(), info.isStatic(), receiver);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -593,15 +593,15 @@ public abstract class StackValue {
|
||||
|
||||
@NotNull
|
||||
public static Field singleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper) {
|
||||
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper));
|
||||
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper), none());
|
||||
}
|
||||
|
||||
public static Field singletonViaInstance(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper, false));
|
||||
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper, false), none());
|
||||
}
|
||||
|
||||
public static Field oldSingleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper, true));
|
||||
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper, true), none());
|
||||
}
|
||||
|
||||
public static StackValue operation(Type type, Function1<InstructionAdapter, Unit> lambda) {
|
||||
|
||||
+11
-15
@@ -158,24 +158,20 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
element.acceptChildren(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitScript(@NotNull KtScript script) {
|
||||
classStack.push(bindingContext.get(SCRIPT, script));
|
||||
nameStack.push(AsmUtil.internalNameByFqNameWithoutInnerClasses(script.getFqName()));
|
||||
script.acceptChildren(this);
|
||||
nameStack.pop();
|
||||
classStack.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitKtFile(@NotNull KtFile file) {
|
||||
if (file.isScript()) {
|
||||
// TODO: replace with visitScript override
|
||||
//noinspection ConstantConditions
|
||||
ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, bindingContext.get(SCRIPT, file.getScript()));
|
||||
classStack.push(classDescriptor);
|
||||
//noinspection ConstantConditions
|
||||
nameStack.push(asmTypeForScriptPsi(bindingContext, file.getScript()).getInternalName());
|
||||
}
|
||||
else {
|
||||
nameStack.push(AsmUtil.internalNameByFqNameWithoutInnerClasses(file.getPackageFqName()));
|
||||
}
|
||||
nameStack.push(AsmUtil.internalNameByFqNameWithoutInnerClasses(file.getPackageFqName()));
|
||||
file.acceptChildren(this);
|
||||
nameStack.pop();
|
||||
if (file.isScript()) {
|
||||
classStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -386,7 +382,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
String peek = peekFromStack(nameStack);
|
||||
String name = safeIdentifier(descriptor.getName()).asString();
|
||||
if (containingDeclaration instanceof ClassDescriptor || containingDeclaration instanceof ScriptDescriptor) {
|
||||
if (containingDeclaration instanceof ClassDescriptor) {
|
||||
return peek + '$' + name;
|
||||
}
|
||||
else if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
|
||||
@@ -24,17 +24,13 @@ import org.jetbrains.kotlin.codegen.SamType;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice;
|
||||
import org.jetbrains.kotlin.util.slicedMap.Slices;
|
||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
||||
@@ -43,15 +39,12 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||
|
||||
public class CodegenBinding {
|
||||
public static final WritableSlice<ClassDescriptor, MutableClosure> CLOSURE = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<CallableDescriptor, ClassDescriptor> CLASS_FOR_CALLABLE = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<ScriptDescriptor, ClassDescriptor> CLASS_FOR_SCRIPT = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<ClassDescriptor, Type> ASM_TYPE = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<ClassDescriptor, Boolean> ENUM_ENTRY_CLASS_NEED_SUBCLASS = Slices.createSimpleSetSlice();
|
||||
@@ -89,22 +82,6 @@ public class CodegenBinding {
|
||||
return Boolean.TRUE.equals(bindingContext.get(ENUM_ENTRY_CLASS_NEED_SUBCLASS, classDescriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type asmTypeForScriptDescriptor(BindingContext bindingContext, @NotNull ScriptDescriptor scriptDescriptor) {
|
||||
ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
|
||||
//noinspection ConstantConditions
|
||||
return getAsmType(bindingContext, classDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type asmTypeForScriptPsi(BindingContext bindingContext, @NotNull KtScript script) {
|
||||
ScriptDescriptor scriptDescriptor = bindingContext.get(SCRIPT, script);
|
||||
if (scriptDescriptor == null) {
|
||||
throw new IllegalStateException("Script descriptor not found by PSI " + script);
|
||||
}
|
||||
return asmTypeForScriptDescriptor(bindingContext, scriptDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ClassDescriptor anonymousClassForCallable(
|
||||
@NotNull BindingContext bindingContext,
|
||||
@@ -163,7 +140,7 @@ public class CodegenBinding {
|
||||
@NotNull Type asmType,
|
||||
@NotNull JvmFileClassesProvider fileClassesManager
|
||||
) {
|
||||
KtElement element = (KtElement) descriptorToDeclaration(classDescriptor);
|
||||
KtElement element = (KtElement) DescriptorToSourceUtils.descriptorToDeclaration(classDescriptor);
|
||||
assert element != null : "No source element for " + classDescriptor;
|
||||
|
||||
MutableClosure closure = new MutableClosure(classDescriptor, enclosing);
|
||||
@@ -196,29 +173,6 @@ public class CodegenBinding {
|
||||
innerClasses.add(inner);
|
||||
}
|
||||
|
||||
public static void registerClassNameForScript(
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull KtScript script,
|
||||
@NotNull Type asmType,
|
||||
@NotNull JvmFileClassesProvider fileClassesManager
|
||||
) {
|
||||
ScriptDescriptor descriptor = trace.getBindingContext().get(SCRIPT, script);
|
||||
if (descriptor == null) {
|
||||
throw new IllegalStateException("Script descriptor is not found for PSI: " + PsiUtilsKt.getElementTextWithContext(script));
|
||||
}
|
||||
|
||||
String simpleName = asmType.getInternalName().substring(asmType.getInternalName().lastIndexOf('/') + 1);
|
||||
ClassDescriptorImpl classDescriptor =
|
||||
new ClassDescriptorImpl(descriptor, Name.special("<script-" + simpleName + ">"), Modality.FINAL,
|
||||
Collections.singleton(DescriptorUtilsKt.getBuiltIns(descriptor).getAnyType()),
|
||||
KotlinSourceElementKt.toSourceElement(script));
|
||||
classDescriptor.initialize(MemberScope.Empty.INSTANCE, Collections.<ConstructorDescriptor>emptySet(), null);
|
||||
|
||||
recordClosure(trace, classDescriptor, null, asmType, fileClassesManager);
|
||||
|
||||
trace.record(CLASS_FOR_SCRIPT, descriptor, classDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<KtFile> allFilesInPackages(BindingContext bindingContext, Collection<KtFile> files) {
|
||||
// todo: we use Set and add given files but ignoring other scripts because something non-clear kept in binding
|
||||
|
||||
@@ -315,9 +315,10 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
public ScriptContext intoScript(
|
||||
@NotNull ScriptDescriptor script,
|
||||
@NotNull List<ScriptDescriptor> earlierScripts,
|
||||
@NotNull ClassDescriptor classDescriptor
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@NotNull JetTypeMapper typeMapper
|
||||
) {
|
||||
return new ScriptContext(script, earlierScripts, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure);
|
||||
return new ScriptContext(typeMapper, script, earlierScripts, classDescriptor, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -16,30 +16,48 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.context;
|
||||
|
||||
import kotlin.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.FieldInfo;
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind;
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor;
|
||||
import org.jetbrains.kotlin.psi.KtClassInitializer;
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.KtScript;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ScriptContext extends FieldOwnerContext<ClassDescriptor> {
|
||||
public class ScriptContext extends ClassContext {
|
||||
private final ScriptDescriptor scriptDescriptor;
|
||||
private final List<ScriptDescriptor> earlierScripts;
|
||||
private final KtExpression lastStatement;
|
||||
|
||||
public ScriptContext(
|
||||
@NotNull JetTypeMapper typeMapper,
|
||||
@NotNull ScriptDescriptor scriptDescriptor,
|
||||
@NotNull List<ScriptDescriptor> earlierScripts,
|
||||
@NotNull ClassDescriptor contextDescriptor,
|
||||
@NotNull OwnerKind contextKind,
|
||||
@Nullable CodegenContext parentContext,
|
||||
@Nullable MutableClosure closure
|
||||
@Nullable CodegenContext parentContext
|
||||
) {
|
||||
super(contextDescriptor, contextKind, parentContext, closure, contextDescriptor, null);
|
||||
super(typeMapper, contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, null);
|
||||
this.scriptDescriptor = scriptDescriptor;
|
||||
this.earlierScripts = earlierScripts;
|
||||
KtScript script = (KtScript) DescriptorToSourceUtils.getSourceFromDescriptor(scriptDescriptor);
|
||||
assert script != null : "Declaration should be present for script: " + scriptDescriptor;
|
||||
KtDeclaration lastDeclaration = CollectionsKt.lastOrNull(script.getDeclarations());
|
||||
if (lastDeclaration instanceof KtClassInitializer) {
|
||||
this.lastStatement = ((KtClassInitializer) lastDeclaration).getBody();
|
||||
}
|
||||
else {
|
||||
this.lastStatement = null;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -47,6 +65,15 @@ public class ScriptContext extends FieldOwnerContext<ClassDescriptor> {
|
||||
return scriptDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FieldInfo getResultFieldInfo() {
|
||||
assert getState().getShouldGenerateScriptResultValue() : "Should not be called unless 'scriptResultFieldName' is set";
|
||||
GenerationState state = getState();
|
||||
String scriptResultFieldName = state.getScriptResultFieldName();
|
||||
assert scriptResultFieldName != null;
|
||||
return FieldInfo.createForHiddenField(state.getTypeMapper().mapClass(scriptDescriptor), AsmTypes.OBJECT_TYPE, scriptResultFieldName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ScriptDescriptor> getEarlierScripts() {
|
||||
return earlierScripts;
|
||||
@@ -61,6 +88,11 @@ public class ScriptContext extends FieldOwnerContext<ClassDescriptor> {
|
||||
return "script$" + (index + 1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public KtExpression getLastStatement() {
|
||||
return lastStatement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Script: " + getContextDescriptor().getName().asString();
|
||||
|
||||
@@ -62,7 +62,6 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLASS_FOR_SCRIPT;
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.addInlineMarker;
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getConstant;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral;
|
||||
@@ -598,17 +597,15 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state, sourceFile);
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
OwnerKind kind = DescriptorUtils.isInterface(descriptor) ? OwnerKind.DEFAULT_IMPLS : OwnerKind.IMPLEMENTATION;
|
||||
return parent.intoClass((ClassDescriptor) descriptor, kind, state);
|
||||
}
|
||||
else if (descriptor instanceof ScriptDescriptor) {
|
||||
ClassDescriptor classDescriptorForScript = state.getBindingContext().get(CLASS_FOR_SCRIPT, (ScriptDescriptor) descriptor);
|
||||
assert classDescriptorForScript != null : "Can't find class for script: " + descriptor;
|
||||
if (descriptor instanceof ScriptDescriptor) {
|
||||
List<ScriptDescriptor> earlierScripts = state.getEarlierScriptsForReplInterpreter();
|
||||
return parent.intoScript((ScriptDescriptor) descriptor,
|
||||
earlierScripts == null ? Collections.emptyList() : earlierScripts,
|
||||
classDescriptorForScript);
|
||||
(ClassDescriptor) descriptor, state.getTypeMapper());
|
||||
}
|
||||
else if (descriptor instanceof ClassDescriptor) {
|
||||
OwnerKind kind = DescriptorUtils.isInterface(descriptor) ? OwnerKind.DEFAULT_IMPLS : OwnerKind.IMPLEMENTATION;
|
||||
return parent.intoClass((ClassDescriptor) descriptor, kind, state);
|
||||
}
|
||||
else if (descriptor instanceof FunctionDescriptor) {
|
||||
return parent.intoFunction((FunctionDescriptor) descriptor);
|
||||
|
||||
@@ -101,6 +101,8 @@ public class GenerationState @JvmOverloads constructor(
|
||||
public val inlineCycleReporter: InlineCycleReporter = InlineCycleReporter(diagnostics)
|
||||
public val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this)
|
||||
public var earlierScriptsForReplInterpreter: List<ScriptDescriptor>? = null
|
||||
public var scriptResultFieldName: String? = null
|
||||
public val shouldGenerateScriptResultValue: Boolean get() = scriptResultFieldName != null
|
||||
public val reflectionTypes: ReflectionTypes = ReflectionTypes(module)
|
||||
public val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes()
|
||||
public val factory: ClassFileFactory
|
||||
|
||||
@@ -169,9 +169,6 @@ public class JetTypeMapper {
|
||||
else if (container instanceof ClassDescriptor) {
|
||||
return mapClass((ClassDescriptor) container);
|
||||
}
|
||||
else if (container instanceof ScriptDescriptor) {
|
||||
return asmTypeForScriptDescriptor(bindingContext, (ScriptDescriptor) container);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Don't know how to map owner for " + descriptor);
|
||||
}
|
||||
@@ -580,10 +577,6 @@ public class JetTypeMapper {
|
||||
return fqName.isRoot() ? name : fqName.asString().replace('.', '/') + '/' + name;
|
||||
}
|
||||
|
||||
if (container instanceof ScriptDescriptor) {
|
||||
return asmTypeForScriptDescriptor(bindingContext, (ScriptDescriptor) container).getInternalName() + "$" + name;
|
||||
}
|
||||
|
||||
assert container instanceof ClassDescriptor : "Unexpected container: " + container + " for " + klass;
|
||||
|
||||
String containerInternalName = computeAsmTypeImpl((ClassDescriptor) container);
|
||||
@@ -1392,12 +1385,10 @@ public class JetTypeMapper {
|
||||
sw.writeParametersStart();
|
||||
|
||||
for (ScriptDescriptor importedScript : importedScripts) {
|
||||
ClassDescriptor descriptor = bindingContext.get(CLASS_FOR_SCRIPT, importedScript);
|
||||
assert descriptor != null : "Script not found: " + importedScript;
|
||||
writeParameter(sw, descriptor.getDefaultType());
|
||||
writeParameter(sw, importedScript.getDefaultType());
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor valueParameter : script.getScriptCodeDescriptor().getValueParameters()) {
|
||||
for (ValueParameterDescriptor valueParameter : script.getUnsubstitutedPrimaryConstructor().getValueParameters()) {
|
||||
writeParameter(sw, valueParameter.getType());
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
@@ -30,7 +29,6 @@ import com.intellij.testFramework.LightVirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport;
|
||||
import org.jetbrains.kotlin.cli.common.messages.DiagnosticMessageReporter;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport;
|
||||
@@ -67,8 +65,8 @@ import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM;
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession;
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.JetClassLikeInfo;
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.*;
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
@@ -85,10 +83,10 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.asmTypeByFqNameWithoutInnerClasses;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.registerClassNameForScript;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||
|
||||
public class ReplInterpreter {
|
||||
private static final String SCRIPT_RESULT_FIELD_NAME = "$$result";
|
||||
|
||||
private int lineNumber = 0;
|
||||
|
||||
@Nullable
|
||||
@@ -309,13 +307,14 @@ public class ReplInterpreter {
|
||||
List<Pair<ScriptDescriptor, Type>> earlierScripts = Lists.newArrayList();
|
||||
|
||||
for (EarlierLine earlierLine : earlierLines) {
|
||||
//TODO_R: not needed
|
||||
earlierScripts.add(Pair.create(earlierLine.getScriptDescriptor(), earlierLine.getClassType()));
|
||||
}
|
||||
|
||||
GenerationState state = new GenerationState(psiFile.getProject(), ClassBuilderFactories.BINARIES,
|
||||
module, trace.getBindingContext(), Collections.singletonList(psiFile));
|
||||
|
||||
compileScript(psiFile.getScript(), scriptClassType, earlierScripts, state, CompilationErrorHandler.THROW_EXCEPTION);
|
||||
compileScript(psiFile.getScript(), earlierScripts, state, CompilationErrorHandler.THROW_EXCEPTION);
|
||||
|
||||
for (OutputFile outputFile : state.getFactory().asList()) {
|
||||
if(outputFile.getRelativePath().endsWith(".class")) {
|
||||
@@ -347,14 +346,13 @@ public class ReplInterpreter {
|
||||
setReplScriptExecuting(false);
|
||||
}
|
||||
|
||||
Field rvField = scriptClass.getDeclaredField("rv");
|
||||
Field rvField = scriptClass.getDeclaredField(SCRIPT_RESULT_FIELD_NAME);
|
||||
rvField.setAccessible(true);
|
||||
Object rv = rvField.get(scriptInstance);
|
||||
|
||||
earlierLines.add(new EarlierLine(line, scriptDescriptor, scriptClass, scriptInstance, scriptClassType));
|
||||
|
||||
KotlinType returnType = scriptDescriptor.getScriptCodeDescriptor().getReturnType();
|
||||
return LineResult.successful(rv, returnType != null && KotlinBuiltIns.isUnit(returnType));
|
||||
return LineResult.successful(rv, false);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
@@ -415,12 +413,8 @@ public class ReplInterpreter {
|
||||
return null;
|
||||
}
|
||||
|
||||
ScriptDescriptor scriptDescriptor = context.getScripts().get(psiFile.getScript());
|
||||
lastLineScope = trace.get(BindingContext.SCRIPT_SCOPE, scriptDescriptor);
|
||||
if (lastLineScope == null) {
|
||||
throw new IllegalStateException("last line scope is not initialized");
|
||||
}
|
||||
|
||||
LazyScriptDescriptor scriptDescriptor = context.getScripts().get(psiFile.getScript());
|
||||
lastLineScope = scriptDescriptor.getScopeForInitializerResolution();
|
||||
return scriptDescriptor;
|
||||
}
|
||||
|
||||
@@ -435,26 +429,19 @@ public class ReplInterpreter {
|
||||
List<ScriptDescriptor> earlierScriptDescriptors = new ArrayList<ScriptDescriptor>(earlierScripts.size());
|
||||
for (Pair<ScriptDescriptor, Type> pair : earlierScripts) {
|
||||
ScriptDescriptor earlierDescriptor = pair.first;
|
||||
Type earlierClassType = pair.second;
|
||||
|
||||
PsiElement jetScript = descriptorToDeclaration(earlierDescriptor);
|
||||
if (jetScript != null) {
|
||||
registerClassNameForScript(state.getBindingTrace(), (KtScript) jetScript, earlierClassType, state.getFileClassesProvider());
|
||||
earlierScriptDescriptors.add(earlierDescriptor);
|
||||
}
|
||||
earlierScriptDescriptors.add(earlierDescriptor);
|
||||
}
|
||||
state.setEarlierScriptsForReplInterpreter(earlierScriptDescriptors);
|
||||
}
|
||||
|
||||
public static void compileScript(
|
||||
@NotNull KtScript script,
|
||||
@NotNull Type classType,
|
||||
@NotNull List<Pair<ScriptDescriptor, Type>> earlierScripts,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull CompilationErrorHandler errorHandler
|
||||
) {
|
||||
state.setScriptResultFieldName(SCRIPT_RESULT_FIELD_NAME);
|
||||
registerEarlierScripts(state, earlierScripts);
|
||||
registerClassNameForScript(state.getBindingTrace(), script, classType, state.getFileClassesProvider());
|
||||
|
||||
state.beforeCompile();
|
||||
KotlinCodegenFacade.generatePackage(
|
||||
|
||||
+1
@@ -51,6 +51,7 @@ public class JvmDeclarationOrigin(
|
||||
public val descriptor: DeclarationDescriptor?
|
||||
) {
|
||||
companion object {
|
||||
@JvmField
|
||||
public val NO_ORIGIN: JvmDeclarationOrigin = JvmDeclarationOrigin(OTHER, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
|
||||
/*disableOptimization=*/false,
|
||||
/*useTypeTableInSerializer=*/false,
|
||||
forExtraDiagnostics)
|
||||
KotlinCodegenFacade.prepareForCompilation(state)
|
||||
state.beforeCompile()
|
||||
|
||||
bindingContext = state.bindingContext
|
||||
|
||||
|
||||
Reference in New Issue
Block a user