Move top level properties from package class to package$src

This commit is contained in:
Natalia.Ukhorskaya
2013-02-28 18:25:46 +04:00
parent 4bfdeffd0b
commit d501e8821c
7 changed files with 80 additions and 65 deletions
@@ -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
@@ -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, "<clinit>", "()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, "<clinit>", "()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() {
@@ -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);
@@ -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;
@@ -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
@@ -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];
@@ -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<String> 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<String> 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;
}