JS backend: Add class object support.
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
package org.jetbrains.k2js.test.semantics;
|
||||||
|
|
||||||
|
import org.jetbrains.k2js.test.SingleFileTranslationTest;
|
||||||
|
|
||||||
|
public final class ClassObjectTest extends SingleFileTranslationTest {
|
||||||
|
|
||||||
|
public ClassObjectTest() {
|
||||||
|
super("class_object/");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
checkFooBoxIsOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWithExtension() throws Exception {
|
||||||
|
checkFooBoxIsOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSetVar() throws Exception {
|
||||||
|
checkFooBoxIsOk();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,9 +20,11 @@ import com.google.dart.compiler.backend.js.ast.*;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.Named;
|
||||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.plugin.JetLanguage;
|
import org.jetbrains.jet.plugin.JetLanguage;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapuslates different types of constants and naming conventions.
|
* Encapuslates different types of constants and naming conventions.
|
||||||
@@ -46,6 +48,16 @@ public final class Namer {
|
|||||||
private static final String RECEIVER_PARAMETER_NAME = "$receiver";
|
private static final String RECEIVER_PARAMETER_NAME = "$receiver";
|
||||||
private static final String CLASSES_OBJECT_NAME = "classes";
|
private static final String CLASSES_OBJECT_NAME = "classes";
|
||||||
private static final String THROW_NPE_FUN_NAME = "throwNPE";
|
private static final String THROW_NPE_FUN_NAME = "throwNPE";
|
||||||
|
private static final String CLASS_OBJECT_GETTER = "object$";
|
||||||
|
private static final String CLASS_OBJECT_INITIALIZER = "object_initializer$";
|
||||||
|
|
||||||
|
private static final Named CLASS_OBJECT_INITIALIZER_NAMED = new Named() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Name getName() {
|
||||||
|
return Name.identifier(CLASS_OBJECT_INITIALIZER);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String getReceiverParameterName() {
|
public static String getReceiverParameterName() {
|
||||||
@@ -101,6 +113,14 @@ public final class Namer {
|
|||||||
return getNameWithPrefix(propertyName, SETTER_PREFIX);
|
return getNameWithPrefix(propertyName, SETTER_PREFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JsExpression getClassObjectAccessor(@NotNull JsExpression referenceToClass) {
|
||||||
|
return new JsInvocation(new JsNameRef(CLASS_OBJECT_GETTER, referenceToClass));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Named getNamedForClassObjectInitializer() {
|
||||||
|
return CLASS_OBJECT_INITIALIZER_NAMED;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String getNameWithPrefix(@NotNull String name, @NotNull String prefix) {
|
private static String getNameWithPrefix(@NotNull String name, @NotNull String prefix) {
|
||||||
return prefix + name;
|
return prefix + name;
|
||||||
@@ -206,6 +226,8 @@ public final class Namer {
|
|||||||
return new JsInvocation(traitCreationMethodReference());
|
return new JsInvocation(traitCreationMethodReference());
|
||||||
case OBJECT:
|
case OBJECT:
|
||||||
return new JsInvocation(objectCreationMethodReference());
|
return new JsInvocation(objectCreationMethodReference());
|
||||||
|
case CLASS_OBJECT:
|
||||||
|
return new JsInvocation(objectCreationMethodReference());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new JsInvocation(classCreationMethodReference());
|
return new JsInvocation(classCreationMethodReference());
|
||||||
|
|||||||
@@ -133,15 +133,13 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
private void addClassOwnDeclarations(@NotNull List<JsExpression> invocationArguments, @NotNull TranslationContext declarationContext) {
|
private void addClassOwnDeclarations(@NotNull List<JsExpression> invocationArguments, @NotNull TranslationContext declarationContext) {
|
||||||
final List<JsPropertyInitializer> properties = new SmartList<JsPropertyInitializer>();
|
final List<JsPropertyInitializer> properties = new SmartList<JsPropertyInitializer>();
|
||||||
|
|
||||||
final List<JsPropertyInitializer> staticProperties;
|
final List<JsPropertyInitializer> staticProperties = new SmartList<JsPropertyInitializer>();
|
||||||
boolean isTopLevelDeclaration = context() == declarationContext;
|
boolean isTopLevelDeclaration = context() == declarationContext;
|
||||||
final JsNameRef qualifiedReference;
|
final JsNameRef qualifiedReference;
|
||||||
if (!isTopLevelDeclaration) {
|
if (!isTopLevelDeclaration) {
|
||||||
staticProperties = null;
|
|
||||||
qualifiedReference = null;
|
qualifiedReference = null;
|
||||||
}
|
}
|
||||||
else if (descriptor.getKind().isObject()) {
|
else if (descriptor.getKind().isObject()) {
|
||||||
staticProperties = null;
|
|
||||||
qualifiedReference = null;
|
qualifiedReference = null;
|
||||||
declarationContext.literalFunctionTranslator().setDefinitionPlace(
|
declarationContext.literalFunctionTranslator().setDefinitionPlace(
|
||||||
new NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>>() {
|
new NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>>() {
|
||||||
@@ -154,7 +152,6 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qualifiedReference = getQualifiedReference(declarationContext, descriptor);
|
qualifiedReference = getQualifiedReference(declarationContext, descriptor);
|
||||||
staticProperties = new SmartList<JsPropertyInitializer>();
|
|
||||||
declarationContext.literalFunctionTranslator().setDefinitionPlace(
|
declarationContext.literalFunctionTranslator().setDefinitionPlace(
|
||||||
new NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>>() {
|
new NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -176,13 +173,13 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
translatePropertiesAsConstructorParameters(declarationContext, properties);
|
translatePropertiesAsConstructorParameters(declarationContext, properties);
|
||||||
new DeclarationBodyVisitor(properties).traverseContainer(classDeclaration, declarationContext);
|
new DeclarationBodyVisitor(properties, staticProperties).traverseContainer(classDeclaration, declarationContext);
|
||||||
|
|
||||||
if (isTopLevelDeclaration) {
|
if (isTopLevelDeclaration) {
|
||||||
declarationContext.literalFunctionTranslator().setDefinitionPlace(null);
|
declarationContext.literalFunctionTranslator().setDefinitionPlace(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasStaticProperties = staticProperties != null && !staticProperties.isEmpty();
|
boolean hasStaticProperties = !staticProperties.isEmpty();
|
||||||
if (!properties.isEmpty() || hasStaticProperties) {
|
if (!properties.isEmpty() || hasStaticProperties) {
|
||||||
if (properties.isEmpty()) {
|
if (properties.isEmpty()) {
|
||||||
invocationArguments.add(JsLiteral.NULL);
|
invocationArguments.add(JsLiteral.NULL);
|
||||||
|
|||||||
+24
-9
@@ -16,14 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.k2js.translate.declaration;
|
package org.jetbrains.k2js.translate.declaration;
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
|
|
||||||
import com.intellij.util.SmartList;
|
import com.intellij.util.SmartList;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.Modality;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.k2js.translate.context.Namer;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
||||||
@@ -32,18 +30,20 @@ import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
import static org.jetbrains.k2js.translate.initializer.InitializerUtils.createPropertyInitializer;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForObjectDeclaration;
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
||||||
|
|
||||||
public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
||||||
protected final List<JsPropertyInitializer> result;
|
protected final List<JsPropertyInitializer> result;
|
||||||
|
protected final List<JsPropertyInitializer> staticResult;
|
||||||
|
|
||||||
public DeclarationBodyVisitor() {
|
public DeclarationBodyVisitor() {
|
||||||
this(new SmartList<JsPropertyInitializer>());
|
this(new SmartList<JsPropertyInitializer>(), new SmartList<JsPropertyInitializer>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeclarationBodyVisitor(List<JsPropertyInitializer> result) {
|
public DeclarationBodyVisitor(@NotNull List<JsPropertyInitializer> result, @NotNull List<JsPropertyInitializer> staticResult) {
|
||||||
this.result = result;
|
this.result = result;
|
||||||
|
this.staticResult = staticResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -56,6 +56,21 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitClassObject(
|
||||||
|
JetClassObject classObject, TranslationContext context
|
||||||
|
) {
|
||||||
|
JetObjectDeclaration declaration = classObject.getObjectDeclaration();
|
||||||
|
assert declaration != null : "Declaration for class object must be not null";
|
||||||
|
ClassDescriptor descriptor = getClassDescriptor(context.bindingContext(), declaration);
|
||||||
|
JsExpression value = ClassTranslator.generateClassCreation(declaration, descriptor, context);
|
||||||
|
|
||||||
|
JsFunction fun = new JsFunction(context.getScopeForDescriptor(descriptor.getContainingDeclaration()));
|
||||||
|
fun.setBody(new JsBlock(new JsReturn(value)));
|
||||||
|
staticResult.add(createPropertyInitializer(Namer.getNamedForClassObjectInitializer(), fun, context));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitNamedFunction(@NotNull JetNamedFunction expression, @NotNull TranslationContext context) {
|
public Void visitNamedFunction(@NotNull JetNamedFunction expression, @NotNull TranslationContext context) {
|
||||||
FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression);
|
FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression);
|
||||||
|
|||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.k2js.translate.reference;
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||||
|
import org.jetbrains.k2js.translate.context.Namer;
|
||||||
|
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||||
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
|
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.k2js.translate.reference.ReferenceTranslator.translateAsFQReference;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
|
||||||
|
|
||||||
|
public class ClassObjectAccessTranslator extends AbstractTranslator implements CachedAccessTranslator {
|
||||||
|
@NotNull
|
||||||
|
/*package*/ static ClassObjectAccessTranslator newInstance(@NotNull JetSimpleNameExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
DeclarationDescriptor referenceDescriptor = getDescriptorForReferenceExpression(context.bindingContext(), expression);
|
||||||
|
assert referenceDescriptor != null : "JetSimpleName expression must reference a descriptor " + expression.getText();
|
||||||
|
return new ClassObjectAccessTranslator(referenceDescriptor, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ static boolean isClassObjectReference(@NotNull JetReferenceExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
DeclarationDescriptor descriptor = getDescriptorForReferenceExpression(context.bindingContext(), expression);
|
||||||
|
return descriptor instanceof ClassDescriptor && !AnnotationsUtils.isNativeObject(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final JsExpression referenceToClassObject;
|
||||||
|
|
||||||
|
private ClassObjectAccessTranslator(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) {
|
||||||
|
super(context);
|
||||||
|
this.referenceToClassObject = Namer.getClassObjectAccessor(translateAsFQReference(descriptor, context()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public JsExpression translateAsGet() {
|
||||||
|
return referenceToClassObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
|
||||||
|
throw new IllegalStateException("Class object can't set");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CachedAccessTranslator getCached() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<TemporaryVariable> declaredTemporaries() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -78,6 +78,9 @@ public final class ReferenceTranslator {
|
|||||||
if (PropertyAccessTranslator.canBePropertyAccess(referenceExpression, context)) {
|
if (PropertyAccessTranslator.canBePropertyAccess(referenceExpression, context)) {
|
||||||
return PropertyAccessTranslator.newInstance(referenceExpression, receiver, CallType.NORMAL, context);
|
return PropertyAccessTranslator.newInstance(referenceExpression, receiver, CallType.NORMAL, context);
|
||||||
}
|
}
|
||||||
|
if (ClassObjectAccessTranslator.isClassObjectReference(referenceExpression, context)) {
|
||||||
|
return ClassObjectAccessTranslator.newInstance(referenceExpression, context);
|
||||||
|
}
|
||||||
return ReferenceAccessTranslator.newInstance(referenceExpression, context);
|
return ReferenceAccessTranslator.newInstance(referenceExpression, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
class A {
|
||||||
|
var a = 3
|
||||||
|
class object {
|
||||||
|
var a = -2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
A.a = 2
|
||||||
|
if (A.a != 2) return "A.a != 2"
|
||||||
|
|
||||||
|
val a = A
|
||||||
|
a.a = 3
|
||||||
|
if (a.a != 3) return "a = A; a.a = 3; a != 3"
|
||||||
|
|
||||||
|
if (A().a != 3) return "A().a != 3"
|
||||||
|
|
||||||
|
val x = A()
|
||||||
|
x.a = 4
|
||||||
|
if (x.a != 4) return "x = A(); x.a = 4; x.a != 4"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val a = 3
|
||||||
|
class object {
|
||||||
|
val a = 2
|
||||||
|
val b = 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
if (A.a != 2) return "A.a != 2"
|
||||||
|
if (A.b != 5) return "A.b != 5"
|
||||||
|
|
||||||
|
val b = A
|
||||||
|
if (b.a != 2) return "b = A; b != 2"
|
||||||
|
|
||||||
|
if (A().a != 3) return "A().a != 3"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
val a = 3
|
||||||
|
fun foo(): Int {
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
class object: A() {
|
||||||
|
val c = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
class object: A() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
if (A.a != 3) return "A.a != 3"
|
||||||
|
if (A.foo() != 5) return "A.foo() != 5"
|
||||||
|
|
||||||
|
val a = A
|
||||||
|
if (a.c != 3) return "a = A; a.c != 3"
|
||||||
|
|
||||||
|
if (A().a != 3) return "A().a != 3"
|
||||||
|
|
||||||
|
if (B.a != 3) return "B.a != 3"
|
||||||
|
val b = B
|
||||||
|
if (b.foo() != 5) return "b = B; b.foo() != 5"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -111,6 +111,7 @@ var Kotlin = {};
|
|||||||
klass.addMethods = addMethods;
|
klass.addMethods = addMethods;
|
||||||
klass.superclass = parent || null;
|
klass.superclass = parent || null;
|
||||||
klass.subclasses = [];
|
klass.subclasses = [];
|
||||||
|
klass.object$ = object$;
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
if (typeof (parent) == "function") {
|
if (typeof (parent) == "function") {
|
||||||
@@ -160,6 +161,14 @@ var Kotlin = {};
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function object$() {
|
||||||
|
if (typeof this.$object$ === "undefined") {
|
||||||
|
this.$object$ = this.object_initializer$();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.$object$;
|
||||||
|
}
|
||||||
|
|
||||||
return create;
|
return create;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,14 @@ var Kotlin = Object.create(null);
|
|||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function class_object$() {
|
||||||
|
if (typeof this.$object$ === "undefined") {
|
||||||
|
this.$object$ = this.object_initializer$();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.$object$;
|
||||||
|
}
|
||||||
|
|
||||||
function createClass(bases, initializer, properties, staticProperties, isClass) {
|
function createClass(bases, initializer, properties, staticProperties, isClass) {
|
||||||
var proto;
|
var proto;
|
||||||
var baseInitializer;
|
var baseInitializer;
|
||||||
@@ -111,6 +119,9 @@ var Kotlin = Object.create(null);
|
|||||||
}
|
}
|
||||||
|
|
||||||
var constructor = createConstructor();
|
var constructor = createConstructor();
|
||||||
|
Object.defineProperty(constructor, "object$", {value: class_object$});
|
||||||
|
Object.defineProperty(constructor, "$object$", {value: undefined, writable: true});
|
||||||
|
|
||||||
Object.defineProperty(constructor, "proto", {value: proto});
|
Object.defineProperty(constructor, "proto", {value: proto});
|
||||||
Object.defineProperty(constructor, "properties", {value: properties || null});
|
Object.defineProperty(constructor, "properties", {value: properties || null});
|
||||||
if (isClass) {
|
if (isClass) {
|
||||||
@@ -124,7 +135,7 @@ var Kotlin = Object.create(null);
|
|||||||
Object.defineProperties(constructor, staticProperties);
|
Object.defineProperties(constructor, staticProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.freeze(constructor);
|
Object.seal(constructor);
|
||||||
return constructor;
|
return constructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user