Treat anonymous objects as classes (ClassKind.CLASS)
They're not objects per se, i.e. they're not singletons
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<String> existingNames) {
|
||||
String prefix = "tmp";
|
||||
int i = RANDOM.nextInt(Integer.MAX_VALUE);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<JsExpression> 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
|
||||
|
||||
@@ -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<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>>() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user