diff --git a/jslib/src/core/javautil.kt b/jslib/src/core/javautil.kt index f645ccd8da8..9bc5b5cab55 100644 --- a/jslib/src/core/javautil.kt +++ b/jslib/src/core/javautil.kt @@ -145,3 +145,7 @@ public class StringBuilder() { public fun toString() : String } +library("splitString") +public fun String.split(regex : String) : Array { +} + diff --git a/translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java b/translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java index 236aa255f63..432a09d9483 100644 --- a/translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java +++ b/translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java @@ -1,18 +1,14 @@ package org.jetbrains.k2js.translate.context; import com.google.dart.compiler.backend.js.ast.*; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; -import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetElement; -import org.jetbrains.jet.lang.psi.JetNamedFunction; -import org.jetbrains.jet.lang.psi.JetPropertyAccessor; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.k2js.translate.intrinsic.Intrinsics; -import org.jetbrains.k2js.translate.utils.BindingUtils; + +import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForElement; /** * @author Pavel Talanov @@ -53,34 +49,14 @@ public final class TranslationContext { return new TranslationContext(staticContext, dynamicContext.innerBlock(block)); } - @NotNull - public TranslationContext newNamespace(@NotNull NamespaceDescriptor namespace) { - return newDeclaration(namespace); - } - @NotNull public TranslationContext newDeclaration(@NotNull DeclarationDescriptor descriptor) { return contextWithScope(getScopeForDescriptor(descriptor)); } @NotNull - public TranslationContext newClass(@NotNull JetClass declaration) { - return newDeclaration(BindingUtils.getClassDescriptor(staticContext.getBindingContext(), declaration)); - } - - @NotNull - public TranslationContext newPropertyAccess(@NotNull JetPropertyAccessor declaration) { - return newDeclaration(BindingUtils.getPropertyAccessorDescriptor(staticContext.getBindingContext(), declaration)); - } - - @NotNull - public TranslationContext newPropertyAccess(@NotNull PropertyAccessorDescriptor descriptor) { - return newDeclaration(descriptor); - } - - @NotNull - public TranslationContext newFunctionDeclaration(@NotNull JetNamedFunction declaration) { - return newDeclaration(BindingUtils.getFunctionDescriptor(staticContext.getBindingContext(), declaration)); + public TranslationContext newDeclaration(@NotNull PsiElement element) { + return newDeclaration(getDescriptorForElement(bindingContext(), element)); } @NotNull @@ -88,21 +64,20 @@ public final class TranslationContext { return staticContext.getBindingContext(); } - @NotNull public NamingScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) { return staticContext.getScopeForDescriptor(descriptor); } @NotNull - public NamingScope getScopeForElement(@NotNull JetElement element) { - DeclarationDescriptor descriptorForElement = BindingUtils.getDescriptorForElement(bindingContext(), element); + public NamingScope getScopeForElement(@NotNull PsiElement element) { + DeclarationDescriptor descriptorForElement = getDescriptorForElement(bindingContext(), element); return getScopeForDescriptor(descriptorForElement); } @NotNull - public JsName getNameForElement(@NotNull JetElement element) { - DeclarationDescriptor descriptor = BindingUtils.getDescriptorForElement(bindingContext(), element); + public JsName getNameForElement(@NotNull PsiElement element) { + DeclarationDescriptor descriptor = getDescriptorForElement(bindingContext(), element); return getNameForDescriptor(descriptor); } diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java index ab0d2065ef3..654dc544b47 100644 --- a/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java @@ -1,27 +1,24 @@ package org.jetbrains.k2js.translate.declaration; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsObjectLiteral; -import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer; +import com.google.dart.compiler.backend.js.ast.*; import com.google.dart.compiler.util.AstUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; -import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.Translation; -import org.jetbrains.k2js.translate.utils.BindingUtils; import java.util.ArrayList; import java.util.List; -import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter; +import static org.jetbrains.k2js.translate.utils.BindingUtils.*; import static org.jetbrains.k2js.translate.utils.DescriptorUtils.findAncestorClass; +import static org.jetbrains.k2js.translate.utils.PsiUtils.getPrimaryConstructorParameters; /** * @author Pavel Talanov @@ -29,7 +26,16 @@ import static org.jetbrains.k2js.translate.utils.DescriptorUtils.findAncestorCla public final class ClassTranslator extends AbstractTranslator { @NotNull - public static JsInvocation translateClass(@NotNull JetClass classDeclaration, @NotNull TranslationContext context) { + public static JsPropertyInitializer translateAsProperty(@NotNull JetClassOrObject classDeclaration, + @NotNull TranslationContext context) { + JsInvocation classCreationExpression = generateClassCreationExpression(classDeclaration, context); + JsName className = context.getNameForElement(classDeclaration); + return new JsPropertyInitializer(className.makeRef(), classCreationExpression); + } + + @NotNull + public static JsInvocation generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration, + @NotNull TranslationContext context) { return (new ClassTranslator(classDeclaration, context)).translateClass(); } @@ -37,10 +43,14 @@ public final class ClassTranslator extends AbstractTranslator { private final DeclarationBodyVisitor declarationBodyVisitor = new DeclarationBodyVisitor(); @NotNull - private final JetClass classDeclaration; + private final JetClassOrObject classDeclaration; - private ClassTranslator(@NotNull JetClass classDeclaration, @NotNull TranslationContext context) { - super(context.newClass(classDeclaration)); + @NotNull + private final ClassDescriptor descriptor; + + private ClassTranslator(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) { + super(context.newDeclaration(classDeclaration)); + this.descriptor = getClassDescriptor(context.bindingContext(), classDeclaration); this.classDeclaration = classDeclaration; } @@ -54,13 +64,23 @@ public final class ClassTranslator extends AbstractTranslator { @NotNull private JsInvocation classCreateMethodInvocation() { - if (classDeclaration.isTrait()) { + if (isObject()) { + return AstUtil.newInvocation(context().namer().objectCreationMethodReference()); + } else if (isTrait()) { return AstUtil.newInvocation(context().namer().traitCreationMethodReference()); } else { return AstUtil.newInvocation(context().namer().classCreationMethodReference()); } } + private boolean isObject() { + return descriptor.getKind().equals(ClassKind.OBJECT); + } + + private boolean isTrait() { + return descriptor.getKind().equals(ClassKind.TRAIT); + } + private void addClassOwnDeclarations(@NotNull JsInvocation jsClassDeclaration) { JsObjectLiteral jsClassDescription = translateClassDeclarations(); jsClassDeclaration.getArguments().add(jsClassDescription); @@ -75,8 +95,7 @@ public final class ClassTranslator extends AbstractTranslator { @NotNull private List getSuperclassNameReferences() { List superclassReferences = new ArrayList(); - List superclassDescriptors = - BindingUtils.getSuperclassDescriptors(context().bindingContext(), classDeclaration); + List superclassDescriptors = getSuperclassDescriptors(descriptor); addAncestorClass(superclassReferences, superclassDescriptors); addTraits(superclassReferences, superclassDescriptors); return superclassReferences; @@ -120,7 +139,7 @@ public final class ClassTranslator extends AbstractTranslator { @NotNull private JsObjectLiteral translateClassDeclarations() { List propertyList = new ArrayList(); - if (!classDeclaration.isTrait()) { + if (!isTrait()) { propertyList.add(Translation.generateClassInitializerMethod(classDeclaration, context())); } propertyList.addAll(translatePropertiesAsConstructorParameters()); @@ -131,7 +150,7 @@ public final class ClassTranslator extends AbstractTranslator { @NotNull private List translatePropertiesAsConstructorParameters() { List result = new ArrayList(); - for (JetParameter parameter : classDeclaration.getPrimaryConstructorParameters()) { + for (JetParameter parameter : getPrimaryConstructorParameters(classDeclaration)) { PropertyDescriptor descriptor = getPropertyDescriptorForConstructorParameter(context().bindingContext(), parameter); if (descriptor != null) { diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java b/translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java index 1288e1bb148..a39f713a83b 100644 --- a/translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java @@ -11,11 +11,11 @@ import org.jetbrains.k2js.translate.general.TranslatorVisitor; import org.jetbrains.k2js.translate.utils.BindingUtils; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import static org.jetbrains.k2js.translate.utils.BindingUtils.getDeclarationsForNamespace; +import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForObjectDeclaration; /** * @author Pavel Talanov @@ -24,7 +24,7 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor traverseClass(@NotNull JetClass jetClass, + public List traverseClass(@NotNull JetClassOrObject jetClass, @NotNull TranslationContext context) { List properties = new ArrayList(); for (JetDeclaration declaration : jetClass.getDeclarations()) { @@ -53,7 +53,7 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor visitNamedFunction(@NotNull JetNamedFunction expression, @NotNull TranslationContext context) { - return Arrays.asList(Translation.functionTranslator(expression, context).translateAsMethod()); + return Collections.singletonList(Translation.functionTranslator(expression, context).translateAsMethod()); } @Override @@ -65,6 +65,21 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor visitObjectDeclaration(@NotNull JetObjectDeclaration expression, + @NotNull TranslationContext context) { + return Collections.singletonList(ClassTranslator.translateAsProperty(expression, context)); + } + + @Override + @NotNull + public List visitObjectDeclarationName(@NotNull JetObjectDeclarationName expression, + @NotNull TranslationContext context) { + PropertyDescriptor propertyDescriptor = + getPropertyDescriptorForObjectDeclaration(context.bindingContext(), expression); + return PropertyTranslator.translateAccessors(propertyDescriptor, context); + } @Override @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java index d93d077d6e5..dda8b8db198 100644 --- a/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java @@ -32,7 +32,7 @@ public final class NamespaceTranslator extends AbstractTranslator { } private NamespaceTranslator(@NotNull NamespaceDescriptor namespace, @NotNull TranslationContext context) { - super(context.newNamespace(namespace)); + super(context.newDeclaration(namespace)); this.namespace = namespace; this.namespaceName = context.getNameForDescriptor(namespace); this.classDeclarationTranslator = new ClassDeclarationTranslator(context(), namespace); diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java index fa2abe2e278..5dfc62106be 100644 --- a/translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java @@ -130,7 +130,7 @@ public final class PropertyTranslator extends AbstractTranslator { @NotNull private TranslationContext propertyAccessContext(@NotNull PropertySetterDescriptor propertySetterDescriptor) { - return context().newPropertyAccess(propertySetterDescriptor); + return context().newDeclaration(propertySetterDescriptor); } @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java index ab7372e80d5..97e2490288f 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java @@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.NullValue; import org.jetbrains.k2js.translate.context.TemporaryVariable; import org.jetbrains.k2js.translate.context.TranslationContext; +import org.jetbrains.k2js.translate.declaration.ClassTranslator; import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.general.TranslatorVisitor; import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator; @@ -369,4 +370,25 @@ public final class ExpressionVisitor extends TranslatorVisitor { assert thrownExpression != null : "Thrown expression must not be null"; return new JsThrow(translateAsExpression(thrownExpression, context)); } + + @Override + @NotNull + public JsNode visitObjectLiteralExpression(@NotNull JetObjectLiteralExpression expression, + @NotNull TranslationContext context) { + return ClassTranslator.generateClassCreationExpression(expression.getObjectDeclaration(), context); + } + + @Override + @NotNull + public JsNode visitObjectDeclaration(@NotNull JetObjectDeclaration expression, + @NotNull TranslationContext context) { + //TODO: util + JetObjectDeclarationName nameAsDeclaration = expression.getNameAsDeclaration(); + assert nameAsDeclaration != null; + DeclarationDescriptor descriptor = getDescriptorForElement(context.bindingContext(), + nameAsDeclaration); + JsName propertyName = context.getNameForDescriptor(descriptor); + JsExpression value = ClassTranslator.generateClassCreationExpression(expression, context); + return AstUtil.newVar(propertyName, value); + } } diff --git a/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java index 86a8d09d933..56c501218a4 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java @@ -156,16 +156,11 @@ public final class FunctionTranslator extends AbstractTranslator { @NotNull private TranslationContext functionBodyContext() { - if (functionDeclaration instanceof JetNamedFunction) { - return context().newFunctionDeclaration((JetNamedFunction) functionDeclaration); - } - if (functionDeclaration instanceof JetPropertyAccessor) { - return context().newPropertyAccess((JetPropertyAccessor) functionDeclaration); - } if (isLiteral()) { return context().innerJsScope(functionObject.getScope()); + } else { + return context().newDeclaration(functionDeclaration); } - throw new AssertionError("Unsupported type of functionDeclaration."); } @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/general/Translation.java b/translator/src/org/jetbrains/k2js/translate/general/Translation.java index 960cb34e650..d8b1cc3cbb3 100644 --- a/translator/src/org/jetbrains/k2js/translate/general/Translation.java +++ b/translator/src/org/jetbrains/k2js/translate/general/Translation.java @@ -46,7 +46,7 @@ public final class Translation { @NotNull public static JsInvocation translateClassDeclaration(@NotNull JetClass classDeclaration, @NotNull TranslationContext context) { - return ClassTranslator.translateClass(classDeclaration, context); + return ClassTranslator.generateClassCreationExpression(classDeclaration, context); } @NotNull @@ -79,7 +79,7 @@ public final class Translation { //TODO: see if generate*Initializer methods fit somewhere else @NotNull - public static JsPropertyInitializer generateClassInitializerMethod(@NotNull JetClass classDeclaration, + public static JsPropertyInitializer generateClassInitializerMethod(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) { return (new ClassInitializerTranslator(classDeclaration, context)).generateInitializeMethod(); } diff --git a/translator/src/org/jetbrains/k2js/translate/initializer/AbstractInitializerTranslator.java b/translator/src/org/jetbrains/k2js/translate/initializer/AbstractInitializerTranslator.java index df2f734cc5a..adc0c2658dd 100644 --- a/translator/src/org/jetbrains/k2js/translate/initializer/AbstractInitializerTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/initializer/AbstractInitializerTranslator.java @@ -5,7 +5,7 @@ import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer; import com.google.dart.compiler.backend.js.ast.JsStatement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; -import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.NamingScope; import org.jetbrains.k2js.translate.context.TranslationContext; @@ -40,7 +40,7 @@ public abstract class AbstractInitializerTranslator extends AbstractTranslator { } @NotNull - protected List translateClassInitializers(@NotNull JetClass declaration) { + protected List translateClassInitializers(@NotNull JetClassOrObject declaration) { return visitor.traverseClass(declaration, context()); } diff --git a/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java b/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java index 8ac49f65a35..d70aef8890f 100644 --- a/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java @@ -6,12 +6,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; -import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetDelegationSpecifier; import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.TranslationContext; +import org.jetbrains.k2js.translate.utils.PsiUtils; import org.jetbrains.k2js.translate.utils.TranslationUtils; import java.util.ArrayList; @@ -27,11 +28,11 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.functionWithSc public final class ClassInitializerTranslator extends AbstractInitializerTranslator { @NotNull - private final JetClass classDeclaration; + private final JetClassOrObject classDeclaration; @NotNull private final List initializerStatements = new ArrayList(); - public ClassInitializerTranslator(@NotNull JetClass classDeclaration, @NotNull TranslationContext context) { + public ClassInitializerTranslator(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) { super(context.getScopeForElement(classDeclaration).innerScope ("initializer " + classDeclaration.getName()), context); this.classDeclaration = classDeclaration; @@ -91,7 +92,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla @NotNull List translatePrimaryConstructorParameters() { - List parameterList = classDeclaration.getPrimaryConstructorParameters(); + List parameterList = PsiUtils.getPrimaryConstructorParameters(classDeclaration); List result = new ArrayList(); for (JetParameter jetParameter : parameterList) { result.add(translateParameter(jetParameter)); diff --git a/translator/src/org/jetbrains/k2js/translate/initializer/InitializerVisitor.java b/translator/src/org/jetbrains/k2js/translate/initializer/InitializerVisitor.java index b255220d761..f63a301ebf6 100644 --- a/translator/src/org/jetbrains/k2js/translate/initializer/InitializerVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/initializer/InitializerVisitor.java @@ -1,12 +1,15 @@ package org.jetbrains.k2js.translate.initializer; import com.google.dart.compiler.backend.js.ast.JsExpression; +import com.google.dart.compiler.backend.js.ast.JsInvocation; +import com.google.dart.compiler.backend.js.ast.JsName; import com.google.dart.compiler.backend.js.ast.JsStatement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.k2js.translate.context.TranslationContext; +import org.jetbrains.k2js.translate.declaration.ClassTranslator; import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.general.TranslatorVisitor; import org.jetbrains.k2js.translate.utils.BindingUtils; @@ -14,9 +17,13 @@ import org.jetbrains.k2js.translate.utils.TranslationUtils; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import static java.util.Collections.singletonList; import static org.jetbrains.k2js.translate.utils.BindingUtils.getDeclarationsForNamespace; +import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForObjectDeclaration; +import static org.jetbrains.k2js.translate.utils.PsiUtils.getObjectDeclarationForName; /** * @author Pavel Talanov @@ -43,6 +50,7 @@ public final class InitializerVisitor extends TranslatorVisitor visitDeclaration(@NotNull JetDeclaration expression, @NotNull TranslationContext context) { - return new ArrayList(); + return Collections.emptyList(); + } + + @Override + @NotNull + public List visitObjectDeclarationName(@NotNull JetObjectDeclarationName objectName, + @NotNull TranslationContext context) { + PropertyDescriptor propertyDescriptorForObjectDeclaration + = getPropertyDescriptorForObjectDeclaration(context.bindingContext(), objectName); + JsName objectPropertyName = context.getNameForDescriptor(propertyDescriptorForObjectDeclaration); + JetObjectDeclaration objectDeclaration = getObjectDeclarationForName(objectName); + JsInvocation objectValue = ClassTranslator.generateClassCreationExpression(objectDeclaration, context); + return singletonList(TranslationUtils.assignmentToBackingField(context, + propertyDescriptorForObjectDeclaration, objectValue)); } @NotNull - public List traverseClass(@NotNull JetClass expression, @NotNull TranslationContext context) { + public List traverseClass(@NotNull JetClassOrObject expression, @NotNull TranslationContext context) { List initializerStatements = new ArrayList(); for (JetDeclaration declaration : expression.getDeclarations()) { initializerStatements.addAll(declaration.accept(this, context)); diff --git a/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java index 322cc6f456b..c902fdba5b6 100644 --- a/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java @@ -41,7 +41,8 @@ public final class BindingUtils { } @NotNull - public static ClassDescriptor getClassDescriptor(@NotNull BindingContext context, @NotNull JetClass declaration) { + public static ClassDescriptor getClassDescriptor(@NotNull BindingContext context, + @NotNull JetClassOrObject declaration) { return getDescriptorForExpression(context, declaration, ClassDescriptor.class); } @@ -113,13 +114,6 @@ public final class BindingUtils { return (JetParameter) result; } - @NotNull - public static List getSuperclassDescriptors(@NotNull BindingContext context, - @NotNull JetClass classDeclaration) { - ClassDescriptor classDescriptor = getClassDescriptor(context, classDeclaration); - return getSuperclassDescriptors(classDescriptor); - } - @NotNull public static List getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) { Collection superclassTypes = classDescriptor.getTypeConstructor().getSupertypes(); @@ -142,8 +136,9 @@ public final class BindingUtils { return (ClassDescriptor) superClassDescriptor; } - public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClass classDeclaration) { - List superclassDescriptors = getSuperclassDescriptors(context, classDeclaration); + public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClassOrObject classDeclaration) { + ClassDescriptor classDescriptor = getClassDescriptor(context, classDeclaration); + List superclassDescriptors = getSuperclassDescriptors(classDescriptor); return (DescriptorUtils.findAncestorClass(superclassDescriptors) != null); } @@ -264,7 +259,7 @@ public final class BindingUtils { @NotNull public static DeclarationDescriptor getDescriptorForElement(@NotNull BindingContext context, - @NotNull JetElement element) { + @NotNull PsiElement element) { DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element); assert descriptor != null : element + " doesn't have a descriptor."; return descriptor; @@ -312,4 +307,12 @@ public final class BindingUtils { assert hasNextDescriptor != null : "Range expression must have a descriptor for hasNext function or property."; return hasNextDescriptor; } + + @NotNull + public static PropertyDescriptor getPropertyDescriptorForObjectDeclaration(@NotNull BindingContext context, + @NotNull JetObjectDeclarationName name) { + PropertyDescriptor propertyDescriptor = context.get(BindingContext.OBJECT_DECLARATION, name); + assert propertyDescriptor != null; + return propertyDescriptor; + } } diff --git a/translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java index f94416be951..c280f0aa400 100644 --- a/translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java @@ -1,5 +1,6 @@ package org.jetbrains.k2js.translate.utils; +import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -7,6 +8,9 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; +import java.util.Collections; +import java.util.List; + /** * @author Pavel Talanov */ @@ -97,4 +101,21 @@ public final class PsiUtils { assert loopParameter != null; return loopParameter; } + + @NotNull + public static List getPrimaryConstructorParameters(@NotNull JetClassOrObject classDeclaration) { + if (classDeclaration instanceof JetClass) { + return ((JetClass) classDeclaration).getPrimaryConstructorParameters(); + } + return Collections.emptyList(); + } + + @NotNull + public static JetObjectDeclaration getObjectDeclarationForName(@NotNull JetObjectDeclarationName name) { + PsiElement parent = name.getParent(); + assert parent instanceof JetObjectDeclaration : + "ObjectDeclarationName should have a parent of type ObjectDeclaration."; + return (JetObjectDeclaration) parent; + + } } diff --git a/translator/test/org/jetbrains/k2js/test/ObjectTest.java b/translator/test/org/jetbrains/k2js/test/ObjectTest.java index 25df0aed8e8..5377930e737 100644 --- a/translator/test/org/jetbrains/k2js/test/ObjectTest.java +++ b/translator/test/org/jetbrains/k2js/test/ObjectTest.java @@ -5,7 +5,7 @@ import org.junit.Test; /** * @author Pavel Talanov */ -public class ObjectTest extends TranslationTest { +public final class ObjectTest extends TranslationTest { private static final String MAIN = "object/"; @@ -18,4 +18,14 @@ public class ObjectTest extends TranslationTest { public void objectWithMethods() throws Exception { testFooBoxIsTrue("objectWithMethods.kt"); } + + @Test + public void objectDeclaration() throws Exception { + testFooBoxIsTrue("objectDeclaration.kt"); + } + + @Test + public void objectInMethod() throws Exception { + testFooBoxIsTrue("objectInMethod.kt"); + } } \ No newline at end of file diff --git a/translator/test/org/jetbrains/k2js/test/WebDemoExamples2Test.java b/translator/test/org/jetbrains/k2js/test/WebDemoExamples2Test.java index cc14a7f1229..a57ad663d26 100644 --- a/translator/test/org/jetbrains/k2js/test/WebDemoExamples2Test.java +++ b/translator/test/org/jetbrains/k2js/test/WebDemoExamples2Test.java @@ -21,10 +21,10 @@ public final class WebDemoExamples2Test extends TranslationTest { } //TODO: a couple of classes not supported and objects -// @Test -// public void life() throws Exception { -// testWithMain("life", "", "2"); -// } + @Test + public void life() throws Exception { + testWithMain("life", "", "2"); + } @Test public void builder() throws Exception { diff --git a/translator/testFiles/kotlin_lib.js b/translator/testFiles/kotlin_lib.js index 52cbb4d5d40..c937205ad0f 100644 --- a/translator/testFiles/kotlin_lib.js +++ b/translator/testFiles/kotlin_lib.js @@ -252,6 +252,7 @@ Kotlin.Namespace = Namespace; Kotlin.Trait = Trait; Kotlin.isType = isType; + Kotlin.object = object; Kotlin.equals = function (obj1, obj2) { if (typeof obj1 == "object") { @@ -499,6 +500,10 @@ } ); + Kotlin.splitString = function(str, regex) { + return str.split(regex); + }; + Kotlin.nullArray = function (size) { var res = []; var i = size; diff --git a/translator/testFiles/object/cases/objectDeclaration.kt b/translator/testFiles/object/cases/objectDeclaration.kt new file mode 100644 index 00000000000..fdf1c0fa352 --- /dev/null +++ b/translator/testFiles/object/cases/objectDeclaration.kt @@ -0,0 +1,17 @@ +package foo + +object test { + var c = 2; + var b = 1; +} + +fun box() : Boolean { + if (test.c != 2) return false; + + if (test.b != 1) return false; + test.c += 10 + if (test.c != 12) { + return false; + } + return true; +} \ No newline at end of file diff --git a/translator/testFiles/object/cases/objectInMethod.kt b/translator/testFiles/object/cases/objectInMethod.kt new file mode 100644 index 00000000000..664d6aedc83 --- /dev/null +++ b/translator/testFiles/object/cases/objectInMethod.kt @@ -0,0 +1,18 @@ +package foo + +class A() { + + fun f() : Boolean { + + object t { + val c = true; + } + val z = object { + val c = true + } + return t.c && z.c + } + +} + +fun box() = A().f(); diff --git a/translator/testFiles/webDemoExamples2/cases/life.kt b/translator/testFiles/webDemoExamples2/cases/life.kt index f1199fde6d0..831b1e6c707 100644 --- a/translator/testFiles/webDemoExamples2/cases/life.kt +++ b/translator/testFiles/webDemoExamples2/cases/life.kt @@ -154,18 +154,8 @@ fun comparator (f : (T, T) -> Int) : Comparator = object : Comparator { override fun compare(o1 : T, o2 : T) : Int = f(o1, o2) } -fun println(message : Any?) { - System.out?.println(message) -} - -fun print(message : Any?) { - System.out?.print(message) -} - val Array.isEmpty : Boolean get() = size == 0 -fun String.split(s : String) = (this as java.lang.String).split(s) - val String.size : Int get() = length