From 7d938dd98f91f977b9b26d681df79061566f234d Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 6 Jun 2012 12:17:25 +0300 Subject: [PATCH] one more step to multi-file compilation --- .../jet/codegen/ClassFileFactory.java | 5 +- .../jet/codegen/GenerationState.java | 35 ++---- .../jet/codegen/NamespaceCodegen.java | 100 ++++++++++++------ .../jetbrains/jet/asJava/JetLightClass.java | 6 +- .../jetbrains/jet/codegen/ArrayGenTest.java | 2 +- 5 files changed, 84 insertions(+), 64 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java index e6988bc66cb..ceeb75b3882 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java @@ -61,13 +61,12 @@ public class ClassFileFactory { return newVisitor(className.getInternalName() + ".class"); } - NamespaceCodegen forNamespace(JetFile file) { + NamespaceCodegen forNamespace(FqName fqName, Collection files) { assert !isDone : "Already done!"; - FqName fqName = JetPsiUtil.getFQName(file); NamespaceCodegen codegen = ns2codegen.get(fqName); if (codegen == null) { final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassNameForKotlinNs(fqName).getInternalName() + ".class"); - codegen = new NamespaceCodegen(builder, fqName, state, file.getContainingFile()); + codegen = new NamespaceCodegen(builder, fqName, state, files); ns2codegen.put(fqName, codegen); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index 760f71eb505..1eb2c992634 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -119,42 +119,25 @@ public class GenerationState { return Pair.create(className, getFactory().forAnonymousSubclass(className)); } - public NamespaceCodegen forNamespace(JetFile namespace) { - return getFactory().forNamespace(namespace); + public NamespaceCodegen forNamespace(FqName fqName, Collection namespace) { + return getFactory().forNamespace(fqName, namespace); } public void compileCorrectFiles(@NotNull CompilationErrorHandler errorHandler) { - MultiMap namespaceGrouping = new MultiMap(); + MultiMap namespaceGrouping = new MultiMap(); for (JetFile file : this.files) { if (file == null) throw new IllegalArgumentException("A null file given for compilation"); - namespaceGrouping.putValue(JetPsiUtil.getFQName(file).getFqName(), file); + namespaceGrouping.putValue(JetPsiUtil.getFQName(file), file); } - for (Map.Entry> entry : namespaceGrouping.entrySet()) { - for (JetFile file : entry.getValue()) { - VirtualFile vFile = file.getVirtualFile(); - String path = vFile != null ? vFile.getPath() : "no_virtual_file/" + file.getName(); - progress.log("For source: " + path + "\tFor namespace: " + entry.getKey()); - try { - generateNamespace(file); - } - catch (ProcessCanceledException e) { - throw e; - } - catch (Throwable e) { - errorHandler.reportException(e, vFile == null ? "no file" : vFile.getUrl()); - DiagnosticUtils.throwIfRunningOnServer(e); - if (ApplicationManager.getApplication().isInternal()) { - e.printStackTrace(); - } - } - } + for (Map.Entry> entry : namespaceGrouping.entrySet()) { + generateNamespace(entry.getKey(), entry.getValue(), errorHandler, progress); } } - protected void generateNamespace(JetFile namespace) { - NamespaceCodegen codegen = forNamespace(namespace); - codegen.generate(namespace); + protected void generateNamespace(FqName fqName, Collection namespace, CompilationErrorHandler errorHandler, Progress progress) { + NamespaceCodegen codegen = forNamespace(fqName, namespace); + codegen.generate(errorHandler, progress); } public GeneratedAnonymousClassDescriptor generateObjectLiteral(JetObjectLiteralExpression literal, ObjectOrClosureCodegen closure) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index e6e01cbd256..559d7120bb9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -16,19 +16,26 @@ package org.jetbrains.jet.codegen; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.utils.Progress; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; +import java.util.Collection; + import static org.objectweb.asm.Opcodes.*; /** @@ -36,12 +43,17 @@ import static org.objectweb.asm.Opcodes.*; */ public class NamespaceCodegen { private final ClassBuilder v; + @NotNull private final FqName name; private final GenerationState state; + private final Collection files; - public NamespaceCodegen(ClassBuilder v, @NotNull FqName fqName, GenerationState state, PsiFile sourceFile) { + public NamespaceCodegen(ClassBuilder v, @NotNull FqName fqName, GenerationState state, Collection files) { this.v = v; + name = fqName; this.state = state; + this.files = files; + PsiFile sourceFile = files.iterator().next().getContainingFile(); v.defineClass(sourceFile, V1_6, ACC_PUBLIC/*|ACC_SUPER*/, getJVMClassNameForKotlinNs(fqName).getInternalName(), @@ -54,8 +66,32 @@ public class NamespaceCodegen { v.visitSource(sourceFile.getName(), null); } - public void generate(JetFile file) { + public void generate(CompilationErrorHandler errorHandler, Progress progress) { + for (JetFile file : files) { + VirtualFile vFile = file.getVirtualFile(); + try { + String path = vFile != null ? vFile.getPath() : "no_virtual_file/" + file.getName(); + if(progress != null) progress.log("For source: " + path); + generate(file); + } + catch (ProcessCanceledException e) { + throw e; + } + catch (Throwable e) { + if(errorHandler != null) errorHandler.reportException(e, vFile == null ? "no file" : vFile.getUrl()); + DiagnosticUtils.throwIfRunningOnServer(e); + if (ApplicationManager.getApplication().isInternal()) { + e.printStackTrace(); + } + } + } + if (hasNonConstantPropertyInitializers()) { + generateStaticInitializers(); + } + } + + private void generate(JetFile file) { for (JetDeclaration declaration : file.getDeclarations()) { if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) { NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, file); @@ -71,54 +107,54 @@ public class NamespaceCodegen { else if (declaration instanceof JetScript) { state.getInjector().getScriptCodegen().generate((JetScript) declaration); } -// else if (declaration instanceof JetFile) { -// JetFile childNamespace = (JetFile) declaration; -// state.forNamespace(childNamespace).generate(childNamespace); -// } - } - - if (hasNonConstantPropertyInitializers(file)) { - generateStaticInitializers(file); } } - private void generateStaticInitializers(JetFile namespace) { + private void generateStaticInitializers() { + JetFile namespace = files.iterator().next(); // @todo: hack + MethodVisitor mv = v.newMethod(namespace, ACC_PUBLIC | ACC_STATIC, "", "()V", null, null); - if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { - mv.visitCode(); + for (JetFile file : files) { + if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + mv.visitCode(); - FrameMap frameMap = new FrameMap(); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContexts.STATIC, state); + FrameMap frameMap = new FrameMap(); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContexts.STATIC, state); - for (JetDeclaration declaration : namespace.getDeclarations()) { - if (declaration instanceof JetProperty) { - final JetExpression initializer = ((JetProperty) declaration).getInitializer(); - if (initializer != null && !(initializer instanceof JetConstantExpression)) { - final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration); - assert descriptor != null; - if(descriptor.getReceiverParameter().exists()) { - continue; + for (JetDeclaration declaration : file.getDeclarations()) { + if (declaration instanceof JetProperty) { + final JetExpression initializer = ((JetProperty) declaration).getInitializer(); + if (initializer != null && !(initializer instanceof JetConstantExpression)) { + final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration); + assert descriptor != null; + if(descriptor.getReceiverParameter().exists()) { + continue; + } + codegen.genToJVMStack(initializer); + codegen.intermediateValueForProperty(descriptor, true, null).store(new InstructionAdapter(mv)); } - codegen.genToJVMStack(initializer); - codegen.intermediateValueForProperty(descriptor, true, null).store(new InstructionAdapter(mv)); } } } + } + if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitInsn(RETURN); FunctionCodegen.endVisit(mv, "static initializer for namespace", namespace); mv.visitEnd(); } } - private static boolean hasNonConstantPropertyInitializers(JetFile namespace) { - for (JetDeclaration declaration : namespace.getDeclarations()) { - if (declaration instanceof JetProperty) { - final JetExpression initializer = ((JetProperty) declaration).getInitializer(); - if (initializer != null && !(initializer instanceof JetConstantExpression)) { - return true; - } + private boolean hasNonConstantPropertyInitializers() { + for (JetFile file : files) { + for (JetDeclaration declaration : file.getDeclarations()) { + if (declaration instanceof JetProperty) { + final JetExpression initializer = ((JetProperty) declaration).getInitializer(); + if (initializer != null && !(initializer instanceof JetConstantExpression)) { + return true; + } + } } } return false; diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java index 3459b1d91fb..5d157337d09 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java @@ -52,8 +52,10 @@ import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.java.*; import org.jetbrains.jet.plugin.JetLanguage; import org.jetbrains.jet.util.QualifiedNamesUtil; +import org.jetbrains.jet.utils.Progress; import javax.swing.*; +import java.util.Collection; import java.util.Collections; public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMarker { @@ -178,7 +180,7 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa final GenerationState state = new GenerationState(project, builderFactory, context, Collections.singletonList(file)) { @Override - protected void generateNamespace(JetFile namespace) { + protected void generateNamespace(FqName fqName, Collection namespace, CompilationErrorHandler errorHandler, Progress progress) { PsiManager manager = PsiManager.getInstance(project); stubStack.push(answer); @@ -195,7 +197,7 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa fakeFile.setPhysical(false); answer.setPsi(fakeFile); - super.generateNamespace(namespace); + super.generateNamespace(fqName, namespace, errorHandler, progress); final StubElement pop = stubStack.pop(); if (pop != answer) { LOG.error("Unbalanced stack operations: " + pop); diff --git a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java index 8193d92ebc5..9ac3f218758 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java @@ -78,7 +78,7 @@ public class ArrayGenTest extends CodegenTestCase { public void testIntGenerics () throws Exception { loadText("class L(var a : T) {} fun foo() = L(5).a"); -// System.out.println(generateToText()); + System.out.println(generateToText()); Method foo = generateFunction(); Object invoke = foo.invoke(null); System.out.println(invoke.getClass());