diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java index bfaf548efde..4ade2003d99 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java @@ -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); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java index 6cbfa456d11..cd31aa5e2e0 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java @@ -310,9 +310,7 @@ public final class StaticContext { Rule constructorOrCompanionObjectHasTheSameNameAsTheClass = new Rule() { @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; diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt index 447d82cd3e9..434f1d85081 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt @@ -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 } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java index 9b949d36d8b..a1e74198b05 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java @@ -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 { protected final List result; - protected final List staticResult; - protected final List enumEntryList = new SmartList(); + private final List staticResult; + private final List enumEntryList = new SmartList(); public DeclarationBodyVisitor(@NotNull List result, @NotNull List staticResult) { this.result = result; @@ -88,15 +84,11 @@ public class DeclarationBodyVisitor extends TranslatorVisitor { @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; } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/FileDeclaration.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/FileDeclaration.kt index 9d313936e61..eedd077a9cf 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/FileDeclaration.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/FileDeclaration.kt @@ -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 } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java index 6d0e68205fd..1b17b1a0d74 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java @@ -280,7 +280,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @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 diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerUtils.java index c3af93863a6..d855a13106a 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerUtils.java @@ -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 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); - } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerVisitor.java index 90312838d4c..55e47dad042 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerVisitor.java @@ -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 { 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; diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CompanionObjectAccessTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CompanionObjectIntrinsicAccessTranslator.java similarity index 67% rename from js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CompanionObjectAccessTranslator.java rename to js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CompanionObjectIntrinsicAccessTranslator.java index a9db236503c..970015dd3e4 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CompanionObjectAccessTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CompanionObjectIntrinsicAccessTranslator.java @@ -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 diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/QualifiedExpressionTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/QualifiedExpressionTranslator.java index d210d02de67..a4bbbd8c96c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/QualifiedExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/QualifiedExpressionTranslator.java @@ -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()); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/ReferenceTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/ReferenceTranslator.java index eee2f4a7e60..fb2208226c1 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/ReferenceTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/ReferenceTranslator.java @@ -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); } diff --git a/js/js.translator/testData/kotlin_lib.js b/js/js.translator/testData/kotlin_lib.js index b9989c39e65..eb01ad02b4b 100644 --- a/js/js.translator/testData/kotlin_lib.js +++ b/js/js.translator/testData/kotlin_lib.js @@ -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)); + }) + }); /** diff --git a/js/js.translator/testData/kotlin_lib_ecma5.js b/js/js.translator/testData/kotlin_lib_ecma5.js index 58a7913835d..57807ddc017 100644 --- a/js/js.translator/testData/kotlin_lib_ecma5.js +++ b/js/js.translator/testData/kotlin_lib_ecma5.js @@ -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) {