ScriptCodegen refactoring: unsingleton
This commit is contained in:
@@ -83,7 +83,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||
}
|
||||
|
||||
private void generateClassBody() {
|
||||
FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state);
|
||||
FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state, this);
|
||||
PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen, this);
|
||||
|
||||
if (kind != OwnerKind.TRAIT_IMPL) {
|
||||
@@ -184,7 +184,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||
clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(), null, null, Visibilities.PRIVATE, false);
|
||||
|
||||
clInitCodegen = new ExpressionCodegen(method, new FrameMap(), Type.VOID_TYPE, context.intoFunction(clInit), state);
|
||||
clInitCodegen = new ExpressionCodegen(method, new FrameMap(), Type.VOID_TYPE, context.intoFunction(clInit), state, this);
|
||||
}
|
||||
return clInitCodegen;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.jet.codegen.CodegenUtil.isConst;
|
||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||
|
||||
public class ClosureCodegen extends GenerationStateAware {
|
||||
public class ClosureCodegen extends ParentCodegenAwareImpl {
|
||||
private final PsiElement fun;
|
||||
private final FunctionDescriptor funDescriptor;
|
||||
private final ClassDescriptor samInterface;
|
||||
@@ -71,9 +71,10 @@ public class ClosureCodegen extends GenerationStateAware {
|
||||
@NotNull Type closureSuperClass,
|
||||
@NotNull CodegenContext context,
|
||||
@NotNull LocalLookup localLookup,
|
||||
@NotNull FunctionGenerationStrategy strategy
|
||||
@NotNull FunctionGenerationStrategy strategy,
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
) {
|
||||
super(state);
|
||||
super(state, parentCodegen);
|
||||
|
||||
this.fun = fun;
|
||||
this.funDescriptor = funDescriptor;
|
||||
@@ -89,7 +90,6 @@ public class ClosureCodegen extends GenerationStateAware {
|
||||
this.asmType = asmTypeForAnonymousClass(bindingContext, funDescriptor);
|
||||
}
|
||||
|
||||
|
||||
public void gen() {
|
||||
ClassBuilder cv = state.getFactory().newVisitor(asmType, fun.getContainingFile());
|
||||
|
||||
@@ -120,7 +120,7 @@ public class ClosureCodegen extends GenerationStateAware {
|
||||
|
||||
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(interfaceFunction.getName(), funDescriptor);
|
||||
|
||||
FunctionCodegen fc = new FunctionCodegen(context, cv, state);
|
||||
FunctionCodegen fc = new FunctionCodegen(context, cv, state, getParentCodegen());
|
||||
fc.generateMethod(fun, jvmMethodSignature, funDescriptor, strategy);
|
||||
|
||||
this.constructor = generateConstructor(cv);
|
||||
@@ -131,9 +131,11 @@ public class ClosureCodegen extends GenerationStateAware {
|
||||
|
||||
genClosureFields(closure, cv, typeMapper);
|
||||
|
||||
FunctionCodegen.generateDefaultIfNeeded(context.intoFunction(funDescriptor), state, cv,
|
||||
typeMapper.mapSignature(Name.identifier("invoke"), funDescriptor), funDescriptor,
|
||||
context.getContextKind(), DefaultParameterValueLoader.DEFAULT);
|
||||
fc.generateDefaultIfNeeded(context.intoFunction(funDescriptor),
|
||||
typeMapper.mapSignature(Name.identifier("invoke"), funDescriptor),
|
||||
funDescriptor,
|
||||
context.getContextKind(),
|
||||
DefaultParameterValueLoader.DEFAULT);
|
||||
|
||||
cv.done();
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ import static org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.TH
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
||||
|
||||
public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implements LocalLookup {
|
||||
public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implements LocalLookup, ParentCodegenAware {
|
||||
|
||||
private static final String CLASS_NO_PATTERN_MATCHED_EXCEPTION = "jet/NoPatternMatchedException";
|
||||
private static final String CLASS_TYPE_CAST_EXCEPTION = "jet/TypeCastException";
|
||||
@@ -101,6 +101,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
private final Stack<BlockStackElement> blockStackElements = new Stack<BlockStackElement>();
|
||||
private final Collection<String> localVariableNames = new HashSet<String>();
|
||||
|
||||
@Nullable
|
||||
private final MemberCodegen parentCodegen;
|
||||
|
||||
/*
|
||||
* When we create a temporary variable to hold some value not to compute it many times
|
||||
* we put it into this map to emit access to that variable instead of evaluating the whole expression
|
||||
@@ -161,9 +164,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
@NotNull FrameMap myMap,
|
||||
@NotNull Type returnType,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull GenerationState state
|
||||
@NotNull GenerationState state,
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
) {
|
||||
this.myFrameMap = myMap;
|
||||
this.parentCodegen = parentCodegen;
|
||||
this.typeMapper = state.getTypeMapper();
|
||||
this.returnType = returnType;
|
||||
this.state = state;
|
||||
@@ -219,6 +224,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return localVariableNames;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MemberCodegen getParentCodegen() {
|
||||
return parentCodegen;
|
||||
}
|
||||
|
||||
public StackValue genQualified(StackValue receiver, JetElement selector) {
|
||||
return genQualified(receiver, selector, this);
|
||||
}
|
||||
@@ -1311,7 +1322,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
Type closureSuperClass = samInterfaceClass == null ? getFunctionImplType(descriptor) : OBJECT_TYPE;
|
||||
|
||||
ClosureCodegen closureCodegen = new ClosureCodegen(state, declaration, descriptor, samInterfaceClass, closureSuperClass, context,
|
||||
this, new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration));
|
||||
this, new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration), parentCodegen);
|
||||
|
||||
closureCodegen.gen();
|
||||
|
||||
@@ -2218,7 +2229,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
else {
|
||||
Type classType = asmTypeForScriptDescriptor(bindingContext, receiver.getDeclarationDescriptor());
|
||||
String fieldName = state.getScriptCodegen().getScriptFieldName(receiver.getDeclarationDescriptor());
|
||||
String fieldName = getParentScriptCodegen().getScriptFieldName(receiver.getDeclarationDescriptor());
|
||||
result.put(currentScriptType, v);
|
||||
StackValue.field(classType, currentScriptType, fieldName, false).put(classType, v);
|
||||
}
|
||||
@@ -2434,14 +2445,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
@Override
|
||||
public ExpressionCodegen initializeExpressionCodegen(
|
||||
JvmMethodSignature signature, MethodContext context, MethodVisitor mv,
|
||||
Type returnType
|
||||
Type returnType,
|
||||
MemberCodegen parentCodegen
|
||||
) {
|
||||
FunctionDescriptor referencedFunction = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
||||
JetType returnJetType = referencedFunction.getReturnType();
|
||||
assert returnJetType != null : "Return type can't be null: " + referencedFunction;
|
||||
|
||||
return super.initializeExpressionCodegen(signature, context,
|
||||
mv, typeMapper.mapReturnType(returnJetType));
|
||||
mv, typeMapper.mapReturnType(returnJetType), parentCodegen);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2564,8 +2576,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
return new ExpressionReceiver(receiverExpression, receiver.getType());
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
getParentCodegen());
|
||||
|
||||
closureCodegen.gen();
|
||||
|
||||
@@ -3809,4 +3821,16 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
public String toString() {
|
||||
return context.getContextDescriptor().toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ScriptCodegen getParentScriptCodegen() {
|
||||
MemberCodegen codegen = parentCodegen;
|
||||
while (codegen != null) {
|
||||
if (codegen instanceof ScriptCodegen) {
|
||||
return (ScriptCodegen) codegen;
|
||||
}
|
||||
codegen = codegen.getParentCodegen();
|
||||
}
|
||||
throw new IllegalStateException("Script codegen should be present in codegen tree");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,12 +57,13 @@ import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isFunctionLiteral;
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||
import static org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils.fqNameByClass;
|
||||
|
||||
public class FunctionCodegen extends GenerationStateAware {
|
||||
public class FunctionCodegen extends ParentCodegenAwareImpl {
|
||||
private final CodegenContext owner;
|
||||
|
||||
private final ClassBuilder v;
|
||||
|
||||
public FunctionCodegen(CodegenContext owner, ClassBuilder v, GenerationState state) {
|
||||
super(state);
|
||||
public FunctionCodegen(@NotNull CodegenContext owner, @NotNull ClassBuilder v, @NotNull GenerationState state, MemberCodegen parentCodegen) {
|
||||
super(state, parentCodegen);
|
||||
this.owner = owner;
|
||||
this.v = v;
|
||||
}
|
||||
@@ -80,7 +81,7 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
new FunctionGenerationStrategy.FunctionDefault(state, functionDescriptor, function));
|
||||
}
|
||||
|
||||
generateDefaultIfNeeded(owner.intoFunction(functionDescriptor), state, v, method, functionDescriptor, kind,
|
||||
generateDefaultIfNeeded(owner.intoFunction(functionDescriptor), method, functionDescriptor, kind,
|
||||
DefaultParameterValueLoader.DEFAULT);
|
||||
}
|
||||
|
||||
@@ -267,7 +268,7 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
genNotNullAssertionsForParameters(new InstructionAdapter(mv), state, functionDescriptor, frameMap);
|
||||
}
|
||||
|
||||
strategy.generateBody(mv, signature, context);
|
||||
strategy.generateBody(mv, signature, context, getParentCodegen());
|
||||
|
||||
localVariableNames.addAll(strategy.getLocalVariableNames());
|
||||
}
|
||||
@@ -518,10 +519,8 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
}
|
||||
}
|
||||
|
||||
static void generateDefaultIfNeeded(
|
||||
void generateDefaultIfNeeded(
|
||||
@NotNull MethodContext owner,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull ClassBuilder v,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull OwnerKind kind,
|
||||
@@ -565,17 +564,17 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
descriptor = descriptor.replace("(", "(" + ownerType.getDescriptor());
|
||||
}
|
||||
MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC),
|
||||
isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX,
|
||||
descriptor, null, null);
|
||||
isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX,
|
||||
descriptor, null, null);
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
generateDefaultImpl(owner, state, signature, functionDescriptor, isStatic, mv, loadStrategy);
|
||||
generateDefaultImpl(owner, signature, functionDescriptor, isStatic, mv, loadStrategy);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateDefaultImpl(
|
||||
private void generateDefaultImpl(
|
||||
@NotNull MethodContext methodContext,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
boolean aStatic,
|
||||
@@ -591,7 +590,7 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
}
|
||||
|
||||
Method jvmSignature = signature.getAsmMethod();
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), methodContext, state);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), methodContext, state, getParentCodegen());
|
||||
|
||||
Type[] argTypes = jvmSignature.getArgumentTypes();
|
||||
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.jet.codegen.context.MethodContext;
|
||||
@@ -38,7 +39,8 @@ public abstract class FunctionGenerationStrategy {
|
||||
public abstract void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context
|
||||
@NotNull MethodContext context,
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
);
|
||||
|
||||
protected void addLocalVariableName(@NotNull String name) {
|
||||
@@ -97,9 +99,10 @@ public abstract class FunctionGenerationStrategy {
|
||||
public void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context
|
||||
@NotNull MethodContext context,
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
) {
|
||||
ExpressionCodegen codegen = initializeExpressionCodegen(signature, context, mv, signature.getAsmMethod().getReturnType());
|
||||
ExpressionCodegen codegen = initializeExpressionCodegen(signature, context, mv, signature.getAsmMethod().getReturnType(), parentCodegen);
|
||||
doGenerateBody(codegen, signature);
|
||||
generateLocalVarNames(codegen);
|
||||
}
|
||||
@@ -111,9 +114,10 @@ public abstract class FunctionGenerationStrategy {
|
||||
JvmMethodSignature signature,
|
||||
MethodContext context,
|
||||
MethodVisitor mv,
|
||||
Type returnType
|
||||
Type returnType,
|
||||
MemberCodegen parentCodegen
|
||||
) {
|
||||
return new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context), returnType, context, state);
|
||||
return new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context), returnType, context, state, parentCodegen);
|
||||
}
|
||||
|
||||
public void generateLocalVarNames(@NotNull ExpressionCodegen codegen) {
|
||||
|
||||
@@ -98,7 +98,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
) {
|
||||
super(aClass, context, v, state, parentCodegen);
|
||||
this.classAsmType = typeMapper.mapType(descriptor.getDefaultType(), JetTypeMapperMode.IMPL);
|
||||
this.functionCodegen = new FunctionCodegen(context, v, state);
|
||||
this.functionCodegen = new FunctionCodegen(context, v, state, this);
|
||||
this.propertyCodegen = new PropertyCodegen(context, v, this.functionCodegen, this);
|
||||
}
|
||||
|
||||
@@ -819,13 +819,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
JvmMethodSignature signature = typeMapper.mapSignature(function);
|
||||
|
||||
FunctionCodegen fc = new FunctionCodegen(context, v, state);
|
||||
fc.generateMethod(myClass, signature, function, new FunctionGenerationStrategy() {
|
||||
functionCodegen.generateMethod(myClass, signature, function, new FunctionGenerationStrategy() {
|
||||
@Override
|
||||
public void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context
|
||||
@NotNull MethodContext context,
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
) {
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
if (!componentType.equals(Type.VOID_TYPE)) {
|
||||
@@ -843,13 +843,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
final Type thisDescriptorType = typeMapper.mapType(descriptor.getDefaultType());
|
||||
|
||||
FunctionCodegen fc = new FunctionCodegen(context, v, state);
|
||||
fc.generateMethod(myClass, methodSignature, function, new FunctionGenerationStrategy() {
|
||||
functionCodegen.generateMethod(myClass, methodSignature, function, new FunctionGenerationStrategy() {
|
||||
@Override
|
||||
public void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context
|
||||
@NotNull MethodContext context,
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
) {
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
@@ -884,7 +884,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
});
|
||||
|
||||
MethodContext functionContext = context.intoFunction(function);
|
||||
FunctionCodegen.generateDefaultIfNeeded(functionContext, state, v, methodSignature, function, OwnerKind.IMPLEMENTATION,
|
||||
|
||||
functionCodegen.generateDefaultIfNeeded(functionContext, methodSignature, function, OwnerKind.IMPLEMENTATION,
|
||||
new DefaultParameterValueLoader() {
|
||||
@Override
|
||||
public void putValueOnStack(
|
||||
@@ -904,7 +905,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
.put(propertyType, codegen.v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void generateEnumMethodsAndConstInitializers() {
|
||||
if (!myEnumConstants.isEmpty()) {
|
||||
@@ -1171,7 +1173,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
);
|
||||
|
||||
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorSignature, constructorDescriptor,
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorSignature, constructorDescriptor,
|
||||
OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT);
|
||||
|
||||
CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, closure);
|
||||
@@ -1483,7 +1485,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
mv.visitCode();
|
||||
FrameMap frameMap = context.prepareFrame(typeMapper);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, returnType, context.intoFunction(inheritedFun), state);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, returnType, context.intoFunction(inheritedFun), state, this);
|
||||
codegen.generateThisOrOuter(descriptor, false); // ??? wouldn't it be addClosureToConstructorParameters good idea to put it?
|
||||
|
||||
Type[] argTypes = methodToGenerate.getArgumentTypes();
|
||||
|
||||
@@ -48,8 +48,6 @@ public class KotlinCodegenFacade {
|
||||
}
|
||||
}
|
||||
|
||||
state.getScriptCodegen().registerEarlierScripts(Collections.<Pair<ScriptDescriptor, Type>>emptyList());
|
||||
|
||||
state.beforeCompile();
|
||||
|
||||
MultiMap<FqName, JetFile> namespaceGrouping = new MultiMap<FqName, JetFile>();
|
||||
|
||||
@@ -23,26 +23,16 @@ import org.jetbrains.jet.codegen.context.ClassContext;
|
||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||
import org.jetbrains.jet.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.GenerationStateAware;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
|
||||
|
||||
public class MemberCodegen extends GenerationStateAware {
|
||||
|
||||
@Nullable
|
||||
private MemberCodegen parentCodegen;
|
||||
public class MemberCodegen extends ParentCodegenAwareImpl {
|
||||
|
||||
public MemberCodegen(@NotNull GenerationState state, @Nullable MemberCodegen parentCodegen) {
|
||||
super(state);
|
||||
this.parentCodegen = parentCodegen;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MemberCodegen getParentCodegen() {
|
||||
return parentCodegen;
|
||||
super(state, parentCodegen);
|
||||
}
|
||||
|
||||
public void genFunctionOrProperty(
|
||||
@@ -50,7 +40,7 @@ public class MemberCodegen extends GenerationStateAware {
|
||||
@NotNull JetTypeParameterListOwner functionOrProperty,
|
||||
@NotNull ClassBuilder classBuilder
|
||||
) {
|
||||
FunctionCodegen functionCodegen = new FunctionCodegen(context, classBuilder, state);
|
||||
FunctionCodegen functionCodegen = new FunctionCodegen(context, classBuilder, state, this);
|
||||
if (functionOrProperty instanceof JetNamedFunction) {
|
||||
try {
|
||||
functionCodegen.gen((JetNamedFunction) functionOrProperty);
|
||||
@@ -102,7 +92,7 @@ public class MemberCodegen extends GenerationStateAware {
|
||||
|
||||
if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) {
|
||||
ClassBuilder traitBuilder = state.getFactory().forTraitImplementation(descriptor, state, aClass.getContainingFile());
|
||||
new TraitImplBodyCodegen(aClass, parentContext.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state), traitBuilder, state)
|
||||
new TraitImplBodyCodegen(aClass, parentContext.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state), traitBuilder, state, this)
|
||||
.generate();
|
||||
traitBuilder.done();
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ public class NamespaceCodegen extends MemberCodegen {
|
||||
}
|
||||
}
|
||||
else if (declaration instanceof JetScript) {
|
||||
state.getScriptCodegen().generate((JetScript) declaration);
|
||||
ScriptCodegen.createScriptCodegen((JetScript) declaration, state, CodegenContext.STATIC.intoNamespace(descriptor)).generate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@ public class NamespaceCodegen extends MemberCodegen {
|
||||
clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(), null, null, Visibilities.PRIVATE, false);
|
||||
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context.intoFunction(clInit), state);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context.intoFunction(clInit), state, this);
|
||||
|
||||
for (JetDeclaration declaration : properties) {
|
||||
ImplementationBodyCodegen.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface ParentCodegenAware {
|
||||
|
||||
@Nullable
|
||||
MemberCodegen getParentCodegen();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.GenerationStateAware;
|
||||
|
||||
public class ParentCodegenAwareImpl extends GenerationStateAware implements ParentCodegenAware {
|
||||
|
||||
@Nullable private final MemberCodegen parentCodegen;
|
||||
|
||||
public ParentCodegenAwareImpl(@NotNull GenerationState state, @Nullable MemberCodegen parentCodegen) {
|
||||
super(state);
|
||||
this.parentCodegen = parentCodegen;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MemberCodegen getParentCodegen() {
|
||||
return parentCodegen;
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public class SamWrapperClasses {
|
||||
new Factory<Type>() {
|
||||
@Override
|
||||
public Type create() {
|
||||
return new SamWrapperCodegen(state, samInterface).genWrapper(file);
|
||||
return new SamWrapperCodegen(state, samInterface, null).genWrapper(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
@@ -42,13 +43,17 @@ import static org.jetbrains.asm4.Opcodes.*;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.NO_FLAG_PACKAGE_PRIVATE;
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||
|
||||
public class SamWrapperCodegen extends GenerationStateAware {
|
||||
public class SamWrapperCodegen extends ParentCodegenAwareImpl {
|
||||
private static final String FUNCTION_FIELD_NAME = "function";
|
||||
|
||||
@NotNull private final ClassDescriptorFromJvmBytecode samInterface;
|
||||
|
||||
public SamWrapperCodegen(@NotNull GenerationState state, @NotNull ClassDescriptorFromJvmBytecode samInterface) {
|
||||
super(state);
|
||||
public SamWrapperCodegen(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull ClassDescriptorFromJvmBytecode samInterface,
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
) {
|
||||
super(state, parentCodegen);
|
||||
this.samInterface = samInterface;
|
||||
}
|
||||
|
||||
@@ -121,7 +126,7 @@ public class SamWrapperCodegen extends GenerationStateAware {
|
||||
) {
|
||||
|
||||
// using static context to avoid creating ClassDescriptor and everything else
|
||||
FunctionCodegen codegen = new FunctionCodegen(CodegenContext.STATIC, cv, state);
|
||||
FunctionCodegen codegen = new FunctionCodegen(CodegenContext.STATIC, cv, state, getParentCodegen());
|
||||
|
||||
FunctionDescriptor invokeFunction = functionJetType.getMemberScope()
|
||||
.getFunctions(Name.identifier("invoke")).iterator().next().getOriginal();
|
||||
|
||||
@@ -16,13 +16,11 @@
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
import org.jetbrains.asm4.commons.Method;
|
||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||
import org.jetbrains.jet.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.jet.codegen.context.MethodContext;
|
||||
@@ -35,7 +33,6 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -45,35 +42,50 @@ import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||
|
||||
public class ScriptCodegen extends MemberCodegen {
|
||||
|
||||
@NotNull
|
||||
private ClassFileFactory classFileFactory;
|
||||
|
||||
private List<ScriptDescriptor> earlierScripts;
|
||||
private Method scriptConstructorMethod;
|
||||
|
||||
public ScriptCodegen(@NotNull GenerationState state) {
|
||||
super(state, null);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setClassFileFactory(@NotNull ClassFileFactory classFileFactory) {
|
||||
this.classFileFactory = classFileFactory;
|
||||
}
|
||||
|
||||
public void generate(JetScript scriptDeclaration) {
|
||||
|
||||
ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration);
|
||||
|
||||
public static ScriptCodegen createScriptCodegen(
|
||||
@NotNull JetScript declaration,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull CodegenContext parentContext
|
||||
) {
|
||||
ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, declaration);
|
||||
assert scriptDescriptor != null;
|
||||
ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
|
||||
|
||||
ClassDescriptor classDescriptorForScript = state.getBindingContext().get(CLASS_FOR_SCRIPT, scriptDescriptor);
|
||||
assert classDescriptorForScript != null;
|
||||
|
||||
ScriptContext context = (ScriptContext) CodegenContext.STATIC.intoScript(scriptDescriptor, classDescriptorForScript);
|
||||
ScriptContext scriptContext = parentContext.intoScript(scriptDescriptor, classDescriptorForScript);
|
||||
return new ScriptCodegen(declaration, state, scriptContext, state.getEarlierScriptsForReplInterpreter());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JetScript scriptDeclaration;
|
||||
|
||||
@NotNull
|
||||
private final ScriptContext context;
|
||||
|
||||
@NotNull
|
||||
private List<ScriptDescriptor> earlierScripts;
|
||||
|
||||
private ScriptCodegen(
|
||||
@NotNull JetScript scriptDeclaration,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull ScriptContext context,
|
||||
@Nullable List<ScriptDescriptor> earlierScripts
|
||||
) {
|
||||
super(state, null);
|
||||
this.scriptDeclaration = scriptDeclaration;
|
||||
this.context = context;
|
||||
this.earlierScripts = earlierScripts == null ? Collections.<ScriptDescriptor>emptyList() : earlierScripts;
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
ScriptDescriptor scriptDescriptor = context.getScriptDescriptor();
|
||||
ClassDescriptor classDescriptorForScript = context.getContextDescriptor();
|
||||
Type classType = bindingContext.get(ASM_TYPE, classDescriptorForScript);
|
||||
assert classType != null;
|
||||
|
||||
ClassBuilder classBuilder = classFileFactory.newVisitor(classType, scriptDeclaration.getContainingFile());
|
||||
ClassBuilder classBuilder = state.getFactory().newVisitor(classType, scriptDeclaration.getContainingFile());
|
||||
|
||||
classBuilder.defineClass(scriptDeclaration,
|
||||
V1_6,
|
||||
ACC_PUBLIC,
|
||||
@@ -82,22 +94,19 @@ public class ScriptCodegen extends MemberCodegen {
|
||||
"java/lang/Object",
|
||||
new String[0]);
|
||||
|
||||
genMembers(scriptDeclaration, context, classBuilder);
|
||||
genMembers(context, classBuilder);
|
||||
genFieldsForParameters(scriptDescriptor, classBuilder);
|
||||
genConstructor(scriptDeclaration, scriptDescriptor, classDescriptorForScript, classBuilder,
|
||||
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()),
|
||||
earlierScripts);
|
||||
genConstructor(scriptDescriptor, classDescriptorForScript, classBuilder,
|
||||
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()));
|
||||
|
||||
classBuilder.done();
|
||||
}
|
||||
|
||||
private void genConstructor(
|
||||
@NotNull JetScript scriptDeclaration,
|
||||
@NotNull ScriptDescriptor scriptDescriptor,
|
||||
@NotNull ClassDescriptor classDescriptorForScript,
|
||||
@NotNull ClassBuilder classBuilder,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull List<ScriptDescriptor> importedScripts
|
||||
@NotNull MethodContext context
|
||||
) {
|
||||
|
||||
Type blockType = typeMapper.mapType(scriptDescriptor.getReturnType());
|
||||
@@ -105,9 +114,7 @@ public class ScriptCodegen extends MemberCodegen {
|
||||
classBuilder.newField(null, ACC_PUBLIC | ACC_FINAL, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME,
|
||||
blockType.getDescriptor(), null, null);
|
||||
|
||||
JvmMethodSignature jvmSignature = typeMapper.mapScriptSignature(scriptDescriptor, importedScripts);
|
||||
|
||||
state.getScriptCodegen().setScriptConstructorMethod(jvmSignature.getAsmMethod());
|
||||
JvmMethodSignature jvmSignature = typeMapper.mapScriptSignature(scriptDescriptor, earlierScripts);
|
||||
|
||||
MethodVisitor mv = classBuilder.newMethod(
|
||||
scriptDeclaration, ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(),
|
||||
@@ -127,7 +134,7 @@ public class ScriptCodegen extends MemberCodegen {
|
||||
|
||||
FrameMap frameMap = context.prepareFrame(typeMapper);
|
||||
|
||||
for (ScriptDescriptor importedScript : importedScripts) {
|
||||
for (ScriptDescriptor importedScript : earlierScripts) {
|
||||
frameMap.enter(importedScript, OBJECT_TYPE);
|
||||
}
|
||||
|
||||
@@ -140,14 +147,14 @@ public class ScriptCodegen extends MemberCodegen {
|
||||
}
|
||||
|
||||
ImplementationBodyCodegen.generateInitializers(
|
||||
new ExpressionCodegen(instructionAdapter, frameMap, Type.VOID_TYPE, context, state),
|
||||
new ExpressionCodegen(instructionAdapter, frameMap, Type.VOID_TYPE, context, state, this),
|
||||
scriptDeclaration.getDeclarations(),
|
||||
bindingContext,
|
||||
state);
|
||||
|
||||
int offset = 1;
|
||||
|
||||
for (ScriptDescriptor earlierScript : importedScripts) {
|
||||
for (ScriptDescriptor earlierScript : earlierScripts) {
|
||||
Type earlierClassType = asmTypeForScriptDescriptor(bindingContext, earlierScript);
|
||||
instructionAdapter.load(0, classType);
|
||||
instructionAdapter.load(offset, earlierClassType);
|
||||
@@ -164,7 +171,7 @@ public class ScriptCodegen extends MemberCodegen {
|
||||
}
|
||||
|
||||
StackValue stackValue =
|
||||
new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state).gen(scriptDeclaration.getBlockExpression());
|
||||
new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state, this).gen(scriptDeclaration.getBlockExpression());
|
||||
if (stackValue.type != Type.VOID_TYPE) {
|
||||
stackValue.put(stackValue.type, instructionAdapter);
|
||||
instructionAdapter.putfield(classType.getInternalName(), ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME,
|
||||
@@ -190,29 +197,13 @@ public class ScriptCodegen extends MemberCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void genMembers(@NotNull JetScript scriptDeclaration, @NotNull FieldOwnerContext context, @NotNull ClassBuilder classBuilder) {
|
||||
private void genMembers(@NotNull FieldOwnerContext context, @NotNull ClassBuilder classBuilder) {
|
||||
for (JetDeclaration decl : scriptDeclaration.getDeclarations()) {
|
||||
genFunctionOrProperty(context, (JetTypeParameterListOwner) decl, classBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerEarlierScripts(List<Pair<ScriptDescriptor, Type>> earlierScripts) {
|
||||
for (Pair<ScriptDescriptor, Type> t : earlierScripts) {
|
||||
ScriptDescriptor earlierDescriptor = t.first;
|
||||
Type earlierClassName = t.second;
|
||||
|
||||
registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, earlierClassName);
|
||||
}
|
||||
|
||||
List<ScriptDescriptor> earlierScriptDescriptors = Lists.newArrayList();
|
||||
for (Pair<ScriptDescriptor, Type> t : earlierScripts) {
|
||||
ScriptDescriptor earlierDescriptor = t.first;
|
||||
earlierScriptDescriptors.add(earlierDescriptor);
|
||||
}
|
||||
this.earlierScripts = earlierScriptDescriptors;
|
||||
}
|
||||
|
||||
protected int getScriptIndex(@NotNull ScriptDescriptor scriptDescriptor) {
|
||||
private int getScriptIndex(@NotNull ScriptDescriptor scriptDescriptor) {
|
||||
int index = earlierScripts.indexOf(scriptDescriptor);
|
||||
if (index < 0) {
|
||||
throw new IllegalStateException("Unregistered script: " + scriptDescriptor);
|
||||
@@ -223,29 +214,4 @@ public class ScriptCodegen extends MemberCodegen {
|
||||
public String getScriptFieldName(@NotNull ScriptDescriptor scriptDescriptor) {
|
||||
return "script$" + getScriptIndex(scriptDescriptor);
|
||||
}
|
||||
|
||||
public void setScriptConstructorMethod(Method scriptConstructorMethod) {
|
||||
this.scriptConstructorMethod = scriptConstructorMethod;
|
||||
}
|
||||
|
||||
public Method getScriptConstructorMethod() {
|
||||
return scriptConstructorMethod;
|
||||
}
|
||||
|
||||
public void compileScript(
|
||||
@NotNull JetScript script,
|
||||
@NotNull Type classType,
|
||||
@NotNull List<Pair<ScriptDescriptor, Type>> earlierScripts,
|
||||
@NotNull CompilationErrorHandler errorHandler
|
||||
) {
|
||||
registerEarlierScripts(earlierScripts);
|
||||
registerClassNameForScript(state.getBindingTrace(), script, classType);
|
||||
|
||||
state.beforeCompile();
|
||||
KotlinCodegenFacade.generateNamespace(
|
||||
state,
|
||||
JetPsiUtil.getFQName((JetFile) script.getContainingFile()),
|
||||
Collections.singleton((JetFile) script.getContainingFile()),
|
||||
errorHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.context.ClassContext;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapperMode;
|
||||
@@ -24,8 +26,15 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import static org.jetbrains.asm4.Opcodes.*;
|
||||
|
||||
public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
||||
public TraitImplBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassBuilder v, GenerationState state) {
|
||||
super(aClass, context, v, state, null);
|
||||
|
||||
public TraitImplBodyCodegen(
|
||||
@NotNull JetClassOrObject aClass,
|
||||
@NotNull ClassContext context,
|
||||
@NotNull ClassBuilder v,
|
||||
@NotNull GenerationState state,
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
) {
|
||||
super(aClass, context, v, state, parentCodegen);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,6 +49,7 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String jvmName() {
|
||||
return typeMapper.mapType(descriptor.getDefaultType(), JetTypeMapperMode.TRAIT_IMPL).getInternalName();
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CodegenContext intoScript(@NotNull ScriptDescriptor script, @NotNull ClassDescriptor classDescriptor) {
|
||||
public ScriptContext intoScript(@NotNull ScriptDescriptor script, @NotNull ClassDescriptor classDescriptor) {
|
||||
return new ScriptContext(script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,12 @@ package org.jetbrains.jet.codegen.state;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.jet.di.InjectorForJvmCodegen;
|
||||
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
@@ -47,9 +49,6 @@ public class GenerationState {
|
||||
@NotNull
|
||||
private final ClassFileFactory classFileFactory;
|
||||
|
||||
@NotNull
|
||||
private final ScriptCodegen scriptCodegen;
|
||||
|
||||
@NotNull
|
||||
private final Project project;
|
||||
|
||||
@@ -71,6 +70,9 @@ public class GenerationState {
|
||||
|
||||
private final boolean generateDeclaredClasses;
|
||||
|
||||
@Nullable
|
||||
private List<ScriptDescriptor> earlierScriptsForReplInterpreter;
|
||||
|
||||
public GenerationState(Project project, ClassBuilderFactory builderFactory, BindingContext bindingContext, List<JetFile> files) {
|
||||
this(project, builderFactory, Progress.DEAF, bindingContext, files, true, false, true);
|
||||
}
|
||||
@@ -97,7 +99,6 @@ public class GenerationState {
|
||||
|
||||
InjectorForJvmCodegen injector = new InjectorForJvmCodegen(typeMapper, this, builderFactory, project);
|
||||
|
||||
this.scriptCodegen = injector.getScriptCodegen();
|
||||
this.intrinsics = injector.getIntrinsics();
|
||||
this.classFileFactory = injector.getClassFileFactory();
|
||||
|
||||
@@ -131,11 +132,6 @@ public class GenerationState {
|
||||
return files;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ScriptCodegen getScriptCodegen() {
|
||||
return scriptCodegen;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public BindingTrace getBindingTrace() {
|
||||
return bindingTrace;
|
||||
@@ -189,4 +185,13 @@ public class GenerationState {
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<ScriptDescriptor> getEarlierScriptsForReplInterpreter() {
|
||||
return earlierScriptsForReplInterpreter;
|
||||
}
|
||||
|
||||
public void setEarlierScriptsForReplInterpreter(@Nullable List<ScriptDescriptor> earlierScriptsForReplInterpreter) {
|
||||
this.earlierScriptsForReplInterpreter = earlierScriptsForReplInterpreter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderMode;
|
||||
import org.jetbrains.jet.codegen.ScriptCodegen;
|
||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -39,7 +38,6 @@ public class InjectorForJvmCodegen {
|
||||
private final BindingTrace bindingTrace;
|
||||
private final BindingContext bindingContext;
|
||||
private final ClassBuilderMode classBuilderMode;
|
||||
private final ScriptCodegen scriptCodegen;
|
||||
private final IntrinsicMethods intrinsics;
|
||||
private final ClassFileFactory classFileFactory;
|
||||
|
||||
@@ -56,12 +54,9 @@ public class InjectorForJvmCodegen {
|
||||
this.bindingTrace = jetTypeMapper.getBindingTrace();
|
||||
this.bindingContext = bindingTrace.getBindingContext();
|
||||
this.classBuilderMode = classBuilderFactory.getClassBuilderMode();
|
||||
this.scriptCodegen = new ScriptCodegen(getGenerationState());
|
||||
this.intrinsics = new IntrinsicMethods();
|
||||
this.classFileFactory = new ClassFileFactory(getGenerationState());
|
||||
|
||||
this.scriptCodegen.setClassFileFactory(classFileFactory);
|
||||
|
||||
this.classFileFactory.setBuilderFactory(classBuilderFactory);
|
||||
|
||||
intrinsics.init();
|
||||
@@ -84,10 +79,6 @@ public class InjectorForJvmCodegen {
|
||||
return this.project;
|
||||
}
|
||||
|
||||
public ScriptCodegen getScriptCodegen() {
|
||||
return this.scriptCodegen;
|
||||
}
|
||||
|
||||
public IntrinsicMethods getIntrinsics() {
|
||||
return this.intrinsics;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderFactories;
|
||||
import org.jetbrains.jet.codegen.CompilationErrorHandler;
|
||||
import org.jetbrains.jet.codegen.KotlinCodegenFacade;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.config.CompilerConfiguration;
|
||||
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
|
||||
@@ -46,6 +47,8 @@ import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.NamespaceLikeBuilderDummy;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.psi.JetScript;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
@@ -67,7 +70,9 @@ import java.net.URLClassLoader;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.asmTypeByFqNameWithoutInnerClasses;
|
||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.registerClassNameForScript;
|
||||
|
||||
public class ReplInterpreter {
|
||||
|
||||
@@ -232,8 +237,9 @@ public class ReplInterpreter {
|
||||
BindingContext bindingContext = AnalyzeExhaust.success(trace.getBindingContext(), module).getBindingContext();
|
||||
GenerationState generationState = new GenerationState(psiFile.getProject(), ClassBuilderFactories.BINARIES,
|
||||
bindingContext, Collections.singletonList(psiFile));
|
||||
generationState.getScriptCodegen().compileScript(psiFile.getScript(), scriptClassType, earlierScripts,
|
||||
CompilationErrorHandler.THROW_EXCEPTION);
|
||||
|
||||
compileScript(psiFile.getScript(), scriptClassType, earlierScripts, generationState,
|
||||
CompilationErrorHandler.THROW_EXCEPTION);
|
||||
|
||||
for (String file : generationState.getFactory().files()) {
|
||||
classLoader.addClass(JvmClassName.byInternalName(file.replaceFirst("\\.class$", "")), generationState.getFactory().asBytes(file));
|
||||
@@ -317,4 +323,41 @@ public class ReplInterpreter {
|
||||
public void dumpClasses(@NotNull PrintWriter out) {
|
||||
classLoader.dumpClasses(out);
|
||||
}
|
||||
|
||||
private static void registerEarlierScripts(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull List<Pair<ScriptDescriptor, Type>> earlierScripts
|
||||
) {
|
||||
for (Pair<ScriptDescriptor, Type> t : earlierScripts) {
|
||||
ScriptDescriptor earlierDescriptor = t.first;
|
||||
Type earlierClassType = t.second;
|
||||
registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, earlierClassType);
|
||||
}
|
||||
|
||||
List<ScriptDescriptor> earlierScriptDescriptors = Lists.newArrayList();
|
||||
for (Pair<ScriptDescriptor, Type> t : earlierScripts) {
|
||||
ScriptDescriptor earlierDescriptor = t.first;
|
||||
earlierScriptDescriptors.add(earlierDescriptor);
|
||||
}
|
||||
state.setEarlierScriptsForReplInterpreter(earlierScriptDescriptors);
|
||||
}
|
||||
|
||||
public static void compileScript(
|
||||
@NotNull JetScript script,
|
||||
@NotNull Type classType,
|
||||
@NotNull List<Pair<ScriptDescriptor, Type>> earlierScripts,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull CompilationErrorHandler errorHandler
|
||||
) {
|
||||
registerEarlierScripts(state, earlierScripts);
|
||||
registerClassNameForScript(state.getBindingTrace(), script, classType);
|
||||
|
||||
state.beforeCompile();
|
||||
KotlinCodegenFacade.generateNamespace(
|
||||
state,
|
||||
JetPsiUtil.getFQName((JetFile) script.getContainingFile()),
|
||||
Collections.singleton((JetFile) script.getContainingFile()),
|
||||
errorHandler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class ScriptGenTest extends CodegenTestCase {
|
||||
try {
|
||||
Class<?> scriptClass = loader.loadClass(scriptClassName);
|
||||
|
||||
Constructor constructor = getConstructor(scriptClass, factory.getState().getScriptCodegen().getScriptConstructorMethod());
|
||||
Constructor constructor = getConstructor(scriptClass);
|
||||
scriptInstance = constructor.newInstance(myFiles.getScriptParameterValues().toArray());
|
||||
|
||||
assertFalse("expecting at least one expectation", myFiles.getExpectedValues().isEmpty());
|
||||
@@ -92,43 +92,12 @@ public class ScriptGenTest extends CodegenTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
protected Constructor getConstructor(@NotNull Class<?> clazz, org.jetbrains.asm4.commons.Method method) {
|
||||
if (!method.getName().equals("<init>")) {
|
||||
throw new IllegalArgumentException("not constructor: " + method);
|
||||
}
|
||||
Class[] classes = new Class[method.getArgumentTypes().length];
|
||||
for (int i = 0; i < classes.length; ++i) {
|
||||
classes[i] = loadClassFromType(method.getArgumentTypes()[i]);
|
||||
}
|
||||
try {
|
||||
return clazz.getConstructor(classes);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Class<?> loadClassFromType(@NotNull Type type) {
|
||||
try {
|
||||
switch (type.getSort()) {
|
||||
case Type.OBJECT:
|
||||
return Class.forName(type.getClassName());
|
||||
case Type.INT:
|
||||
return int.class;
|
||||
case Type.LONG:
|
||||
return long.class;
|
||||
default:
|
||||
// AFAIK there is no way to create array class from class
|
||||
if (type.getDescriptor().equals("[Ljava/lang/String;")) {
|
||||
return String[].class;
|
||||
}
|
||||
throw new IllegalStateException("not implemented: " + type.getDescriptor());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw ExceptionUtils.rethrow(e);
|
||||
protected Constructor getConstructor(@NotNull Class<?> clazz) {
|
||||
Constructor [] constructors = clazz.getConstructors();
|
||||
if (constructors == null || constructors.length != 1) {
|
||||
throw new IllegalArgumentException("Script class should have one constructor: " + clazz);
|
||||
}
|
||||
return constructors[0];
|
||||
}
|
||||
|
||||
public void testHelloWorld() {
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
package org.jetbrains.jet.generators.injectors;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderFactory;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderMode;
|
||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||
import org.jetbrains.jet.codegen.ScriptCodegen;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
@@ -233,7 +230,6 @@ public class GenerateInjectors {
|
||||
new GivenExpression("bindingTrace.getBindingContext()"));
|
||||
generator.addField(false, ClassBuilderMode.class, "classBuilderMode",
|
||||
new GivenExpression("classBuilderFactory.getClassBuilderMode()"));
|
||||
generator.addPublicField(ScriptCodegen.class);
|
||||
generator.addField(true, IntrinsicMethods.class, "intrinsics", null);
|
||||
generator.addPublicField(ClassFileFactory.class);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user