diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 07a6b4e9650..c144ee85621 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -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.emptyList(), Collections.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; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 6365cdf14a3..6d8ee6db1ad 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -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(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 97ab2f79a53..9f1f5499721 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -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 implements LocalLookup { +public class ExpressionCodegen extends JetVisitor 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 implem private final Stack blockStackElements = new Stack(); private final Collection localVariableNames = new HashSet(); + @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 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 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 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 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 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 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"); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 8416d07be06..772b6d55768 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -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 ? "" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, - descriptor, null, null); + isConstructor ? "" : 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 paramDescrs = functionDescriptor.getValueParameters(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java index b9cbcb900c0..76cb049fb85 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java @@ -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) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 1b8127f3222..b5dc1f46fac 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -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(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/KotlinCodegenFacade.java b/compiler/backend/src/org/jetbrains/jet/codegen/KotlinCodegenFacade.java index 93933e61cf6..3ba8907f39d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/KotlinCodegenFacade.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/KotlinCodegenFacade.java @@ -48,8 +48,6 @@ public class KotlinCodegenFacade { } } - state.getScriptCodegen().registerEarlierScripts(Collections.>emptyList()); - state.beforeCompile(); MultiMap namespaceGrouping = new MultiMap(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index 48d81bf99aa..1dbbe0ddae6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -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(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index f9857d45ec6..c3779d43ac5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -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.emptyList(), Collections.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. diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ParentCodegenAware.java b/compiler/backend/src/org/jetbrains/jet/codegen/ParentCodegenAware.java new file mode 100644 index 00000000000..4eeb4ef25fe --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ParentCodegenAware.java @@ -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(); +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ParentCodegenAwareImpl.java b/compiler/backend/src/org/jetbrains/jet/codegen/ParentCodegenAwareImpl.java new file mode 100644 index 00000000000..64943a234c7 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ParentCodegenAwareImpl.java @@ -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; + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperClasses.java b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperClasses.java index a528d2962a2..f4cf5e68849 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperClasses.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperClasses.java @@ -43,7 +43,7 @@ public class SamWrapperClasses { new Factory() { @Override public Type create() { - return new SamWrapperCodegen(state, samInterface).genWrapper(file); + return new SamWrapperCodegen(state, samInterface, null).genWrapper(file); } }); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java index 3bcbc773be3..cef7ab0cecf 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java @@ -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(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java index 6e8c015c711..c2088854173 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java @@ -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 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 earlierScripts; + + private ScriptCodegen( + @NotNull JetScript scriptDeclaration, + @NotNull GenerationState state, + @NotNull ScriptContext context, + @Nullable List earlierScripts + ) { + super(state, null); + this.scriptDeclaration = scriptDeclaration; + this.context = context; + this.earlierScripts = earlierScripts == null ? Collections.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 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> earlierScripts) { - for (Pair t : earlierScripts) { - ScriptDescriptor earlierDescriptor = t.first; - Type earlierClassName = t.second; - - registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, earlierClassName); - } - - List earlierScriptDescriptors = Lists.newArrayList(); - for (Pair 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> 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); - } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java index 1f04bcc9c5d..35be1ec7f65 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java @@ -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(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index 57bbc35d9c3..d1be0aee4da 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -187,7 +187,7 @@ public abstract class CodegenContext { } @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); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java index 1cbeffb33bb..d7a1276e762 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java @@ -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 earlierScriptsForReplInterpreter; + public GenerationState(Project project, ClassBuilderFactory builderFactory, BindingContext bindingContext, List 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 getEarlierScriptsForReplInterpreter() { + return earlierScriptsForReplInterpreter; + } + + public void setEarlierScriptsForReplInterpreter(@Nullable List earlierScriptsForReplInterpreter) { + this.earlierScriptsForReplInterpreter = earlierScriptsForReplInterpreter; + } } diff --git a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java index d4931342d5d..72257f5116f 100644 --- a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java @@ -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; } diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/repl/ReplInterpreter.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/repl/ReplInterpreter.java index cecdc0c7b3e..b4eb9724286 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/repl/ReplInterpreter.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/repl/ReplInterpreter.java @@ -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> earlierScripts + ) { + for (Pair t : earlierScripts) { + ScriptDescriptor earlierDescriptor = t.first; + Type earlierClassType = t.second; + registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, earlierClassType); + } + + List earlierScriptDescriptors = Lists.newArrayList(); + for (Pair t : earlierScripts) { + ScriptDescriptor earlierDescriptor = t.first; + earlierScriptDescriptors.add(earlierDescriptor); + } + state.setEarlierScriptsForReplInterpreter(earlierScriptDescriptors); + } + + public static void compileScript( + @NotNull JetScript script, + @NotNull Type classType, + @NotNull List> 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); + } + } diff --git a/compiler/tests/org/jetbrains/jet/codegen/ScriptGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ScriptGenTest.java index b7a03acf621..0e3cdbabf6f 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ScriptGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ScriptGenTest.java @@ -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("")) { - 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() { diff --git a/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.java b/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.java index ab2fcbd3e01..f20d7c47ffc 100644 --- a/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.java +++ b/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.java @@ -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);