From 18c59d549505aca5972397e44f1236faa621c8c1 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 25 Oct 2013 20:55:16 +0400 Subject: [PATCH] Treat anonymous objects as classes (ClassKind.CLASS) They're not objects per se, i.e. they're not singletons --- .../org/jetbrains/jet/codegen/AsmUtil.java | 4 ++ .../jetbrains/jet/codegen/CodegenUtil.java | 6 --- .../codegen/ImplementationBodyCodegen.java | 28 +++++------ .../lang/resolve/TypeHierarchyResolver.java | 47 ++++++++++--------- .../class/accessFlags/objectLiteral.kt | 7 +++ .../flags/WriteFlagsTestGenerated.java | 5 ++ .../jet/lang/resolve/DescriptorUtils.java | 14 +++--- .../k2js/translate/context/Namer.java | 25 +++++----- .../declaration/ClassTranslator.java | 7 ++- .../translate/utils/AnnotationsUtils.java | 13 ----- 10 files changed, 78 insertions(+), 78 deletions(-) create mode 100644 compiler/testData/writeFlags/class/accessFlags/objectLiteral.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 89f181d5946..f82199043c5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -252,6 +252,10 @@ public class AsmUtil { return NO_FLAG_PACKAGE_PRIVATE; } if (memberDescriptor instanceof ConstructorDescriptor) { + if (isAnonymousObject(containingDeclaration)) { + return NO_FLAG_PACKAGE_PRIVATE; + } + ClassKind kind = ((ClassDescriptor) containingDeclaration).getKind(); if (kind == ClassKind.OBJECT) { return NO_FLAG_PACKAGE_PRIVATE; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 022243e5504..ef0680eda59 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -34,8 +34,6 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; -import org.jetbrains.jet.lang.psi.JetClassOrObject; -import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil; import org.jetbrains.jet.lang.resolve.name.Name; @@ -87,10 +85,6 @@ public class CodegenUtil { return invokeDescriptor; } - public static boolean isNonLiteralObject(JetClassOrObject myClass) { - return myClass instanceof JetObjectDeclaration && !((JetObjectDeclaration) myClass).isObjectLiteral(); - } - public static String createTmpVariableName(Collection existingNames) { String prefix = "tmp"; int i = RANDOM.nextInt(Integer.MAX_VALUE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 216c487abca..b67e4c3d1ec 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -1028,35 +1028,35 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(0, OBJECT_TYPE); } - for (int paramIndex = 0; paramIndex < argTypes.length; paramIndex++) { - Type argType = argTypes[paramIndex]; + for (Type argType : argTypes) { iv.load(reg, argType); - //noinspection AssignmentToForLoopParameter reg += argType.getSize(); } callableMethod.invokeWithoutAssertions(iv); } private void generateFieldForSingleton() { - boolean hasClassObject = descriptor.getClassObjectDescriptor() != null; - boolean isEnumClass = DescriptorUtils.isEnumClass(descriptor); - boolean isObjectDeclaration = descriptor.getKind() == ClassKind.OBJECT && isNonLiteralObject(myClass) ; + if (isEnumClass(descriptor)) return; - if (!isObjectDeclaration && !hasClassObject || isEnumClass) return; - - ClassDescriptor fieldTypeDescriptor = hasClassObject ? descriptor.getClassObjectDescriptor() : descriptor; - assert fieldTypeDescriptor != null; - StackValue.Field field = StackValue.singleton(fieldTypeDescriptor, typeMapper); + ClassDescriptor classObjectDescriptor = descriptor.getClassObjectDescriptor(); + ClassDescriptor fieldTypeDescriptor; JetClassOrObject original; - if (hasClassObject) { + if (isObject(descriptor)) { + original = myClass; + fieldTypeDescriptor = descriptor; + } + else if (classObjectDescriptor != null) { JetClassObject classObject = ((JetClass) myClass).getClassObject(); - assert classObject != null : myClass.getText(); + assert classObject != null : "Class object not found: " + myClass.getText(); original = classObject.getObjectDeclaration(); + fieldTypeDescriptor = classObjectDescriptor; } else { - original = myClass; + return; } + StackValue.Field field = StackValue.singleton(fieldTypeDescriptor, typeMapper); + v.newField(original, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null); if (!AsmUtil.isClassObjectWithBackingFieldsInOuter(fieldTypeDescriptor)) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 55f4f8f91ff..30d99a61ccd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.impl.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.name.SpecialNames; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; @@ -478,11 +479,18 @@ public class TypeHierarchyResolver { @Override public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) { - MutableClassDescriptor objectDescriptor = - createClassDescriptorForObject(declaration, owner, outerScope, JetPsiUtil.safeName(declaration.getName()), - ClassKind.OBJECT); - owner.addObjectDescriptor(objectDescriptor); - trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(declaration), objectDescriptor); + if (declaration.isObjectLiteral()) { + MutableClassDescriptor descriptor = + createClassDescriptorForObject(declaration, SpecialNames.NO_NAME_PROVIDED, ClassKind.CLASS); + context.getClasses().put(declaration, descriptor); + return; + } + + MutableClassDescriptor descriptor = + createClassDescriptorForObject(declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.OBJECT); + context.getObjects().put(declaration, descriptor); + owner.addObjectDescriptor(descriptor); + trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(declaration), descriptor); } @Override @@ -504,11 +512,10 @@ public class TypeHierarchyResolver { public void visitClassObject(@NotNull JetClassObject classObject) { JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration(); if (objectDeclaration != null) { - Name classObjectName = getClassObjectName(owner.getOwnerForChildren().getName()); - - MutableClassDescriptor classObjectDescriptor = createClassDescriptorForObject( - objectDeclaration, owner, outerScope, - classObjectName, ClassKind.CLASS_OBJECT); + MutableClassDescriptor classObjectDescriptor = + createClassDescriptorForObject(objectDeclaration, getClassObjectName(owner.getOwnerForChildren().getName()), + ClassKind.CLASS_OBJECT); + context.getObjects().put(objectDeclaration, classObjectDescriptor); NamespaceLikeBuilder.ClassObjectStatus status = owner.setClassObjectDescriptor(classObjectDescriptor); switch (status) { @@ -571,21 +578,17 @@ public class TypeHierarchyResolver { @NotNull private MutableClassDescriptor createClassDescriptorForObject( - @NotNull JetObjectDeclaration declaration, @NotNull NamespaceLikeBuilder owner, - @NotNull JetScope scope, @NotNull Name name, @NotNull ClassKind kind + @NotNull JetObjectDeclaration declaration, + @NotNull Name name, + @NotNull ClassKind kind ) { - MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor( - owner.getOwnerForChildren(), scope, kind, false, name); + MutableClassDescriptor descriptor = new MutableClassDescriptor(owner.getOwnerForChildren(), outerScope, kind, false, name); - context.getObjects().put(declaration, mutableClassDescriptor); + prepareForDeferredCall(descriptor.getScopeForMemberResolution(), descriptor, declaration); - JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution(); - - prepareForDeferredCall(classScope, mutableClassDescriptor, declaration); - - createPrimaryConstructorForObject(declaration, mutableClassDescriptor); - trace.record(BindingContext.CLASS, declaration, mutableClassDescriptor); - return mutableClassDescriptor; + createPrimaryConstructorForObject(declaration, descriptor); + trace.record(BindingContext.CLASS, declaration, descriptor); + return descriptor; } private MutableClassDescriptor createClassDescriptorForEnumEntry( diff --git a/compiler/testData/writeFlags/class/accessFlags/objectLiteral.kt b/compiler/testData/writeFlags/class/accessFlags/objectLiteral.kt new file mode 100644 index 00000000000..9eaf745a96f --- /dev/null +++ b/compiler/testData/writeFlags/class/accessFlags/objectLiteral.kt @@ -0,0 +1,7 @@ +class Foo { + val x = object { } +} + +// TESTED_OBJECT_KIND: class +// TESTED_OBJECTS: Foo$x$1 +// FLAGS: ACC_PUBLIC, ACC_FINAL, ACC_SUPER diff --git a/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java index 3070770fdad..b511984cfea 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java @@ -50,6 +50,11 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/class/accessFlags"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("objectLiteral.kt") + public void testObjectLiteral() throws Exception { + doTest("compiler/testData/writeFlags/class/accessFlags/objectLiteral.kt"); + } + @TestMetadata("publicFinalClass.kt") public void testPublicFinalClass() throws Exception { doTest("compiler/testData/writeFlags/class/accessFlags/publicFinalClass.kt"); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 6e9ff6a2b87..93542a6d641 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.name.SpecialNames; import org.jetbrains.jet.lang.resolve.scopes.FilteringScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.*; @@ -230,8 +231,12 @@ public class DescriptorUtils { return isKindOf(descriptor, ClassKind.CLASS_OBJECT); } - public static boolean isAnonymousObject(@NotNull ClassifierDescriptor descriptor) { - return isKindOf(descriptor, ClassKind.OBJECT) && descriptor.getName().isSpecial(); + public static boolean isAnonymousObject(@NotNull DeclarationDescriptor descriptor) { + return isClass(descriptor) && descriptor.getName().equals(SpecialNames.NO_NAME_PROVIDED); + } + + public static boolean isObject(@NotNull DeclarationDescriptor descriptor) { + return isKindOf(descriptor, ClassKind.OBJECT); } public static boolean isEnumEntry(@NotNull DeclarationDescriptor descriptor) { @@ -325,10 +330,7 @@ public class DescriptorUtils { @NotNull public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) { ClassKind classKind = classDescriptor.getKind(); - if (classKind == ClassKind.ENUM_CLASS) { - return Visibilities.PRIVATE; - } - if (classKind.isSingleton()) { + if (classKind == ClassKind.ENUM_CLASS || classKind.isSingleton() || isAnonymousObject(classDescriptor)) { return Visibilities.PRIVATE; } assert classKind == ClassKind.CLASS || classKind == ClassKind.TRAIT || classKind == ClassKind.ANNOTATION_CLASS; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java index e8f0b9bca58..1b6dcc22b0d 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java @@ -19,12 +19,13 @@ package org.jetbrains.k2js.translate.context; import com.google.dart.compiler.backend.js.ast.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.plugin.JetLanguage; -import java.util.List; +import static org.jetbrains.jet.lang.descriptors.ClassKind.TRAIT; /** * Encapuslates different types of constants and naming conventions. @@ -267,19 +268,17 @@ public final class Namer { } @NotNull - public JsInvocation classCreateInvocation(@NotNull ClassDescriptor descriptor, @NotNull List arguments) { - switch (descriptor.getKind()) { - case TRAIT: - return new JsInvocation(traitCreationMethodReference(), arguments); - - case OBJECT: - case CLASS_OBJECT: - case ENUM_ENTRY: - return new JsInvocation(objectCreationMethodReference(), arguments); - - default: - return new JsInvocation(classCreationMethodReference(), arguments); + public JsExpression classCreateInvocation(@NotNull ClassDescriptor descriptor) { + ClassKind kind = descriptor.getKind(); + if (kind == TRAIT) { + return traitCreationMethodReference(); } + + if (kind.isSingleton() || DescriptorUtils.isAnonymousObject(descriptor)) { + return objectCreationMethodReference(); + } + + return classCreationMethodReference(); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java index 2228a7ec93c..813aadb347f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java @@ -37,8 +37,7 @@ import org.jetbrains.k2js.translate.utils.JsAstUtils; import java.util.*; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassDescriptorForType; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassDescriptorForTypeConstructor; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.types.TypeUtils.topologicallySortSuperclassesAndRecordAllInstances; import static org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator.createPlace; import static org.jetbrains.k2js.translate.initializer.InitializerUtils.createClassObjectInitializer; @@ -121,7 +120,7 @@ public final class ClassTranslator extends AbstractTranslator { @NotNull public JsInvocation translate(@NotNull TranslationContext declarationContext) { - return context().namer().classCreateInvocation(descriptor, getClassCreateInvocationArguments(declarationContext)); + return new JsInvocation(context().namer().classCreateInvocation(descriptor), getClassCreateInvocationArguments(declarationContext)); } private boolean isTrait() { @@ -138,7 +137,7 @@ public final class ClassTranslator extends AbstractTranslator { if (!isTopLevelDeclaration) { qualifiedReference = null; } - else if (descriptor.getKind().isSingleton()) { + else if (descriptor.getKind().isSingleton() || isAnonymousObject(descriptor)) { qualifiedReference = null; declarationContext.literalFunctionTranslator().setDefinitionPlace( new NotNullLazyValue, LabelGenerator, JsExpression>>() { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java index de275385345..3092b09a017 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java @@ -19,7 +19,6 @@ package org.jetbrains.k2js.translate.utils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; @@ -29,8 +28,6 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getContaining public final class AnnotationsUtils { - private static final String ENUMERABLE = "js.enumerable"; - private AnnotationsUtils() { } @@ -108,16 +105,6 @@ public final class AnnotationsUtils { return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE); } - public static boolean isEnumerable(@NotNull DeclarationDescriptor descriptor) { - if (getAnnotationByName(descriptor, ENUMERABLE) != null) { - return true; - } - ClassDescriptor containingClass = getContainingClass(descriptor); - return containingClass != null && - ((containingClass.getKind().equals(ClassKind.OBJECT) && containingClass.getName().isSpecial()) || - getAnnotationByName(containingClass, ENUMERABLE) != null); - } - public static boolean isLibraryObject(@NotNull DeclarationDescriptor descriptor) { return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.LIBRARY); }