KT-11030 Implements closures in classes. Represent local object literals as classes
This commit is contained in:
@@ -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.
|
||||
@@ -78,7 +78,7 @@ public class DescriptorUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isDescriptorWithLocalVisibility(DeclarationDescriptor current) {
|
||||
public static boolean isDescriptorWithLocalVisibility(DeclarationDescriptor current) {
|
||||
return current instanceof DeclarationDescriptorWithVisibility &&
|
||||
((DeclarationDescriptorWithVisibility) current).getVisibility() == Visibilities.LOCAL;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -41,7 +41,7 @@ public final class ObjectTest extends SingleFileTranslationTest {
|
||||
}
|
||||
|
||||
public void testObjectInObject() throws Exception {
|
||||
fooBoxTest();
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testObjectInheritingFromATrait() throws Exception {
|
||||
|
||||
+11
-6
@@ -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.
|
||||
@@ -17,9 +17,7 @@
|
||||
package org.jetbrains.kotlin.js.translate.callTranslator
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.js.PredefinedAnnotation
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
@@ -212,11 +210,18 @@ object ConstructorCallCase : FunctionCallCase() {
|
||||
val arguments = argumentsInfo.getArguments()
|
||||
|
||||
val constructorDescriptor = callableDescriptor as ConstructorDescriptor
|
||||
val classDescriptor = constructorDescriptor.containingDeclaration
|
||||
val closure = context.getLocalClassClosure(classDescriptor)
|
||||
var closureArgs = emptyList<JsExpression>()
|
||||
if (closure != null) {
|
||||
closureArgs = closure.asSequence().map { context.getParameterNameRefForInvocation(it) }.toList()
|
||||
}
|
||||
|
||||
if (constructorDescriptor.isPrimary || AnnotationsUtils.isNativeObject(constructorDescriptor)) {
|
||||
return JsNew(functionRef, arguments)
|
||||
return JsNew(functionRef, closureArgs + arguments)
|
||||
}
|
||||
else {
|
||||
return JsInvocation(functionRef, arguments)
|
||||
return JsInvocation(functionRef, closureArgs + arguments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -438,9 +438,7 @@ public final class Namer {
|
||||
return objectCreationMethodReference();
|
||||
case ANNOTATION_CLASS:
|
||||
case CLASS:
|
||||
return DescriptorUtils.isAnonymousObject(descriptor)
|
||||
? objectCreationMethodReference()
|
||||
: classCreationMethodReference();
|
||||
return classCreationMethodReference();
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unsupported class kind: " + descriptor);
|
||||
}
|
||||
|
||||
@@ -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,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.context;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.HasMetadata;
|
||||
@@ -98,6 +99,9 @@ public final class StaticContext {
|
||||
@NotNull
|
||||
private final Map<JsScope, JsFunction> scopeToFunction = Maps.newHashMap();
|
||||
|
||||
@NotNull
|
||||
private final Map<ClassDescriptor, List<DeclarationDescriptor>> localClassesClosure = Maps.newHashMap();
|
||||
|
||||
@NotNull
|
||||
private final Config config;
|
||||
|
||||
@@ -262,13 +266,17 @@ public final class StaticContext {
|
||||
@Nullable
|
||||
@Override
|
||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (!DescriptorUtils.isLocal(descriptor) || !DescriptorUtils.isClass(descriptor)) return null;
|
||||
if (!DescriptorUtils.isDescriptorWithLocalVisibility(descriptor) ||
|
||||
!DescriptorUtils.isClass(descriptor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> parts = new ArrayList<String>();
|
||||
do {
|
||||
parts.add(descriptor.getName().asString());
|
||||
parts.add(descriptor.getName().isSpecial() ? "f" : descriptor.getName().getIdentifier());
|
||||
descriptor = descriptor.getContainingDeclaration();
|
||||
} while (!(descriptor instanceof ClassOrPackageFragmentDescriptor));
|
||||
} while (descriptor != null && !(descriptor instanceof ClassOrPackageFragmentDescriptor));
|
||||
assert descriptor != null;
|
||||
|
||||
Collections.reverse(parts);
|
||||
StringBuilder suggestedName = new StringBuilder(parts.get(0));
|
||||
@@ -580,10 +588,7 @@ public final class StaticContext {
|
||||
if (!(descriptor instanceof ClassDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
if (container != null && !(container instanceof ClassDescriptor)) {
|
||||
container = DescriptorUtils.getContainingClass(container);
|
||||
}
|
||||
DeclarationDescriptor container = getEnclosingNonSingleton(descriptor.getContainingDeclaration());
|
||||
if (container == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -608,7 +613,9 @@ public final class StaticContext {
|
||||
@Nullable
|
||||
@Override
|
||||
public JsExpression apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (!DescriptorUtils.isLocal(descriptor) || !(descriptor instanceof ClassDescriptor)) return null;
|
||||
if (!DescriptorUtils.isDescriptorWithLocalVisibility(descriptor) || !(descriptor instanceof ClassDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
descriptor = descriptor.getContainingDeclaration();
|
||||
while (descriptor != null && !(descriptor instanceof ClassOrPackageFragmentDescriptor)) {
|
||||
@@ -631,6 +638,14 @@ public final class StaticContext {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ClassDescriptor getEnclosingNonSingleton(@NotNull DeclarationDescriptor descriptor) {
|
||||
while (descriptor != null && (!(descriptor instanceof ClassDescriptor) || DescriptorUtils.isObject(descriptor))) {
|
||||
descriptor = descriptor.getContainingDeclaration();
|
||||
}
|
||||
return (ClassDescriptor) descriptor;
|
||||
}
|
||||
|
||||
private static JsExpression applySideEffects(JsExpression expression, DeclarationDescriptor descriptor) {
|
||||
if (expression instanceof HasMetadata) {
|
||||
if (descriptor instanceof FunctionDescriptor ||
|
||||
@@ -658,4 +673,14 @@ public final class StaticContext {
|
||||
addRule(propertiesInClassHaveNoQualifiers);
|
||||
}
|
||||
}
|
||||
|
||||
public void putLocalClassClosure(@NotNull ClassDescriptor localClass, @NotNull List<DeclarationDescriptor> closure) {
|
||||
localClassesClosure.put(localClass, Lists.newArrayList(closure));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<DeclarationDescriptor> getLocalClassClosure(@NotNull ClassDescriptor localClass) {
|
||||
List<DeclarationDescriptor> result = localClassesClosure.get(localClass);
|
||||
return result != null ? Lists.newArrayList(result) : null;
|
||||
}
|
||||
}
|
||||
|
||||
+48
-4
@@ -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.
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.js.translate.context.UsageTrackerKt.getNameForCapturedDescriptor;
|
||||
@@ -135,6 +136,13 @@ public class TranslationContext {
|
||||
this.definitionPlace, descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TranslationContext innerWithUsageTracker(@NotNull JsScope scope, @NotNull MemberDescriptor descriptor) {
|
||||
UsageTracker usageTracker = new UsageTracker(this.usageTracker, descriptor, scope);
|
||||
return new TranslationContext(this, staticContext, dynamicContext, aliasingContext.inner(), usageTracker, definitionPlace,
|
||||
descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TranslationContext innerBlock(@NotNull JsBlock block) {
|
||||
return new TranslationContext(this, staticContext, dynamicContext.innerBlock(block), aliasingContext, usageTracker, null,
|
||||
@@ -154,8 +162,7 @@ public class TranslationContext {
|
||||
|
||||
@NotNull
|
||||
private TranslationContext innerWithAliasingContext(AliasingContext aliasingContext) {
|
||||
return new TranslationContext(this, this.staticContext, this.dynamicContext, aliasingContext, this.usageTracker, null,
|
||||
this.declarationDescriptor);
|
||||
return new TranslationContext(this, staticContext, dynamicContext, aliasingContext, usageTracker, null, declarationDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -414,12 +421,27 @@ public class TranslationContext {
|
||||
usageTracker.used(descriptor);
|
||||
|
||||
JsName name = getNameForCapturedDescriptor(usageTracker, descriptor);
|
||||
if (name != null) return name.makeRef();
|
||||
if (name != null) {
|
||||
JsNameRef result = name.makeRef();
|
||||
if (shouldCaptureViaThis()) {
|
||||
result.setQualifier(JsLiteral.THIS);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean shouldCaptureViaThis() {
|
||||
if (declarationDescriptor == null) return false;
|
||||
|
||||
if (DescriptorUtils.isDescriptorWithLocalVisibility(declarationDescriptor)) {
|
||||
return !(declarationDescriptor instanceof FunctionDescriptor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ClassDescriptor getNearestClass(@NotNull DeclarationDescriptor declaration) {
|
||||
DeclarationDescriptor decl = declaration;
|
||||
@@ -438,4 +460,26 @@ public class TranslationContext {
|
||||
public DeclarationDescriptor getDeclarationDescriptor() {
|
||||
return declarationDescriptor;
|
||||
}
|
||||
|
||||
public void putLocalClassClosure(@NotNull ClassDescriptor localClass, @NotNull List<DeclarationDescriptor> closure) {
|
||||
staticContext.putLocalClassClosure(localClass, closure);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<DeclarationDescriptor> getLocalClassClosure(@NotNull ClassDescriptor localClass) {
|
||||
return staticContext.getLocalClassClosure(localClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression getParameterNameRefForInvocation(@NotNull DeclarationDescriptor descriptor) {
|
||||
JsExpression alias = getAliasForDescriptor(descriptor);
|
||||
if (alias != null) return alias;
|
||||
if (descriptor instanceof ReceiverParameterDescriptor) return JsLiteral.THIS;
|
||||
return getNameForDescriptor(descriptor).makeRef();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsScope getRootScope() {
|
||||
return staticContext.getRootScope();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,7 +20,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isAncestor
|
||||
import com.google.dart.compiler.backend.js.ast.JsName
|
||||
import org.jetbrains.kotlin.js.translate.utils.ManglingUtils.getSuggestedName
|
||||
import com.google.dart.compiler.backend.js.ast.JsFunctionScope
|
||||
import com.google.dart.compiler.backend.js.ast.JsScope
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
private val CAPTURED_RECEIVER_NAME_PREFIX : String = "this$"
|
||||
@@ -28,7 +28,7 @@ private val CAPTURED_RECEIVER_NAME_PREFIX : String = "this$"
|
||||
class UsageTracker(
|
||||
private val parent: UsageTracker?,
|
||||
val containingDescriptor: MemberDescriptor,
|
||||
private val scope: JsFunctionScope
|
||||
private val scope: JsScope
|
||||
) {
|
||||
|
||||
private val captured = linkedMapOf<DeclarationDescriptor, JsName>()
|
||||
|
||||
+58
-29
@@ -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.
|
||||
@@ -28,8 +28,8 @@ import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
||||
import org.jetbrains.kotlin.js.translate.context.DefinitionPlace
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.context.*
|
||||
import org.jetbrains.kotlin.js.translate.expression.FunctionTranslator
|
||||
import org.jetbrains.kotlin.js.translate.expression.withCapturedParameters
|
||||
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
|
||||
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.*
|
||||
import org.jetbrains.kotlin.types.CommonSupertypes.topologicallySortSuperclassesAndRecordAllInstances
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -64,9 +65,10 @@ class ClassTranslator private constructor(
|
||||
private val descriptor = getClassDescriptor(context.bindingContext(), classDeclaration)
|
||||
|
||||
private fun translateObjectLiteralExpression(): JsExpression {
|
||||
getContainingClass(descriptor) ?: return translate(context())
|
||||
|
||||
return translateObjectInsideClass(context())
|
||||
return if (descriptor.containingDeclaration is ClassDescriptor && descriptor.kind == ClassKind.OBJECT)
|
||||
translateObjectInsideClass(context())
|
||||
else
|
||||
translate(context())
|
||||
}
|
||||
|
||||
private fun translate(declarationContext: TranslationContext = context()): JsInvocation {
|
||||
@@ -82,28 +84,19 @@ class ClassTranslator private constructor(
|
||||
val properties = SmartList<JsPropertyInitializer>()
|
||||
val staticProperties = SmartList<JsPropertyInitializer>()
|
||||
|
||||
val isTopLevelDeclaration = context() == context
|
||||
|
||||
var qualifiedReference: JsNameRef? = null
|
||||
if (isTopLevelDeclaration) {
|
||||
var definitionPlace: DefinitionPlace? = null
|
||||
|
||||
if (!descriptor.kind.isSingleton && !isAnonymousObject(descriptor)) {
|
||||
qualifiedReference = context.getQualifiedReference(descriptor)
|
||||
val scope = context().getScopeForDescriptor(descriptor)
|
||||
definitionPlace = DefinitionPlace(scope as JsObjectScope, qualifiedReference, staticProperties)
|
||||
}
|
||||
|
||||
context = context.newDeclaration(descriptor, definitionPlace)
|
||||
}
|
||||
val qualifiedReference = context.getQualifiedReference(descriptor)
|
||||
val scope = context().getScopeForDescriptor(descriptor)
|
||||
val definitionPlace = DefinitionPlace(scope as JsObjectScope, qualifiedReference, staticProperties)
|
||||
|
||||
context = context.newDeclaration(descriptor, definitionPlace)
|
||||
context = fixContextForCompanionObjectAccessing(context)
|
||||
|
||||
invocationArguments.add(getSuperclassReferences(context))
|
||||
val delegationTranslator = DelegationTranslator(classDeclaration, context())
|
||||
var initializer: JsFunction? = null
|
||||
if (!isTrait()) {
|
||||
val initializer = ClassInitializerTranslator(classDeclaration, context).generateInitializeMethod(delegationTranslator)
|
||||
invocationArguments.add(if (initializer.body.statements.isEmpty()) JsLiteral.NULL else initializer)
|
||||
initializer = ClassInitializerTranslator(classDeclaration, context).generateInitializeMethod(delegationTranslator)
|
||||
invocationArguments.add(initializer)
|
||||
}
|
||||
|
||||
translatePropertiesAsConstructorParameters(context, properties)
|
||||
@@ -129,10 +122,8 @@ class ClassTranslator private constructor(
|
||||
invocationArguments.add(JsLiteral.NULL)
|
||||
}
|
||||
else {
|
||||
if (qualifiedReference != null) {
|
||||
// about "prototype" - see http://code.google.com/p/jsdoc-toolkit/wiki/TagLends
|
||||
invocationArguments.add(JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, JsNameRef("prototype", qualifiedReference)))
|
||||
}
|
||||
// about "prototype" - see http://code.google.com/p/jsdoc-toolkit/wiki/TagLends
|
||||
invocationArguments.add(JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, JsNameRef("prototype", qualifiedReference)))
|
||||
invocationArguments.add(JsObjectLiteral(properties, true))
|
||||
}
|
||||
}
|
||||
@@ -141,6 +132,22 @@ class ClassTranslator private constructor(
|
||||
invocationArguments.add(JsObjectLiteral(staticProperties, true))
|
||||
}
|
||||
|
||||
val tracker = context.usageTracker()
|
||||
if (tracker != null && initializer != null && tracker.hasCapturedExceptContaining()) {
|
||||
val captured = tracker.capturedDescriptorToJsName
|
||||
val keysAsList = captured.keys.toList()
|
||||
for ((i, key) in keysAsList.withIndex()) {
|
||||
val name = captured[key]!!
|
||||
initializer.parameters.add(i, JsParameter(name))
|
||||
initializer.body.statements.add(i, JsAstUtils.defineSimpleProperty(name.ident, name.makeRef()))
|
||||
}
|
||||
context.putLocalClassClosure(descriptor, keysAsList)
|
||||
}
|
||||
|
||||
if (initializer != null && initializer.body.isEmpty) {
|
||||
invocationArguments.replaceAll { if (it == initializer) JsLiteral.NULL else it }
|
||||
}
|
||||
|
||||
return invocationArguments
|
||||
}
|
||||
|
||||
@@ -214,12 +221,30 @@ class ClassTranslator private constructor(
|
||||
}
|
||||
|
||||
private fun translateObjectInsideClass(outerClassContext: TranslationContext): JsExpression {
|
||||
val function = JsFunction(outerClassContext.scope(), JsBlock(), "initializer for " + descriptor.name.asString())
|
||||
val funContext = outerClassContext.newFunctionBodyWithUsageTracker(function, descriptor)
|
||||
var outerDeclaration = descriptor.containingDeclaration.containingDeclaration
|
||||
if (outerDeclaration != null && outerDeclaration !is ClassDescriptor) {
|
||||
outerDeclaration = DescriptorUtils.getContainingClass(outerDeclaration)
|
||||
}
|
||||
val scope = if (outerDeclaration != null)
|
||||
outerClassContext.getScopeForDescriptor(outerDeclaration)
|
||||
else
|
||||
outerClassContext.rootScope
|
||||
|
||||
function.body.statements.add(JsReturn(translate(funContext)))
|
||||
val classContext = outerClassContext.innerWithUsageTracker(scope, descriptor)
|
||||
|
||||
return function.withCapturedParameters(funContext, outerClassContext, descriptor)
|
||||
var declarationArgs = getClassCreateInvocationArguments(classContext)
|
||||
val jsClass = JsInvocation(context().namer().classCreationMethodReference(), declarationArgs)
|
||||
|
||||
val name = outerClassContext.getNameForDescriptor(descriptor)
|
||||
val constructor = outerClassContext.define(name, jsClass)
|
||||
|
||||
val closure = outerClassContext.getLocalClassClosure(descriptor)
|
||||
var closureArgs = emptyList<JsExpression>()
|
||||
if (closure != null) {
|
||||
closureArgs = closure.map { context().getParameterNameRefForInvocation(it) }.toList()
|
||||
}
|
||||
|
||||
return JsNew(constructor, closureArgs)
|
||||
}
|
||||
|
||||
private fun generatedBridgeMethods(properties: MutableList<JsPropertyInitializer>) {
|
||||
@@ -289,6 +314,10 @@ class ClassTranslator private constructor(
|
||||
}
|
||||
|
||||
@JvmStatic fun generateObjectLiteral(objectDeclaration: KtObjectDeclaration, context: TranslationContext): JsExpression {
|
||||
return ClassTranslator(objectDeclaration, context).translateObjectInsideClass(context)
|
||||
}
|
||||
|
||||
@JvmStatic fun generateObjectDeclaration(objectDeclaration: KtObjectDeclaration, context: TranslationContext): JsExpression {
|
||||
return ClassTranslator(objectDeclaration, context).translateObjectLiteralExpression()
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -518,8 +518,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsNode visitObjectLiteralExpression(@NotNull KtObjectLiteralExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
public JsNode visitObjectLiteralExpression(@NotNull KtObjectLiteralExpression expression, @NotNull TranslationContext context) {
|
||||
return ClassTranslator.generateObjectLiteral(expression.getObjectDeclaration(), context);
|
||||
}
|
||||
|
||||
@@ -569,8 +568,12 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
|
||||
@Override
|
||||
public JsNode visitClass(@NotNull KtClass klass, TranslationContext context) {
|
||||
JsInvocation jsClass = ClassTranslator.generateClassCreation(klass, context);
|
||||
DeclarationDescriptor descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), klass);
|
||||
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), klass);
|
||||
JsObjectScope scope = new JsObjectScope(context.scope(), descriptor.toString(), "");
|
||||
TranslationContext classContext = context.innerWithUsageTracker(scope, descriptor);
|
||||
|
||||
JsInvocation jsClass = ClassTranslator.generateClassCreation(klass, classContext);
|
||||
|
||||
JsName name = context.getNameForDescriptor(descriptor);
|
||||
return context.define(name, jsClass);
|
||||
}
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -64,7 +64,7 @@ public final class InitializerUtils {
|
||||
@NotNull List<JsStatement> initializers,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
JsExpression value = ClassTranslator.generateObjectLiteral(declaration, 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());
|
||||
|
||||
+12
-3
@@ -22,7 +22,16 @@ class C {
|
||||
}
|
||||
}
|
||||
|
||||
fun box() = A.query.status == "complete" && B.query.status == "completed"
|
||||
// todo fix after KT-3868 will be fixed
|
||||
// && C.query.status == "completed"
|
||||
fun box(): String {
|
||||
var result = A.query.status
|
||||
if (result != "complete") return "fail1: $result"
|
||||
|
||||
result = B.query.status
|
||||
if (result != "completed") return "fail2: $result"
|
||||
|
||||
result = C.query.status
|
||||
if (result != "completed") return "fail3: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user