diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 4afb69675d7..49065793425 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,35 +6,13 @@ - + - - - - - - - - - - - + - - - - - - - - - - - - @@ -112,63 +90,9 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -178,10 +102,66 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -209,82 +189,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + @@ -293,7 +201,79 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -320,22 +300,22 @@ @@ -359,7 +339,7 @@ - + @@ -531,6 +511,32 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + localhost @@ -903,21 +913,21 @@ + - + - + - + - @@ -989,6 +999,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -996,107 +1069,46 @@ - + - + - + - + - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/js/src/com/google/dart/compiler/util/AstUtil.java b/js/src/com/google/dart/compiler/util/AstUtil.java index 1ca19c75a1a..0b3e8768205 100644 --- a/js/src/com/google/dart/compiler/util/AstUtil.java +++ b/js/src/com/google/dart/compiler/util/AstUtil.java @@ -7,6 +7,7 @@ package com.google.dart.compiler.util; import com.google.dart.compiler.InternalCompilerException; import com.google.dart.compiler.backend.js.ast.*; import com.google.dart.compiler.common.SourceInfo; + import java.util.List; /** @@ -182,31 +183,6 @@ public class AstUtil { return fn; } - public static JsStatement convertToStatement(JsNode jsNode) { - if (jsNode instanceof JsExpression) { - return new JsExprStmt((JsExpression) jsNode); - } - if (jsNode instanceof JsStatement) { - return (JsStatement) jsNode; - } - throw new RuntimeException("Cannot convert JsNode to JsStatement: Unexpected node"); - } - - public static JsBlock convertToBlock(JsNode jsNode) { - if (jsNode instanceof JsBlock) { - return (JsBlock)jsNode; - } - JsStatement jsStatement = convertToStatement(jsNode); - return new JsBlock(jsStatement); - } - - public static JsExpression convertToExpression(JsNode jsNode) { - if (jsNode instanceof JsExpression) { - return (JsExpression)jsNode; - } - throw new RuntimeException("Cannot convert JsNode to JsExpression: Unexpected node"); - } - public static JsInvocation call(SourceInfo src, JsExpression target, JsExpression... params) { return (JsInvocation) newInvocation(target, params).setSourceRef(src); } @@ -252,8 +228,38 @@ public class AstUtil { return new JsBinaryOperation(JsBinaryOperator.INOP, propName, obj).setSourceRef(src); } + + // Pavel Talanov public static JsPropertyInitializer newNamedMethod(JsName name, JsFunction function) { JsNameRef methodName = name.makeRef(); return new JsPropertyInitializer(methodName, function); } + + public static JsStatement convertToStatement(JsNode jsNode) { + assert (jsNode instanceof JsExpression) || (jsNode instanceof JsStatement) + : "Unexpected node of type: " + jsNode.getClass().toString(); + if (jsNode instanceof JsExpression) { + return new JsExprStmt((JsExpression) jsNode); + } + return (JsStatement) jsNode; + } + + public static JsBlock convertToBlock(JsNode jsNode) { + if (jsNode instanceof JsBlock) { + return (JsBlock) jsNode; + } + JsStatement jsStatement = convertToStatement(jsNode); + return new JsBlock(jsStatement); + } + + public static JsExpression convertToExpression(JsNode jsNode) { + assert jsNode instanceof JsExpression : "Unexpected node of type: " + jsNode.getClass().toString(); + return (JsExpression) jsNode; + } + + public static JsNameRef thisQualifiedReference(JsName name) { + JsNameRef result = name.makeRef(); + result.setQualifier(new JsThisRef()); + return result; + } } diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java index 345ed389dee..af89e9ea60b 100644 --- a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java @@ -113,7 +113,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { private JsNode translateAsBinaryOperation(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) { JsExpression left = AstUtil.convertToExpression(expression.getLeft().accept(this, context)); JetExpression rightExpression = expression.getRight(); - assert rightExpression != null : "Binary expression should have a right exprssion"; + assert rightExpression != null : "Binary expression should have a right expression"; JsExpression right = AstUtil.convertToExpression(rightExpression.accept(this, context)); JetToken jetOperationToken = (JetToken) expression.getOperationToken(); return new JsBinaryOperation(OperationTranslator.getBinaryOperator(jetOperationToken), left, right); @@ -124,17 +124,34 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull public JsNode visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression, @NotNull TranslationContext context) { + + //TODO: this is only a hack for now + // Problem is that namespace properties do not generate getters and setter actually so they must be referenced + // by name + JsName referencedName = getReferencedName(expression, context); + if (referencedName != null) { + if (context.namespaceScope().ownsName(referencedName)) { + return context.getNamespaceQualifiedReference(referencedName); + } + JsNameRef nameRef = referencedName.makeRef(); + if (expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) { + nameRef.setQualifier(new JsThisRef()); + } + return nameRef; + } + + PropertyAccessTranslator propertyAccessTranslator = new PropertyAccessTranslator(context); + JsInvocation getterCall = propertyAccessTranslator.resolveAsPropertyGet(expression); + if (getterCall != null) { + return getterCall; + } + throw new AssertionError("Undefined name in this scope: " + expression.getReferencedName()); + } + + @Nullable + private JsName getReferencedName(@NotNull JetSimpleNameExpression expression, @NotNull TranslationContext context) { String referencedName = expression.getReferencedName(); - JsName jsName = context.enclosingScope().findExistingName(referencedName); - assert jsName != null : "Undeclared name: " + referencedName; - if (context.namespaceScope().ownsName(jsName)) { - return context.getNamespaceQualifiedReference(jsName); - } - JsNameRef nameRef = jsName.makeRef(); - if (expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) { - nameRef.setQualifier(new JsThisRef()); - } - return nameRef; + return context.enclosingScope().findExistingName(referencedName); } @Override diff --git a/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java b/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java index 9a5d76c6d12..2d1af093534 100644 --- a/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java @@ -39,8 +39,8 @@ public final class FunctionTranslator extends AbstractTranslator { private JsFunction generateFunctionObject(@NotNull JetNamedFunction jetFunction) { JsFunction result = JsFunction.getAnonymousFunctionWithScope (translationContext().getScopeForElement(jetFunction)); - JsNode jsBody = translateBody(jetFunction); List jsParameters = translateParameters(jetFunction.getValueParameters(), result.getScope()); + JsNode jsBody = translateBody(jetFunction); result.setParameters(jsParameters); result.setBody(AstUtil.convertToBlock(jsBody)); return result; diff --git a/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java index 5371702c124..acd9717da51 100644 --- a/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java @@ -13,6 +13,7 @@ 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.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; @@ -37,6 +38,15 @@ public final class PropertyAccessTranslator extends AbstractTranslator { return translateReceiverAndReturnAccessorInvocation(expression, getterName); } + @Nullable + JsInvocation resolveAsPropertyGet(@NotNull JetSimpleNameExpression expression) { + JsName getterName = getPropertyGetterName(expression); + if (getterName == null) { + return null; + } + return AstUtil.newInvocation(AstUtil.thisQualifiedReference(getterName)); + } + @NotNull private JsInvocation translateReceiverAndReturnAccessorInvocation (@NotNull JetDotQualifiedExpression dotQualifiedExpression, @NotNull JsName accessorName) { @@ -49,17 +59,33 @@ public final class PropertyAccessTranslator extends AbstractTranslator { @Nullable public JsInvocation resolveAsPropertySet(@NotNull JetExpression expression) { - if (!(expression instanceof JetDotQualifiedExpression)) { - return null; + if (expression instanceof JetDotQualifiedExpression) { + return resolveAsPropertySet((JetDotQualifiedExpression) expression); } - JetDotQualifiedExpression dotQualifiedExpression = (JetDotQualifiedExpression) expression; + if (expression instanceof JetSimpleNameExpression) { + return resolveAsPropertySet((JetSimpleNameExpression) expression); + } + return null; + } + + @Nullable + private JsInvocation resolveAsPropertySet(@NotNull JetDotQualifiedExpression dotQualifiedExpression) { JetExpression selectorExpression = dotQualifiedExpression.getSelectorExpression(); assert selectorExpression != null : "Selector should not be null."; - JsName getterName = getPropertySetterName(selectorExpression); - if (getterName == null) { + JsName setterName = getPropertySetterName(selectorExpression); + if (setterName == null) { return null; } - return translateReceiverAndReturnAccessorInvocation(dotQualifiedExpression, getterName); + return translateReceiverAndReturnAccessorInvocation(dotQualifiedExpression, setterName); + } + + @Nullable + JsInvocation resolveAsPropertySet(@NotNull JetSimpleNameExpression expression) { + JsName setterName = getPropertySetterName(expression); + if (setterName == null) { + return null; + } + return AstUtil.newInvocation(AstUtil.thisQualifiedReference(setterName)); } @Nullable diff --git a/translator/test/org/jetbrains/k2js/test/BasicClassTest.java b/translator/test/org/jetbrains/k2js/test/BasicClassTest.java index aa6f71a6617..4c58ffa2dd3 100644 --- a/translator/test/org/jetbrains/k2js/test/BasicClassTest.java +++ b/translator/test/org/jetbrains/k2js/test/BasicClassTest.java @@ -35,8 +35,14 @@ public class BasicClassTest extends AbstractClassTest { } // TODO : excluded test +// @Test +// public void constructorWithParameter() throws Exception { +// testFooBoxIsTrue("constructorWithParameter.kt"); +// } + @Test - public void constructorWithParameter() throws Exception { - //testFooBoxIsTrue("constructorWithParameter.kt"); + public void incrementProperty() throws Exception { + //testFooBoxIsTrue("incrementProperty.kt"); + performTest("incrementProperty.kt", "foo", "box", "OK"); } } diff --git a/translator/testFiles/class/cases/incrementProperty.kt b/translator/testFiles/class/cases/incrementProperty.kt new file mode 100644 index 00000000000..a296c7b30e0 --- /dev/null +++ b/translator/testFiles/class/cases/incrementProperty.kt @@ -0,0 +1,16 @@ +namespace foo + +class Slot() { + var vitality: Int = 10000 + + fun increaseVitality(delta: Int) { + vitality = vitality + delta + if (vitality > 65535) vitality = 65535; + } +} + +fun box(): String { + val s = Slot() + s.increaseVitality(1000) + if (s.vitality == 11000) return "OK" else return "fail" +}