From 8e147b26a733513b9be9ca612bb6300cd3062d02 Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Thu, 10 Nov 2011 21:29:50 +0400 Subject: [PATCH] Added default getter/setter support and initializer support. --- .idea/workspace.xml | 586 ++++++++++-------- .../dart/compiler/backend/js/ast/JsBlock.java | 68 +- .../compiler/backend/js/ast/JsInvocation.java | 6 + .../declarations/DeclarationExtractor.java | 16 +- .../k2js/declarations/ExtractionVisitor.java | 54 +- .../k2js/translate/ClassBodyVisitor.java | 3 + .../k2js/translate/ClassTranslator.java | 16 +- .../k2js/translate/ExpressionTranslator.java | 2 +- .../k2js/translate/ExpressionVisitor.java | 82 ++- .../k2js/translate/InitializerVisitor.java | 69 +++ .../org/jetbrains/k2js/translate/Namer.java | 6 +- .../k2js/translate/OperationTranslator.java | 4 + .../translate/PropertyAccessTranslator.java | 105 ++++ .../k2js/translate/TranslationContext.java | 5 + .../org/jetbrains/k2js/test/ClassTest.java | 15 + .../test_cases/accessToInstanceProperty.kt | 5 +- .../test_cases/constructorWithParameter.kt | 9 + translator/test_files/test_cases/setter.kt | 12 + .../test_cases/twoClassesWithProperties.kt | 13 + 19 files changed, 740 insertions(+), 336 deletions(-) create mode 100644 translator/src/org/jetbrains/k2js/translate/InitializerVisitor.java create mode 100644 translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java create mode 100644 translator/test_files/test_cases/constructorWithParameter.kt create mode 100644 translator/test_files/test_cases/setter.kt create mode 100644 translator/test_files/test_cases/twoClassesWithProperties.kt diff --git a/.idea/workspace.xml b/.idea/workspace.xml index f828a9fb0f0..0c6727619f0 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,11 +6,25 @@ - + + + + + - - - + + + + + + + + + + + + + @@ -35,7 +49,20 @@ - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -189,14 +147,46 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -204,10 +194,32 @@ - - + + - + + + + + + + + + + + + + + + + + + + + + + + @@ -215,10 +227,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -226,70 +294,19 @@ - - + + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -311,22 +328,22 @@ @@ -463,6 +480,50 @@ - + - + - - - + + - + - + @@ -755,10 +810,10 @@ - - + + - + localhost @@ -800,24 +855,24 @@ - - - + + + - + - + - - - + + + - + - + @@ -848,7 +903,7 @@ @@ -880,132 +936,130 @@ - + - + + + + + + + + - + - + - + - + - - - - - - - - + - + - - - - + + + + + + + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/js/src/com/google/dart/compiler/backend/js/ast/JsBlock.java b/js/src/com/google/dart/compiler/backend/js/ast/JsBlock.java index 3d927a2bf7d..10973593ecc 100644 --- a/js/src/com/google/dart/compiler/backend/js/ast/JsBlock.java +++ b/js/src/com/google/dart/compiler/backend/js/ast/JsBlock.java @@ -12,38 +12,44 @@ import java.util.List; */ public class JsBlock extends JsStatement { - private final List stmts = new ArrayList(); + private final List stmts = new ArrayList(); - public JsBlock() { - } - - public JsBlock(JsStatement stmt) { - stmts.add(stmt); - } - - public List getStatements() { - return stmts; - } - - public void addStatement(JsStatement statement) { - assert statement != null; - stmts.add(statement); - } - - public boolean isGlobalBlock() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - v.acceptWithInsertRemove(stmts); + public JsBlock() { + } + + public JsBlock(JsStatement stmt) { + stmts.add(stmt); + } + + public List getStatements() { + return stmts; + } + + public void addStatement(JsStatement statement) { + assert statement != null; + stmts.add(statement); + } + + public boolean isGlobalBlock() { + return false; + } + + @Override + public void traverse(JsVisitor v, JsContext ctx) { + if (v.visit(this, ctx)) { + v.acceptWithInsertRemove(stmts); + } + v.endVisit(this, ctx); + } + + @Override + public NodeKind getKind() { + return NodeKind.BLOCK; + } + + public void setStatements(List statements) { + assert this.stmts.isEmpty() : "Already contains statements."; + this.stmts.addAll(statements); } - v.endVisit(this, ctx); - } - @Override - public NodeKind getKind() { - return NodeKind.BLOCK; - } } diff --git a/js/src/com/google/dart/compiler/backend/js/ast/JsInvocation.java b/js/src/com/google/dart/compiler/backend/js/ast/JsInvocation.java index 6704234df29..40cb649319c 100644 --- a/js/src/com/google/dart/compiler/backend/js/ast/JsInvocation.java +++ b/js/src/com/google/dart/compiler/backend/js/ast/JsInvocation.java @@ -59,4 +59,10 @@ public final class JsInvocation extends JsExpression implements HasArguments { public NodeKind getKind() { return NodeKind.INVOKE; } + + // Pavel Talanov + public void setArguments(List arguments) { + assert this.args.isEmpty() : "Arguments already set."; + this.args.addAll(arguments); + } } diff --git a/translator/src/org/jetbrains/k2js/declarations/DeclarationExtractor.java b/translator/src/org/jetbrains/k2js/declarations/DeclarationExtractor.java index e49124a4590..492f80c6fd2 100644 --- a/translator/src/org/jetbrains/k2js/declarations/DeclarationExtractor.java +++ b/translator/src/org/jetbrains/k2js/declarations/DeclarationExtractor.java @@ -1,5 +1,6 @@ package org.jetbrains.k2js.declarations; +import com.google.dart.compiler.backend.js.ast.JsName; import com.google.dart.compiler.backend.js.ast.JsScope; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; @@ -13,6 +14,8 @@ import java.util.Map; public final class DeclarationExtractor { private final Map descriptorToScopeMap = new HashMap(); + private final Map descriptorToNameMap + = new HashMap(); public DeclarationExtractor() { @@ -30,7 +33,18 @@ public final class DeclarationExtractor { return scope; } - /*package*/ void put(@NotNull DeclarationDescriptor descriptor, @NotNull JsScope scope) { + @NotNull + public JsName getName(@NotNull DeclarationDescriptor descriptor) { + JsName name = descriptorToNameMap.get(descriptor); + assert name != null : "Unknown declaration"; + return name; + } + + /*package*/ void putScope(@NotNull DeclarationDescriptor descriptor, @NotNull JsScope scope) { descriptorToScopeMap.put(descriptor, scope); } + + /*package*/ void putName(@NotNull DeclarationDescriptor descriptor, @NotNull JsName name) { + descriptorToNameMap.put(descriptor, name); + } } diff --git a/translator/src/org/jetbrains/k2js/declarations/ExtractionVisitor.java b/translator/src/org/jetbrains/k2js/declarations/ExtractionVisitor.java index c69cc8f0f17..1fbea825abb 100644 --- a/translator/src/org/jetbrains/k2js/declarations/ExtractionVisitor.java +++ b/translator/src/org/jetbrains/k2js/declarations/ExtractionVisitor.java @@ -1,8 +1,6 @@ package org.jetbrains.k2js.declarations; -import com.google.dart.compiler.backend.js.ast.JsName; import com.google.dart.compiler.backend.js.ast.JsScope; -import com.intellij.codeInspection.ex.Descriptor; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.k2js.translate.Namer; @@ -20,11 +18,11 @@ public final class ExtractionVisitor extends DeclarationDescriptorVisitor(), AstUtil.convertToBlock(returnExpression)); } + //TODO rewrite @NotNull private JsName declareOrGetBackingFieldName(@NotNull String propertyName, @NotNull TranslationContext context) { String backingFieldName = Namer.getBackingFieldNameForProperty(propertyName); @@ -113,6 +115,7 @@ public final class ClassBodyVisitor extends TranslatorVisitor initializerStatements = classDeclaration.accept(initializerVisitor, + translationContext().newClass(classDeclaration)); + JsBlock block = new JsBlock(); + block.setStatements(initializerStatements); + return AstUtil.newFunction(translationContext().enclosingScope(), null, null, block); } diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionTranslator.java b/translator/src/org/jetbrains/k2js/translate/ExpressionTranslator.java index 6bbf698f72a..934f33ebce6 100644 --- a/translator/src/org/jetbrains/k2js/translate/ExpressionTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/ExpressionTranslator.java @@ -9,7 +9,7 @@ import org.jetbrains.jet.lang.psi.JetExpression; */ public final class ExpressionTranslator extends AbstractTranslator { - final private ExpressionVisitor visitor = new ExpressionVisitor(); + final private ExpressionVisitor visitor = new ExpressionVisitor(translationContext()); public ExpressionTranslator(@NotNull TranslationContext context) { super(context); diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java index 1de62d25e08..7259463428d 100644 --- a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java @@ -5,7 +5,6 @@ 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.JsReturn; import com.google.dart.compiler.util.AstUtil; -import com.sun.xml.internal.bind.v2.runtime.reflect.opt.Const; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; @@ -17,6 +16,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lexer.JetToken; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -24,6 +24,8 @@ import java.util.List; */ public final class ExpressionVisitor extends TranslatorVisitor { + public ExpressionVisitor(TranslationContext context) { + } //TODO method too long @Override @@ -87,13 +89,39 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull public JsNode visitBinaryExpression(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) { + JsInvocation setterCall = translateAsSetterCall(expression, context); + if (setterCall != null) { + return setterCall; + } + return translateAsBinaryOperation(expression, context); + } + + @Nullable + public JsInvocation translateAsSetterCall(@NotNull JetBinaryExpression expression, + @NotNull TranslationContext context) { + JetToken jetOperationToken = (JetToken)expression.getOperationToken(); + if (!OperationTranslator.isAssignment(jetOperationToken)) { + return null; + } + PropertyAccessTranslator translator = new PropertyAccessTranslator(context); + JetExpression leftExpression = expression.getLeft(); + JsInvocation setterCall = translator.resolveAsPropertySet(leftExpression); + if (setterCall == null) { + return null; + } + JetExpression rightExpression = expression.getRight(); + assert rightExpression != null : "Selector should not be null"; + JsExpression right = AstUtil.convertToExpression(rightExpression.accept(this, context)); + setterCall.setArguments(Arrays.asList(right)); + return setterCall; + } + + @NotNull + private JsNode translateAsBinaryOperation(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) { JsExpression left = AstUtil.convertToExpression(expression.getLeft().accept(this, context)); JetExpression rightExpression = expression.getRight(); - if (rightExpression == null) { - throw new AssertionError("BinaryExpression with no right parameter"); - } + assert rightExpression != null : "Selector should not be null"; JsExpression right = AstUtil.convertToExpression(rightExpression.accept(this, context)); - //TODO cast dangerous? JetToken jetOperationToken = (JetToken)expression.getOperationToken(); return new JsBinaryOperation(OperationTranslator.getBinaryOperator(jetOperationToken), left, right); } @@ -281,6 +309,25 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull public JsNode visitDotQualifiedExpression(@NotNull JetDotQualifiedExpression expression, @NotNull TranslationContext context) { + JsInvocation getterCall = translateAsGetterCall(expression, context); + if (getterCall != null) { + return getterCall; + } + return translateAsQualifiedExpression(expression, context); + } + + @Nullable + private JsInvocation translateAsGetterCall(@NotNull JetDotQualifiedExpression expression, + @NotNull TranslationContext context) { + JsInvocation result; + PropertyAccessTranslator translator = new PropertyAccessTranslator(context); + result = translator.resolveAsPropertyGet(expression); + return result; + } + + @NotNull + private JsNode translateAsQualifiedExpression(@NotNull JetDotQualifiedExpression expression, + @NotNull TranslationContext context) { JsExpression receiver = AstUtil.convertToExpression(expression.getReceiverExpression().accept(this, context)); JetExpression jetSelector = expression.getSelectorExpression(); assert jetSelector != null : "Selector should not be null in dot qualified expression."; @@ -288,18 +335,27 @@ public final class ExpressionVisitor extends TranslatorVisitor { assert (selector instanceof JsNameRef || selector instanceof JsInvocation) : "Selector should be a name reference or a method invocation in dot qualified expression."; if (selector instanceof JsInvocation) { - JsInvocation result = (JsInvocation)selector; - JsExpression qualifier = result.getQualifier(); - JsNameRef nameRef = (JsNameRef)qualifier; - nameRef.setQualifier(receiver); - return result; + return translateAsQualifiedInvocation(receiver, (JsInvocation) selector); } else { - JsNameRef result = (JsNameRef)selector; - result.setQualifier(receiver); - return result; + return translateAsQualifiedNameReference(receiver, (JsNameRef) selector); } } + @NotNull + private JsNode translateAsQualifiedNameReference(@NotNull JsExpression receiver, @NotNull JsNameRef selector) { + JsNameRef result = (JsNameRef)selector; + result.setQualifier(receiver); + return result; + } + + @NotNull + private JsNode translateAsQualifiedInvocation(@NotNull JsExpression receiver, @NotNull JsInvocation selector) { + JsInvocation result = (JsInvocation)selector; + JsExpression qualifier = result.getQualifier(); + JsNameRef nameRef = (JsNameRef)qualifier; + nameRef.setQualifier(receiver); + return result; + } } diff --git a/translator/src/org/jetbrains/k2js/translate/InitializerVisitor.java b/translator/src/org/jetbrains/k2js/translate/InitializerVisitor.java new file mode 100644 index 00000000000..834a2c801bf --- /dev/null +++ b/translator/src/org/jetbrains/k2js/translate/InitializerVisitor.java @@ -0,0 +1,69 @@ +package org.jetbrains.k2js.translate; + +import com.google.dart.compiler.backend.js.ast.*; +import com.google.dart.compiler.util.AstUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor; +import org.jetbrains.jet.lang.psi.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author Talanov Pavel + * + * This visitor collects all initializers from a given class in a list of statements. + * Note: we do use this to preserve the order in which initializers are executed. + */ +public class InitializerVisitor extends TranslatorVisitor> { + + @Override + @NotNull + public List visitClass(@NotNull JetClass expression, @NotNull TranslationContext context) { + List initializerStatements = new ArrayList(); + for (JetDeclaration declaration : expression.getDeclarations()) { + initializerStatements.addAll(declaration.accept(this, context)); + } + return initializerStatements; + } + + @Override + @NotNull + public List visitProperty(@NotNull JetProperty expression, @NotNull TranslationContext context) { + JetExpression initializer = expression.getInitializer(); + if (initializer == null) { + return new ArrayList(); + } + ExpressionTranslator translator = new ExpressionTranslator(context); + JsExpression initExpression = AstUtil.convertToExpression(translator.translate(initializer)); + return Arrays.asList(assignmentToBackingField(expression, initExpression, context)); + } + + @NotNull + JsStatement assignmentToBackingField(@NotNull JetProperty property, @NotNull JsExpression initExpression, + @NotNull TranslationContext context) { + JsName backingFieldName = context.classScope() + .findExistingName(Namer.getBackingFieldNameForProperty(property.getName())); + assert backingFieldName != null : "Class scope should contain backing field names"; + JsNameRef backingFieldRef = backingFieldName.makeRef(); + backingFieldRef.setQualifier(new JsThisRef()); + return AstUtil.convertToStatement(AstUtil.newAssignment(backingFieldRef, initExpression)); + } + + //TODO : implement + @Override + @NotNull + public List visitAnonymousInitializer(@NotNull JetClassInitializer initializer, + @NotNull TranslationContext context) { + return new ArrayList(); + } + + @Override + @NotNull + // Not interested in other types of declarations, they do not contain initializers. + public List visitDeclaration(@NotNull JetDeclaration expression, @NotNull TranslationContext context) { + return new ArrayList(); + } + +} diff --git a/translator/src/org/jetbrains/k2js/translate/Namer.java b/translator/src/org/jetbrains/k2js/translate/Namer.java index d7324fd6add..55b20c5aec6 100644 --- a/translator/src/org/jetbrains/k2js/translate/Namer.java +++ b/translator/src/org/jetbrains/k2js/translate/Namer.java @@ -20,9 +20,9 @@ public final class Namer { public static final String INITIALIZE_METHOD_NAME = "initialize"; private static final String CLASS_OBJECT_NAME = "Class"; //private static final String CLASS_CREATE_METHOD_NAME = "create"; - private static final String SETTER_PREFIX = "_set_"; - private static final String GETTER_PREFIX = "_get_"; - private static final String BACKING_FIELD_PREFIX = "_$_"; + private static final String SETTER_PREFIX = "set_"; + private static final String GETTER_PREFIX = "get_"; + private static final String BACKING_FIELD_PREFIX = "_"; // public static final String DEFAULT_SETTER_PARAM_NAME = "val"; public static String getClassObjectName() { diff --git a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java index 845c49fced6..871783f72ed 100644 --- a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java @@ -27,6 +27,7 @@ public final class OperationTranslator { map.put(JetTokens.LT, JsBinaryOperator.LT); map.put(JetTokens.LTEQ, JsBinaryOperator.LTE); map.put(JetTokens.EQEQ, JsBinaryOperator.EQ); + map.put(JetTokens.ANDAND, JsBinaryOperator.AND); } public static JsBinaryOperator getBinaryOperator(JetToken token) { @@ -38,5 +39,8 @@ public final class OperationTranslator { throw new AssertionError("Invalid map: should contain token: " + token.toString()); } + public static boolean isAssignment(JetToken token) { + return (token == JetTokens.EQ); + } } diff --git a/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java new file mode 100644 index 00000000000..9a118369366 --- /dev/null +++ b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java @@ -0,0 +1,105 @@ +package org.jetbrains.k2js.translate; + +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.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor; +import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; + +/** + * @author Talanov Pavel + */ +//TODO ask for code review. Class has messy code. +public final class PropertyAccessTranslator extends AbstractTranslator { + + public PropertyAccessTranslator(@NotNull TranslationContext context) { + super(context); + } + + @Nullable + public JsInvocation resolveAsPropertyGet(@NotNull JetDotQualifiedExpression expression) { + if (!(expression instanceof JetDotQualifiedExpression)) { + return null; + } + JetDotQualifiedExpression dotQualifiedExpression = (JetDotQualifiedExpression)expression; + JetExpression selectorExpression = dotQualifiedExpression.getSelectorExpression(); + assert selectorExpression != null : "Selector should not be null."; + JsName getterName = getPropertyGetterName(selectorExpression); + if (getterName == null) { + return null; + } + return translateReceiverAndReturnAccessorInvocation(dotQualifiedExpression, getterName); + } + + @NotNull + private JsInvocation translateReceiverAndReturnAccessorInvocation + (@NotNull JetDotQualifiedExpression dotQualifiedExpression, @NotNull JsName accessorName) { + ExpressionTranslator translator = new ExpressionTranslator(translationContext()); + JsNode node = translator.translate(dotQualifiedExpression.getReceiverExpression()); + JsNameRef result = accessorName.makeRef(); + result.setQualifier(AstUtil.convertToExpression(node)); + return AstUtil.newInvocation(result); + } + + @Nullable + public JsInvocation resolveAsPropertySet(@NotNull JetExpression expression) { + if (!(expression instanceof JetDotQualifiedExpression)) { + return null; + } + JetDotQualifiedExpression dotQualifiedExpression = (JetDotQualifiedExpression)expression; + JetExpression selectorExpression = dotQualifiedExpression.getSelectorExpression(); + assert selectorExpression != null : "Selector should not be null."; + JsName getterName = getPropertySetterName(selectorExpression); + if (getterName == null) { + return null; + } + return translateReceiverAndReturnAccessorInvocation(dotQualifiedExpression, getterName); + } + + @Nullable + public JsName getPropertyGetterName(@NotNull JetExpression expression) { + PropertyDescriptor property = getPropertyDescriptor(expression); + if (property == null) { + return null; + } + PropertyGetterDescriptor getter = property.getGetter(); + if (getter == null) { + return null; + } + return translationContext().declarations().getName(getter); + } + + @Nullable + public JsName getPropertySetterName(@NotNull JetExpression expression) { + PropertyDescriptor property = getPropertyDescriptor(expression); + if (property == null) { + return null; + } + PropertySetterDescriptor setter = property.getSetter(); + if (setter == null) { + return null; + } + return translationContext().declarations().getName(setter); + } + + @Nullable + private PropertyDescriptor getPropertyDescriptor(@NotNull JetExpression expression) { + ResolvedCall resolvedCall = + translationContext().bindingContext().get(BindingContext.RESOLVED_CALL, expression); + if (resolvedCall != null) { + DeclarationDescriptor descriptor = resolvedCall.getCandidateDescriptor(); + if (descriptor instanceof PropertyDescriptor) { + return (PropertyDescriptor)descriptor; + } + } + return null; + } + +} diff --git a/translator/src/org/jetbrains/k2js/translate/TranslationContext.java b/translator/src/org/jetbrains/k2js/translate/TranslationContext.java index 056f3c7f847..69c9f0c271a 100644 --- a/translator/src/org/jetbrains/k2js/translate/TranslationContext.java +++ b/translator/src/org/jetbrains/k2js/translate/TranslationContext.java @@ -152,4 +152,9 @@ public final class TranslationContext { assert descriptor != null : "Element should have a descriptor"; return getScopeForDescriptor(descriptor); } + + @NotNull + public DeclarationExtractor declarations() { + return extractor; + } } diff --git a/translator/test/org/jetbrains/k2js/test/ClassTest.java b/translator/test/org/jetbrains/k2js/test/ClassTest.java index 7ddc07e7a00..cfbf4814da8 100644 --- a/translator/test/org/jetbrains/k2js/test/ClassTest.java +++ b/translator/test/org/jetbrains/k2js/test/ClassTest.java @@ -57,4 +57,19 @@ public final class ClassTest extends TranslationTest { testFooBoxIsTrue("accessToInstanceProperty.kt"); } + @Test + public void twoClassesWithProperties() throws Exception { + testFooBoxIsTrue("twoClassesWithProperties.kt"); + } + + @Test + public void setter() throws Exception { + performTest("setter.kt", "foo", "f", 99.0); + } + + @Test + public void constructorWithParameter() throws Exception { + testFooBoxIsTrue("constructorWithParameter.kt"); + } + } diff --git a/translator/test_files/test_cases/accessToInstanceProperty.kt b/translator/test_files/test_cases/accessToInstanceProperty.kt index 340dee70671..3b210ee773d 100644 --- a/translator/test_files/test_cases/accessToInstanceProperty.kt +++ b/translator/test_files/test_cases/accessToInstanceProperty.kt @@ -1,10 +1,11 @@ namespace foo class Test() { - val a : Int = 1 + var a : Int = 100 } fun box() : Boolean { var test = Test() - return (test.a == 1) + test.a = 1 + return (1 == test.a) } \ No newline at end of file diff --git a/translator/test_files/test_cases/constructorWithParameter.kt b/translator/test_files/test_cases/constructorWithParameter.kt new file mode 100644 index 00000000000..a735b048b43 --- /dev/null +++ b/translator/test_files/test_cases/constructorWithParameter.kt @@ -0,0 +1,9 @@ +namespace foo + +class Test(var a : Int) { +} + +fun box() : Boolean { + var test = Test(1) + return (test.a == 1) +} \ No newline at end of file diff --git a/translator/test_files/test_cases/setter.kt b/translator/test_files/test_cases/setter.kt new file mode 100644 index 00000000000..ac6b99f7272 --- /dev/null +++ b/translator/test_files/test_cases/setter.kt @@ -0,0 +1,12 @@ +namespace foo + +class Test() { + var a : Int = 1 +} + +fun f() : Int { + var a = Test() + var b = Test() + b.a = 100 + return (b.a - a.a) +} \ No newline at end of file diff --git a/translator/test_files/test_cases/twoClassesWithProperties.kt b/translator/test_files/test_cases/twoClassesWithProperties.kt new file mode 100644 index 00000000000..7c6a8f57da0 --- /dev/null +++ b/translator/test_files/test_cases/twoClassesWithProperties.kt @@ -0,0 +1,13 @@ +namespace foo + +class A() { + val a : Int = 1 +} + +class B() { + val b : Int = 2 +} + +fun box() : Boolean { + return ((A().a == 1) && (B().b == 2); +} \ No newline at end of file