From d501e8821ca28349be647ecb3ecaaa3cfd5939e1 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Thu, 28 Feb 2013 18:25:46 +0400 Subject: [PATCH] Move top level properties from package class to package$src --- .../jet/codegen/FunctionCodegen.java | 2 +- .../jet/codegen/NamespaceCodegen.java | 67 ++++++++----------- .../jet/codegen/PropertyCodegen.java | 14 ++-- .../jet/codegen/state/JetTypeMapper.java | 22 ++++-- .../deprecatedFlag/topLevelProperty.kt | 3 +- .../jet/codegen/PropertyGenTest.java | 2 +- .../codegen/flags/AbstractWriteFlagsTest.java | 35 ++++++---- 7 files changed, 80 insertions(+), 65 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 05c56420482..d6495acfafc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -314,7 +314,7 @@ public class FunctionCodegen extends GenerationStateAware { } } - private void generateStaticDelegateMethodBody( + public static void generateStaticDelegateMethodBody( @NotNull MethodVisitor mv, @NotNull Method asmMethod, @NotNull OwnerKind.StaticDelegateKind dk diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 54a1549bc03..dbb1483264c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -109,10 +109,6 @@ public class NamespaceCodegen extends MemberCodegen { } assert v.isActivated() == shouldGenerateNSClass(files) : "Different algorithms for generating namespace class and for heuristics"; - - if (hasNonConstantPropertyInitializers()) { - generateStaticInitializers(); - } } private void generate(JetFile file) { @@ -120,11 +116,7 @@ public class NamespaceCodegen extends MemberCodegen { assert descriptor != null : "No namespace found for file " + file + " declared package: " + file.getPackageName(); int countOfDeclarationsInSrcClass = 0; for (JetDeclaration declaration : file.getDeclarations()) { - if (declaration instanceof JetProperty) { - final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); - genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); - } - else if (declaration instanceof JetNamedFunction) { + if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) { countOfDeclarationsInSrcClass++; } else if (declaration instanceof JetClassOrObject) { @@ -154,7 +146,7 @@ public class NamespaceCodegen extends MemberCodegen { builder.visitSource(file.getName(), null); for (JetDeclaration declaration : file.getDeclarations()) { - if (declaration instanceof JetNamedFunction) { + if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) { { final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); @@ -168,6 +160,10 @@ public class NamespaceCodegen extends MemberCodegen { } } + if (hasNonConstantPropertyInitializers()) { + generateStaticInitializers(builder, file); + } + builder.done(); } } @@ -210,41 +206,32 @@ public class NamespaceCodegen extends MemberCodegen { } } - private void generateStaticInitializers() { - final JetFile namespace = files.iterator().next(); // @todo: hack + private void generateStaticInitializers(@NotNull ClassBuilder builder, @NotNull JetFile file) { + MethodVisitor mv = builder.newMethod(file, ACC_PUBLIC | ACC_STATIC, "", "()V", null, null); + if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + mv.visitCode(); - v.addOptionalDeclaration(new ClassBuilderOnDemand.ClassBuilderCallback() { - @Override - public void doSomething(@NotNull ClassBuilder v) { - MethodVisitor mv = v.newMethod(namespace, ACC_PUBLIC | ACC_STATIC, "", "()V", null, null); - if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { - mv.visitCode(); + FrameMap frameMap = new FrameMap(); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContext.STATIC, state); - FrameMap frameMap = new FrameMap(); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContext.STATIC, state); - - 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)) { - final PropertyDescriptor descriptor = - (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration); - assert descriptor != null; - codegen.genToJVMStack(initializer); - StackValue.Property propValue = codegen.intermediateValueForProperty(descriptor, true, null); - propValue.store(propValue.type, new InstructionAdapter(mv)); - } - } - } + 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; + codegen.genToJVMStack(initializer); + StackValue.Property propValue = codegen.intermediateValueForProperty(descriptor, true, null); + propValue.store(propValue.type, new InstructionAdapter(mv)); } - - mv.visitInsn(RETURN); - FunctionCodegen.endVisit(mv, "static initializer for namespace", namespace); - mv.visitEnd(); } } - }); + + mv.visitInsn(RETURN); + FunctionCodegen.endVisit(mv, "static initializer for namespace", file); + mv.visitEnd(); + } } private boolean hasNonConstantPropertyInitializers() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 881be36ccd1..2d99cf10ef1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -66,10 +66,10 @@ public class PropertyCodegen extends GenerationStateAware { throw new UnsupportedOperationException("expect a property to have a property descriptor"); } PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - assert kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL + assert kind instanceof OwnerKind.StaticDelegateKind || kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL : "Generating property with a wrong kind (" + kind + "): " + descriptor; - if (kind != OwnerKind.TRAIT_IMPL) { + if (kind != OwnerKind.TRAIT_IMPL && !(kind instanceof OwnerKind.StaticDelegateKind)) { generateBackingField(p, propertyDescriptor); } generateGetter(p, propertyDescriptor); @@ -166,7 +166,7 @@ public class PropertyCodegen extends GenerationStateAware { return; } - if (kind == OwnerKind.NAMESPACE) { + if (kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind) { flags |= ACC_STATIC; } @@ -200,6 +200,9 @@ public class PropertyCodegen extends GenerationStateAware { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { genStubThrow(mv); } + else if (kind instanceof OwnerKind.StaticDelegateKind) { + FunctionCodegen.generateStaticDelegateMethodBody(mv, jvmMethodSignature.getAsmMethod(), (OwnerKind.StaticDelegateKind) kind); + } else { InstructionAdapter iv = new InstructionAdapter(mv); if (kind != OwnerKind.NAMESPACE) { @@ -246,7 +249,7 @@ public class PropertyCodegen extends GenerationStateAware { return; } - if (kind == OwnerKind.NAMESPACE) { + if (kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind) { flags |= ACC_STATIC; } @@ -276,6 +279,9 @@ public class PropertyCodegen extends GenerationStateAware { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { genStubThrow(mv); } + else if (kind instanceof OwnerKind.StaticDelegateKind) { + FunctionCodegen.generateStaticDelegateMethodBody(mv, jvmMethodSignature.getAsmMethod(), (OwnerKind.StaticDelegateKind) kind); + } else { InstructionAdapter iv = new InstructionAdapter(mv); final Type type = typeMapper.mapType(propertyDescriptor); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index 6540c70e8eb..99bed1e22f7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -29,6 +29,7 @@ import org.jetbrains.jet.codegen.signature.*; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -66,7 +67,7 @@ public class JetTypeMapper extends BindingTraceAware { DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (containingDeclaration instanceof NamespaceDescriptor) { - return jvmClassNameForNamespace((NamespaceDescriptor) containingDeclaration); + return jvmClassNameForNamespace((NamespaceDescriptor) containingDeclaration, descriptor); } else if (containingDeclaration instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; @@ -121,7 +122,7 @@ public class JetTypeMapper extends BindingTraceAware { } @NotNull - private JvmClassName jvmClassNameForNamespace(@NotNull NamespaceDescriptor namespace) { + private JvmClassName jvmClassNameForNamespace(@NotNull NamespaceDescriptor namespace, @NotNull DeclarationDescriptor descriptor) { StringBuilder r = new StringBuilder(); @@ -145,7 +146,20 @@ public class JetTypeMapper extends BindingTraceAware { if (r.length() > 0) { r.append("/"); } - r.append(PackageClassUtils.getPackageClassName(namespace.getFqName())); + + if (descriptor instanceof PropertyDescriptor) { + JetFile file = BindingContextUtils.getContainingFile(bindingContext, descriptor); + if (file != null) { + String internalName = NamespaceCodegen.getNamespacePartInternalName(file); + r.append(internalName.substring(r.length())); + } + else { + r.append(PackageClassUtils.getPackageClassName(namespace.getFqName())); + } + } + else { + r.append(PackageClassUtils.getPackageClassName(namespace.getFqName())); + } } if (r.length() == 0) { @@ -450,7 +464,7 @@ public class JetTypeMapper extends BindingTraceAware { JvmClassName thisClass; if (functionParent instanceof NamespaceDescriptor) { assert !superCall; - owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent); + owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent, functionDescriptor); ownerForDefaultImpl = ownerForDefaultParam = owner; invokeOpcode = INVOKESTATIC; thisClass = null; diff --git a/compiler/testData/writeFlags/property/deprecatedFlag/topLevelProperty.kt b/compiler/testData/writeFlags/property/deprecatedFlag/topLevelProperty.kt index 7fa1884feea..80f0c9c3329 100644 --- a/compiler/testData/writeFlags/property/deprecatedFlag/topLevelProperty.kt +++ b/compiler/testData/writeFlags/property/deprecatedFlag/topLevelProperty.kt @@ -1,5 +1,6 @@ deprecated("") val test: Int = 0 // TESTED_OBJECT_KIND: property -// TESTED_OBJECTS: _DefaultPackage, test +// TESTED_OBJECTS: _DefaultPackage$src$topLevelProperty$, test +// IS_FULL_CONTAINING_CLASS_NAME: false // FLAGS: ACC_DEPRECATED, ACC_FINAL, ACC_STATIC diff --git a/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java index bbb9790b5bb..fb3f2ff27c1 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java @@ -76,7 +76,7 @@ public class PropertyGenTest extends CodegenTestCase { public void testPrivatePropertyInNamespace() throws Exception { loadText("private val x = 239"); - final Class nsClass = generateNamespaceClass(); + final Class nsClass = generateNamespaceSrcClass(); final Field[] fields = nsClass.getDeclaredFields(); assertEquals(1, fields.length); final Field field = fields[0]; diff --git a/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java b/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java index 3e6f9342ed9..202d1f4164c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java @@ -32,6 +32,7 @@ import java.lang.reflect.Field; import java.util.List; import static org.jetbrains.jet.InTextDirectivesUtils.findListWithPrefix; +import static org.jetbrains.jet.InTextDirectivesUtils.findStringWithPrefix; /* * Test correctness of written flags in class file @@ -69,22 +70,26 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { TestedObject testedObject = parseExpectedTestedObject(fileText); - boolean isClassFound = false; + String className = null; for (String filename : factory.files()) { - if (filename.equals(testedObject.containingClass + ".class")) { - isClassFound = true; - ClassReader cr = new ClassReader(factory.asBytes(filename)); - TestClassVisitor classVisitor; - classVisitor = getClassVisitor(testedObject.kind, testedObject.name); - cr.accept(classVisitor, ClassReader.SKIP_CODE); - int expectedAccess = getExpectedFlags(fileText); - assertEquals("Wrong access flag \n" + factory.asText(filename), expectedAccess, classVisitor.getAccess()); + if (testedObject.isFullContainingClassName && filename.equals(testedObject.containingClass + ".class")) { + className = filename; + } + else if (!testedObject.isFullContainingClassName && filename.startsWith(testedObject.containingClass)) { + className = filename; } } - if (!isClassFound) { + if (className == null) { throw new AssertionError("Couldn't find a class file with name " + testedObject.containingClass); } + + ClassReader cr = new ClassReader(factory.asBytes(className)); + TestClassVisitor classVisitor; + classVisitor = getClassVisitor(testedObject.kind, testedObject.name); + cr.accept(classVisitor, ClassReader.SKIP_CODE); + int expectedAccess = getExpectedFlags(fileText); + assertEquals("Wrong access flag \n" + factory.asText(className), expectedAccess, classVisitor.getAccess()); } private static TestedObject parseExpectedTestedObject(String fileText) { @@ -103,16 +108,18 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { "TESTED_OBJECTS instruction must contains one (for class) or two (for function and property) values"); } - List testedObjectKinds = findListWithPrefix("// TESTED_OBJECT_KIND: ", fileText); - assertTrue("TESTED_OBJECT_KIND instruction must contains exactly one value. Actual value is " + testedObjectKinds.size(), - testedObjectKinds.size() == 1); - result.kind = testedObjectKinds.get(0); + result.kind = findStringWithPrefix("// TESTED_OBJECT_KIND: ", fileText); + List isFullName = findListWithPrefix("// IS_FULL_CONTAINING_CLASS_NAME: ", fileText); + if (isFullName.size() == 1) { + result.isFullContainingClassName = Boolean.parseBoolean(isFullName.get(0)); + } return result; } private static class TestedObject { public String name; public String containingClass = ""; + public boolean isFullContainingClassName = true; public String kind; }