From 89e1588e137c31c4dea2139e5df370c5dbe1e252 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 25 Dec 2014 20:01:08 +0300 Subject: [PATCH] LIGHT_CLASSES mode for scripts - Do not generate constructor bodies - Do not generate script class when package contents are requested - NOT DONE: generate script class when its name is requested --- .../jetbrains/jet/codegen/PackageCodegen.java | 8 +- .../jetbrains/jet/codegen/ScriptCodegen.java | 107 +++++++++--------- .../binding/CodegenAnnotatingVisitor.java | 4 +- .../jet/codegen/state/GenerationState.java | 11 +- .../asJava/KotlinJavaFileStubProvider.java | 17 ++- .../tests/annotations/DanglingInScript.kt | 5 + .../tests/annotations/DanglingInScript.txt | 9 ++ .../checkers/JetDiagnosticsTestGenerated.java | 6 + 8 files changed, 108 insertions(+), 59 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/annotations/DanglingInScript.kt create mode 100644 compiler/testData/diagnostics/tests/annotations/DanglingInScript.txt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java index a42a660ac31..31fc8399429 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java @@ -304,13 +304,17 @@ public class PackageCodegen { } else if (declaration instanceof JetClassOrObject) { JetClassOrObject classOrObject = (JetClassOrObject) declaration; - if (state.getGenerateDeclaredClassFilter().shouldProcess(classOrObject)) { + if (state.getGenerateDeclaredClassFilter().shouldProcessClass(classOrObject)) { generateClassOrObject(classOrObject); } } else if (declaration instanceof JetScript) { + JetScript script = (JetScript) declaration; + // SCRIPT: generate script code, should be separate execution branch - ScriptCodegen.createScriptCodegen((JetScript) declaration, state, packagePartContext).generate(); + if (state.getGenerateDeclaredClassFilter().shouldProcessScript(script)) { + ScriptCodegen.createScriptCodegen(script, state, packagePartContext).generate(); + } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java index 0a2d0437169..65573c0b94f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java @@ -140,68 +140,73 @@ public class ScriptCodegen extends MemberCodegen { ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), null, null); - mv.visitCode(); + if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + mv.visitCode(); - final InstructionAdapter iv = new InstructionAdapter(mv); + final InstructionAdapter iv = new InstructionAdapter(mv); - Type classType = typeMapper.mapType(classDescriptorForScript); + Type classType = typeMapper.mapType(classDescriptorForScript); - iv.load(0, classType); - iv.invokespecial("java/lang/Object", "", "()V", false); + iv.load(0, classType); + iv.invokespecial("java/lang/Object", "", "()V", false); - iv.load(0, classType); + iv.load(0, classType); - final FrameMap frameMap = new FrameMap(); - frameMap.enterTemp(OBJECT_TYPE); + final FrameMap frameMap = new FrameMap(); + frameMap.enterTemp(OBJECT_TYPE); - for (ScriptDescriptor importedScript : context.getEarlierScripts()) { - frameMap.enter(importedScript, OBJECT_TYPE); - } - - Type[] argTypes = jvmSignature.getAsmMethod().getArgumentTypes(); - int add = 0; - - for (int i = 0; i < scriptDescriptor.getScriptCodeDescriptor().getValueParameters().size(); i++) { - ValueParameterDescriptor parameter = scriptDescriptor.getScriptCodeDescriptor().getValueParameters().get(i); - frameMap.enter(parameter, argTypes[i + add]); - } - - generateInitializers(new Function0() { - @Override - public ExpressionCodegen invoke() { - return new ExpressionCodegen(iv, frameMap, Type.VOID_TYPE, methodContext, state, ScriptCodegen.this); + for (ScriptDescriptor importedScript : context.getEarlierScripts()) { + frameMap.enter(importedScript, OBJECT_TYPE); } - }); - int offset = 1; + Type[] argTypes = jvmSignature.getAsmMethod().getArgumentTypes(); + int add = 0; - for (ScriptDescriptor earlierScript : context.getEarlierScripts()) { - Type earlierClassType = asmTypeForScriptDescriptor(bindingContext, earlierScript); - iv.load(0, classType); - iv.load(offset, earlierClassType); - offset += earlierClassType.getSize(); - iv.putfield(classType.getInternalName(), context.getScriptFieldName(earlierScript), earlierClassType.getDescriptor()); + for (int i = 0; i < scriptDescriptor.getScriptCodeDescriptor().getValueParameters().size(); i++) { + ValueParameterDescriptor parameter = scriptDescriptor.getScriptCodeDescriptor().getValueParameters().get(i); + frameMap.enter(parameter, argTypes[i + add]); + } + + generateInitializers(new Function0() { + @Override + public ExpressionCodegen invoke() { + return new ExpressionCodegen(iv, frameMap, Type.VOID_TYPE, methodContext, state, ScriptCodegen.this); + } + }); + + int offset = 1; + + for (ScriptDescriptor earlierScript : context.getEarlierScripts()) { + Type earlierClassType = asmTypeForScriptDescriptor(bindingContext, earlierScript); + iv.load(0, classType); + iv.load(offset, earlierClassType); + offset += earlierClassType.getSize(); + iv.putfield(classType.getInternalName(), context.getScriptFieldName(earlierScript), earlierClassType.getDescriptor()); + } + + for (ValueParameterDescriptor parameter : scriptDescriptor.getScriptCodeDescriptor().getValueParameters()) { + Type parameterType = typeMapper.mapType(parameter.getType()); + iv.load(0, classType); + iv.load(offset, parameterType); + offset += parameterType.getSize(); + iv.putfield(classType.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor()); + } + + StackValue stackValue = + new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, methodContext, state, this) + .gen(scriptDeclaration.getBlockExpression()); + if (stackValue.type != Type.VOID_TYPE) { + StackValue.Field resultValue = StackValue + .field(blockType, classType, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, false, StackValue.LOCAL_0); + resultValue.store(stackValue, iv); + } + else { + stackValue.put(blockType, iv); + } + + iv.areturn(Type.VOID_TYPE); } - for (ValueParameterDescriptor parameter : scriptDescriptor.getScriptCodeDescriptor().getValueParameters()) { - Type parameterType = typeMapper.mapType(parameter.getType()); - iv.load(0, classType); - iv.load(offset, parameterType); - offset += parameterType.getSize(); - iv.putfield(classType.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor()); - } - - StackValue stackValue = - new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, methodContext, state, this).gen(scriptDeclaration.getBlockExpression()); - if (stackValue.type != Type.VOID_TYPE) { - StackValue.Field resultValue = StackValue - .field(blockType, classType, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, false, StackValue.LOCAL_0); - resultValue.store(stackValue, iv); - } else { - stackValue.put(blockType, iv); - } - - iv.areturn(Type.VOID_TYPE); mv.visitMaxs(-1, -1); mv.visitEnd(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java index 547d2a2c6a9..ecc4445c49c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java @@ -214,7 +214,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { super.visitObjectDeclaration(declaration); } else { - if (!filter.shouldProcess(declaration)) return; + if (!filter.shouldProcessClass(declaration)) return; ClassDescriptor classDescriptor = bindingContext.get(CLASS, declaration); // working around a problem with shallow analysis @@ -233,7 +233,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { @Override public void visitClass(@NotNull JetClass klass) { - if (!filter.shouldProcess(klass)) return; + if (!filter.shouldProcessClass(klass)) return; ClassDescriptor classDescriptor = bindingContext.get(CLASS, klass); // working around a problem with shallow analysis 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 fb25e6537da..eef4419cbba 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java @@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; import org.jetbrains.jet.lang.diagnostics.DiagnosticSink; import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetScript; import org.jetbrains.jet.lang.reflect.ReflectionTypes; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -42,11 +43,17 @@ import java.util.List; public class GenerationState { public interface GenerateClassFilter { - boolean shouldProcess(JetClassOrObject classOrObject); + boolean shouldProcessClass(JetClassOrObject classOrObject); + boolean shouldProcessScript(JetScript script); GenerateClassFilter GENERATE_ALL = new GenerateClassFilter() { @Override - public boolean shouldProcess(JetClassOrObject classOrObject) { + public boolean shouldProcessClass(JetClassOrObject classOrObject) { + return true; + } + + @Override + public boolean shouldProcessScript(JetScript script) { return true; } }; diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java index 6e6ed8be32f..40d206bd6dc 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java @@ -51,6 +51,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.psi.JetClassOrObject; 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.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.Diagnostics; @@ -110,11 +111,17 @@ public class KotlinJavaFileStubProvider \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/DanglingInScript.txt b/compiler/testData/diagnostics/tests/annotations/DanglingInScript.txt new file mode 100644 index 00000000000..8082df6aacf --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/DanglingInScript.txt @@ -0,0 +1,9 @@ +package + +public final class Script { + public constructor Script() + public final val rv: [ERROR : getBlockReturnedType returned null] + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 3e565760a26..d440946e384 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -637,6 +637,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("DanglingInScript.kt") + public void testDanglingInScript() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/DanglingInScript.kt"); + doTest(fileName); + } + @TestMetadata("DanglingMixed.kt") public void testDanglingMixed() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/DanglingMixed.kt");