KT-11030 Unify concept of objects and companion objects. Fix order of initialization of nested objects.

This commit is contained in:
Alexey Andreev
2016-03-10 11:47:54 +03:00
parent 8e7d949dd4
commit 337078faf3
13 changed files with 95 additions and 232 deletions
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.js.resolve.JsPlatform;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -93,10 +92,9 @@ public final class Namer {
public static final String ANOTHER_THIS_PARAMETER_NAME = "$this";
private static final String THROW_NPE_FUN_NAME = "throwNPE";
private static final String COMPANION_OBJECT_GETTER = "object";
private static final String COMPANION_OBJECT_INITIALIZER = "object_initializer$";
private static final String PROTOTYPE_NAME = "prototype";
public static final String CAPTURED_VAR_FIELD = "v";
private static final String CAPTURED_VAR_FIELD = "v";
public static final String DEFINE_INLINE_FUNCTION = "defineInlineFunction";
private static final JsNameRef JS_OBJECT = new JsNameRef("Object");
@@ -170,16 +168,6 @@ public final class Namer {
return getNameWithPrefix(propertyName, SETTER_PREFIX);
}
@NotNull
public static JsExpression getCompanionObjectAccessor(@NotNull JsExpression referenceToClass) {
return fqnWithoutSideEffects(COMPANION_OBJECT_GETTER, referenceToClass);
}
@NotNull
public static String getNameForCompanionObjectInitializer() {
return COMPANION_OBJECT_INITIALIZER;
}
@NotNull
public static String getPrototypeName() {
return PROTOTYPE_NAME;
@@ -240,8 +228,6 @@ public final class Namer {
return new Namer(rootScope);
}
@NotNull
private final JsName kotlinName;
@NotNull
private final JsObjectScope kotlinScope;
@NotNull
@@ -282,7 +268,6 @@ public final class Namer {
private final JsExpression modulesMap;
private Namer(@NotNull JsScope rootScope) {
kotlinName = rootScope.declareName(KOTLIN_NAME);
kotlinScope = JsObjectScope(rootScope, "Kotlin standard object");
traitName = kotlinScope.declareName(TRAIT_OBJECT_NAME);
@@ -310,9 +310,7 @@ public final class StaticContext {
Rule<JsName> constructorOrCompanionObjectHasTheSameNameAsTheClass = new Rule<JsName>() {
@Override
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof ConstructorDescriptor && ((ConstructorDescriptor) descriptor).isPrimary() ||
DescriptorUtils.isCompanionObject(descriptor)
) {
if (descriptor instanceof ConstructorDescriptor && ((ConstructorDescriptor) descriptor).isPrimary()) {
//noinspection ConstantConditions
return getNameForDescriptor(descriptor.getContainingDeclaration());
}
@@ -588,7 +586,7 @@ public final class StaticContext {
if (!(descriptor instanceof ClassDescriptor)) {
return null;
}
DeclarationDescriptor container = getEnclosingNonSingleton(descriptor.getContainingDeclaration());
DeclarationDescriptor container = getEnclosing(descriptor.getContainingDeclaration());
if (container == null) {
return null;
}
@@ -596,16 +594,7 @@ public final class StaticContext {
if (isNativeObject(descriptor)) {
return null;
}
ClassDescriptor cls = (ClassDescriptor) descriptor;
if (cls.getKind() == ClassKind.ENUM_ENTRY || cls.getKind() == ClassKind.OBJECT) {
return null;
}
JsExpression result = getQualifiedReference(container);
if (DescriptorUtils.isCompanionObject(container)) {
result = Namer.getCompanionObjectAccessor(result);
}
return applySideEffects(result, descriptor);
return getQualifiedReference(container);
}
};
@@ -639,8 +628,8 @@ public final class StaticContext {
}
@Nullable
private static ClassDescriptor getEnclosingNonSingleton(@NotNull DeclarationDescriptor descriptor) {
while (descriptor != null && (!(descriptor instanceof ClassDescriptor) || DescriptorUtils.isObject(descriptor))) {
private static ClassDescriptor getEnclosing(@Nullable DeclarationDescriptor descriptor) {
while (descriptor != null && !(descriptor instanceof ClassDescriptor)) {
descriptor = descriptor.getContainingDeclaration();
}
return (ClassDescriptor) descriptor;
@@ -32,11 +32,9 @@ import org.jetbrains.kotlin.js.translate.context.*
import org.jetbrains.kotlin.js.translate.expression.FunctionTranslator
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
import org.jetbrains.kotlin.js.translate.initializer.ClassInitializerTranslator
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator.translateAsFQReference
import org.jetbrains.kotlin.js.translate.utils.*
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getReceiverParameterForDeclaration
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getSupertypesWithoutFakes
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getPrimaryConstructorParameters
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.simpleReturnFunction
@@ -64,12 +62,8 @@ class ClassTranslator private constructor(
private val descriptor = getClassDescriptor(context.bindingContext(), classDeclaration)
private fun translateObjectLiteralExpression(): JsExpression {
return if (descriptor.containingDeclaration is ClassDescriptor && descriptor.kind == ClassKind.OBJECT)
translateObjectInsideClass(context())
else
translate(context())
}
// TODO: eliminate
private fun translateObjectLiteralExpression() = translate(context())
private fun translate(declarationContext: TranslationContext = context()): JsInvocation {
return JsInvocation(context().namer().classCreateInvocation(descriptor), getClassCreateInvocationArguments(declarationContext))
@@ -152,22 +146,6 @@ class ClassTranslator private constructor(
}
private fun fixContextForCompanionObjectAccessing(context: TranslationContext): TranslationContext {
// In Kotlin we can access to companion object members without qualifier just by name, but we should translate it to access with FQ name.
// So create alias for companion object receiver parameter.
val companionObjectDescriptor = descriptor.companionObjectDescriptor
if (companionObjectDescriptor != null) {
val referenceToClass = translateAsFQReference(companionObjectDescriptor.containingDeclaration, context)
val companionObjectAccessor = Namer.getCompanionObjectAccessor(referenceToClass)
val companionObjectReceiver = getReceiverParameterForDeclaration(companionObjectDescriptor)
context.aliasingContext().registerAlias(companionObjectReceiver, companionObjectAccessor)
}
// Overlap alias of companion object receiver for accessing from containing class(see previous if block),
// because inside companion object we should use simple name for access.
if (isCompanionObject(descriptor)) {
return context.innerContextWithAliased(descriptor.thisAsReceiverParameter, JsLiteral.THIS)
}
return context
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,7 @@
package org.jetbrains.kotlin.js.translate.declaration;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsFunction;
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
import com.google.dart.compiler.backend.js.ast.*;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
@@ -30,21 +28,19 @@ import org.jetbrains.kotlin.js.translate.general.Translation;
import org.jetbrains.kotlin.js.translate.general.TranslatorVisitor;
import org.jetbrains.kotlin.js.translate.initializer.ClassInitializerTranslator;
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.types.KotlinType;
import java.util.List;
import static org.jetbrains.kotlin.js.translate.initializer.InitializerUtils.createCompanionObjectInitializer;
import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor;
import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getFunctionDescriptor;
import static org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getSupertypesWithoutFakes;
public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
protected final List<JsPropertyInitializer> result;
protected final List<JsPropertyInitializer> staticResult;
protected final List<JsPropertyInitializer> enumEntryList = new SmartList<JsPropertyInitializer>();
private final List<JsPropertyInitializer> staticResult;
private final List<JsPropertyInitializer> enumEntryList = new SmartList<JsPropertyInitializer>();
public DeclarationBodyVisitor(@NotNull List<JsPropertyInitializer> result, @NotNull List<JsPropertyInitializer> staticResult) {
this.result = result;
@@ -88,15 +84,11 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
@Override
public Void visitObjectDeclaration(@NotNull KtObjectDeclaration declaration, TranslationContext context) {
if (!declaration.isCompanion()) {
// parsed it in initializer visitor => no additional actions are needed
return null;
}
JsExpression value = ClassTranslator.generateClassCreation(declaration, context);
JsExpression object = ClassTranslator.generateObjectDeclaration(declaration, context);
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), declaration);
JsName objName = context.getNameForDescriptor(descriptor);
staticResult.add(new JsPropertyInitializer(objName.makeRef(), object));
ClassDescriptor descriptor = getClassDescriptor(context.bindingContext(), declaration);
JsFunction fun = TranslationUtils.simpleReturnFunction(context.getScopeForDescriptor(descriptor), value);
staticResult.add(createCompanionObjectInitializer(fun, context));
return null;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,10 +21,10 @@ import com.intellij.util.SmartList
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.general.Translation
import org.jetbrains.kotlin.js.translate.initializer.InitializerUtils
import org.jetbrains.kotlin.js.translate.initializer.InitializerUtils.generateInitializerForDelegate
import org.jetbrains.kotlin.js.translate.initializer.InitializerUtils.generateInitializerForProperty
import org.jetbrains.kotlin.js.translate.initializer.InitializerVisitor
import org.jetbrains.kotlin.js.translate.utils.BindingUtils
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getPropertyDescriptor
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.psi.KtClass
@@ -56,7 +56,14 @@ class FileDeclarationVisitor(
}
override fun visitObjectDeclaration(declaration: KtObjectDeclaration, context: TranslationContext?): Void? {
InitializerUtils.generateObjectInitializer(declaration, initializerStatements, context!!)
context!!
// TODO: avoid duplication with superclass
val obj = ClassTranslator.generateObjectDeclaration(declaration, context)
val descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), declaration)
val objName = context.getNameForDescriptor(descriptor)
result.add(JsPropertyInitializer(objName.makeRef(), obj))
return null
}
@@ -280,7 +280,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
public JsExpression visitSimpleNameExpression(@NotNull KtSimpleNameExpression expression,
@NotNull TranslationContext context) {
return ReferenceTranslator.translateSimpleNameWithQualifier(expression, null, context).source(expression);
return ReferenceTranslator.translateSimpleName(expression, context).source(expression);
}
@Override
@@ -19,21 +19,14 @@ package org.jetbrains.kotlin.js.translate.initializer;
import com.google.dart.compiler.backend.js.ast.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.js.translate.context.Namer;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.declaration.ClassTranslator;
import org.jetbrains.kotlin.js.translate.general.Translation;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.psi.KtExpression;
import org.jetbrains.kotlin.psi.KtObjectDeclaration;
import org.jetbrains.kotlin.psi.KtProperty;
import java.util.List;
import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor;
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.assignment;
import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.assignmentToBackingField;
public final class InitializerUtils {
@@ -58,20 +51,4 @@ public final class InitializerUtils {
}
return null;
}
public static void generateObjectInitializer(
@NotNull KtObjectDeclaration declaration,
@NotNull List<JsStatement> initializers,
@NotNull TranslationContext context
) {
JsExpression value = ClassTranslator.generateObjectDeclaration(declaration, context);
ClassDescriptor descriptor = getClassDescriptor(context.bindingContext(), declaration);
JsExpression expression = assignment(new JsNameRef(descriptor.getName().asString(), JsLiteral.THIS), value);
initializers.add(expression.makeStmt());
}
public static JsPropertyInitializer createCompanionObjectInitializer(JsExpression value, TranslationContext context) {
JsStringLiteral companionObjectInitStr = context.program().getStringLiteral(Namer.getNameForCompanionObjectInitializer());
return new JsPropertyInitializer(companionObjectInitStr, value);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,14 +71,6 @@ public final class InitializerVisitor extends TranslatorVisitor<Void> {
return null;
}
@Override
public Void visitObjectDeclaration(@NotNull KtObjectDeclaration declaration, @NotNull TranslationContext context) {
if (!declaration.isCompanion()) {
InitializerUtils.generateObjectInitializer(declaration, result, context);
}
return null;
}
@Override
public Void visitSecondaryConstructor(@NotNull KtSecondaryConstructor constructor, TranslationContext data) {
return null;
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,32 +20,27 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.js.translate.context.Namer;
import org.jetbrains.kotlin.js.translate.context.TemporaryVariable;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.js.translate.intrinsic.objects.ObjectIntrinsic;
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils;
import org.jetbrains.kotlin.psi.KtReferenceExpression;
import org.jetbrains.kotlin.psi.KtSimpleNameExpression;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator.translateAsFQReference;
import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isNonCompanionObject;
public class CompanionObjectAccessTranslator extends AbstractTranslator implements CachedAccessTranslator {
public class CompanionObjectIntrinsicAccessTranslator extends AbstractTranslator implements CachedAccessTranslator {
@NotNull
/*package*/ static CompanionObjectAccessTranslator newInstance(
/*package*/ static CompanionObjectIntrinsicAccessTranslator newInstance(
@NotNull KtSimpleNameExpression expression,
@NotNull TranslationContext context
) {
DeclarationDescriptor referenceDescriptor = getDescriptorForReferenceExpression(context.bindingContext(), expression);
assert referenceDescriptor != null : "JetSimpleName expression must reference a descriptor " + expression.getText();
return new CompanionObjectAccessTranslator(referenceDescriptor, context);
return new CompanionObjectIntrinsicAccessTranslator(referenceDescriptor, context);
}
/*package*/ static boolean isCompanionObjectReference(
@@ -53,32 +48,21 @@ public class CompanionObjectAccessTranslator extends AbstractTranslator implemen
@NotNull TranslationContext context
) {
DeclarationDescriptor descriptor = getDescriptorForReferenceExpression(context.bindingContext(), expression);
return descriptor instanceof ClassDescriptor && !AnnotationsUtils.isNativeObject(descriptor);
return descriptor instanceof ClassDescriptor && context.intrinsics().getObjectIntrinsic((ClassDescriptor) descriptor).exists();
}
@NotNull
private final JsExpression referenceToCompanionObject;
private CompanionObjectAccessTranslator(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) {
private CompanionObjectIntrinsicAccessTranslator(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) {
super(context);
this.referenceToCompanionObject = generateReferenceToCompanionObject(descriptor, context);
}
@NotNull
private static JsExpression generateReferenceToCompanionObject(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) {
if (descriptor instanceof ClassDescriptor) {
ObjectIntrinsic objectIntrinsic = context.intrinsics().getObjectIntrinsic((ClassDescriptor) descriptor);
if (objectIntrinsic.exists()) {
return objectIntrinsic.apply(context);
}
}
JsExpression fqReference = translateAsFQReference(descriptor, context);
if (isNonCompanionObject(descriptor) || isEnumEntry(descriptor)) {
return fqReference;
}
return Namer.getCompanionObjectAccessor(fqReference);
ObjectIntrinsic objectIntrinsic = context.intrinsics().getObjectIntrinsic((ClassDescriptor) descriptor);
return objectIntrinsic.apply(context);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.utils.ErrorReportingUtils;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import static org.jetbrains.kotlin.js.translate.general.Translation.translateAsExpression;
import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
@@ -55,7 +57,11 @@ public final class QualifiedExpressionTranslator {
@NotNull KtQualifiedExpression expression,
@NotNull TranslationContext context
) {
JsExpression receiver = translateReceiver(expression, context);
ResolvedCall<?> call = CallUtilKt.getResolvedCall(expression, context.bindingContext());
JsExpression receiver = null;
if (call != null) {
receiver = translateReceiver(expression, context);
}
KtExpression selector = getSelector(expression);
return dispatchToCorrectTranslator(receiver, selector, context);
}
@@ -75,7 +81,7 @@ public final class QualifiedExpressionTranslator {
}
//TODO: never get there
if (selector instanceof KtSimpleNameExpression) {
return ReferenceTranslator.translateSimpleNameWithQualifier((KtSimpleNameExpression) selector, receiver, context);
return ReferenceTranslator.translateSimpleName((KtSimpleNameExpression) selector, context);
}
throw new AssertionError("Unexpected qualified expression: " + selector.getText());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,19 +18,16 @@ package org.jetbrains.kotlin.js.translate.reference;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.js.translate.context.Namer;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils;
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
import org.jetbrains.kotlin.psi.KtExpression;
import org.jetbrains.kotlin.psi.KtQualifiedExpression;
import org.jetbrains.kotlin.psi.KtSimpleNameExpression;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.setQualifier;
import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.getSelectorAsSimpleName;
import static org.jetbrains.kotlin.psi.KtPsiUtil.isBackingFieldReference;
@@ -40,45 +37,10 @@ public final class ReferenceTranslator {
}
@NotNull
public static JsExpression translateSimpleName(@NotNull KtSimpleNameExpression expression,
@NotNull TranslationContext context) {
public static JsExpression translateSimpleName(@NotNull KtSimpleNameExpression expression, @NotNull TranslationContext context) {
return getAccessTranslator(expression, context).translateAsGet();
}
@NotNull
public static JsExpression translateSimpleNameWithQualifier(
@NotNull KtSimpleNameExpression expression,
@Nullable JsExpression qualifier,
@NotNull TranslationContext context
) {
JsExpression simpleName = translateSimpleName(expression, context);
// Ignore qualifier if expression is EnumEntry or companion object reference and always use FQ name.
DeclarationDescriptor descriptor = BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), expression);
//TODO: should go away when objects inside classes are supported
if (descriptor != null && DescriptorUtils.isCompanionObject(descriptor) && !AnnotationsUtils.isNativeObject(descriptor)) {
return simpleName;
}
if (descriptor instanceof ClassDescriptor) {
ClassDescriptor entryClass = (ClassDescriptor) descriptor;
if (entryClass.getKind() == ClassKind.ENUM_ENTRY) {
if (!AnnotationsUtils.isNativeObject(entryClass)) {
DeclarationDescriptor enumClass = entryClass.getContainingDeclaration();
qualifier = Namer.getCompanionObjectAccessor(translateAsFQReference(enumClass, context));
}
}
else if (DescriptorUtils.isClassOrEnumClass(entryClass)) {
qualifier = null;
}
}
if (qualifier != null) { // TODO: hack for nested Object
setQualifier(simpleName, qualifier);
}
return simpleName;
}
@NotNull
public static JsExpression translateAsFQReference(@NotNull DeclarationDescriptor referencedDescriptor,
@NotNull TranslationContext context) {
@@ -95,27 +57,20 @@ public final class ReferenceTranslator {
return alias;
}
}
return context.getNameForDescriptor(descriptor).makeRef();
return context.getQualifiedReference(descriptor);
}
@NotNull
public static AccessTranslator getAccessTranslator(@NotNull KtSimpleNameExpression referenceExpression,
@NotNull TranslationContext context) {
return getAccessTranslator(referenceExpression, null, context);
}
@NotNull
public static AccessTranslator getAccessTranslator(@NotNull KtSimpleNameExpression referenceExpression,
@Nullable JsExpression receiver,
@NotNull TranslationContext context) {
if (isBackingFieldReference(getDescriptorForReferenceExpression(context.bindingContext(), referenceExpression))) {
return BackingFieldAccessTranslator.newInstance(referenceExpression, context);
}
if (canBePropertyAccess(referenceExpression, context)) {
return VariableAccessTranslator.newInstance(context, referenceExpression, receiver);
return VariableAccessTranslator.newInstance(context, referenceExpression, null);
}
if (CompanionObjectAccessTranslator.isCompanionObjectReference(referenceExpression, context)) {
return CompanionObjectAccessTranslator.newInstance(referenceExpression, context);
if (CompanionObjectIntrinsicAccessTranslator.isCompanionObjectReference(referenceExpression, context)) {
return CompanionObjectIntrinsicAccessTranslator.newInstance(referenceExpression, context);
}
return ReferenceAccessTranslator.newInstance(referenceExpression, context);
}
+13 -13
View File
@@ -905,10 +905,10 @@
return this.start.toString() + '..' + this.endInclusive;
}
}, {
object_initializer$: function () {
return { EMPTY : new this(1, 0) };
}
});
Companion: Kotlin.createObject(null, function () {
this.EMPTY = new Kotlin.NumberRange(1, 0);
})
});
@@ -983,11 +983,11 @@
toString: function () {
return this.start.toString() + '..' + this.endInclusive;
}
}, {
object_initializer$: function () {
return { EMPTY : new this(Kotlin.Long.ONE, Kotlin.Long.ZERO) };
}
});
}, {
Companion: Kotlin.createObject(null, function () {
this.EMPTY = new Kotlin.LongRange(Kotlin.Long.ONE, Kotlin.Long.ZERO);
})
});
@@ -1057,10 +1057,10 @@
return this.start.toString() + '..' + this.endInclusive;
}
}, {
object_initializer$: function () {
return { EMPTY : new this(Kotlin.toChar(1), Kotlin.toChar(0)) };
}
});
Companion: Kotlin.createObject(null, function () {
this.EMPTY = new Kotlin.CharRange(Kotlin.toChar(1), Kotlin.toChar(0));
})
});
/**
+26 -28
View File
@@ -141,16 +141,6 @@ var Kotlin = {};
return metadata;
}
/**
* @this {{object_initializer$: (function(): Object)}}
* @returns {Object}
*/
function class_object() {
var object = this.object_initializer$();
Object.defineProperty(this, "object", {value: object});
return object;
}
/**
* @param {(Array|Object|null)=} bases
* @param {(function(new: T, ?, ?, ?, ?, ?, ?, ?): T)|null=} constructor
@@ -186,7 +176,6 @@ var Kotlin = {};
constructor.$metadata$ = metadata;
constructor.prototype = prototypeObj;
Object.defineProperty(constructor, "object", {get: class_object, configurable: true});
return constructor;
};
@@ -204,14 +193,6 @@ var Kotlin = {};
}
}
Kotlin.createObjectNow = function (bases, constructor, functions, staticProperties) {
var noNameClass = Kotlin.createClassNow(bases, constructor, functions, staticProperties);
var obj = new noNameClass();
noNameClass.$metadata$.type = Kotlin.TYPE.OBJECT;
defineNestedTypes(obj, noNameClass.$metadata$.types);
return obj;
};
Kotlin.createTraitNow = function (bases, properties, staticProperties) {
var obj = function () {};
@@ -222,7 +203,6 @@ var Kotlin = {};
obj.prototype = {};
Object.defineProperties(obj.prototype, obj.$metadata$.properties);
copyProperties(obj.prototype, obj.$metadata$.functions);
Object.defineProperty(obj, "object", {get: class_object, configurable: true});
defineNestedTypes(obj, obj.$metadata$.types);
return obj;
@@ -248,6 +228,9 @@ var Kotlin = {};
function $o() {
var klass = Kotlin.createClassNow(getBases(basesFun), constructor, properties, staticProperties);
Object.defineProperty(this, $o.className, {value: klass});
if (staticProperties && staticProperties.object_initializer$) {
staticProperties.object_initializer$(klass);
}
return klass;
}
@@ -267,29 +250,28 @@ var Kotlin = {};
staticProperties = staticProperties || {};
// TODO use Object.assign
staticProperties.object_initializer$ = function () {
staticProperties.object_initializer$ = function (cls) {
var enumEntryList = enumEntries();
var i = 0;
var values = [];
for (var entryName in enumEntryList) {
if (enumEntryList.hasOwnProperty(entryName)) {
var entryObject = enumEntryList[entryName];
values[i] = entryObject;
entryObject.ordinal$ = i;
values.push(entryObject);
entryObject.ordinal$ = i++;
entryObject.name$ = entryName;
i++;
cls[entryName] = entryObject;
}
}
enumEntryList.values$ = values;
return enumEntryList;
};
staticProperties.values = function () {
return this.object.values$;
return this.values$;
};
staticProperties.valueOf_61zpoe$ = function (name) {
return this.object[name];
return this[name];
};
return Kotlin.createClass(basesFun, constructor, properties, staticProperties)
@@ -321,7 +303,23 @@ var Kotlin = {};
* @template T
*/
Kotlin.createObject = function (basesFun, constructor, functions, staticProperties) {
return Kotlin.createObjectNow(getBases(basesFun), constructor, functions, staticProperties);
constructor = constructor || function() {};
function $o() {
var klass = Kotlin.createClassNow(getBases(basesFun), null, functions, staticProperties);
var obj = new klass();
var metadata = klass.$metadata$;
metadata.type = Kotlin.TYPE.OBJECT;
Object.defineProperty(this, $o.className, {value: obj});
defineNestedTypes(obj, klass.$metadata$.types);
if (metadata.baseClass != null) {
constructor.baseInitializer = metadata.baseClass;
}
constructor.apply(obj);
return obj;
}
$o.type = Kotlin.TYPE.INIT_FUN;
return $o;
};
Kotlin.callGetter = function (thisObject, klass, propertyName) {