diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 835a0ad7a54..905da820aa1 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,33 +5,12 @@ - - - - - - - + - - - - - - - - - - - - - - - - - - + + + @@ -74,8 +53,8 @@ - + - + - + @@ -246,19 +225,10 @@ - - - - - - - - - - + @@ -309,10 +279,10 @@ - + - + @@ -320,95 +290,106 @@ + + + + + + + + + - - - - - - - - - - + - + - - + + - + + + + + + + + + + + + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + @@ -435,9 +416,6 @@ @@ -659,7 +640,55 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - + + + + + localhost @@ -1221,7 +1213,7 @@ - + @@ -1264,7 +1256,7 @@ @@ -1311,120 +1303,120 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java index d9654503ba7..dbf7195bf64 100644 --- a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java @@ -7,14 +7,14 @@ import com.google.dart.compiler.backend.js.ast.JsNew; 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.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic; import org.jetbrains.k2js.translate.utils.TranslationUtils; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -29,12 +29,15 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.*; */ public final class CallTranslator extends AbstractTranslator { - public static boolean isFunctionCall(@NotNull JetOperationExpression expression, - @NotNull TranslationContext context) { - DeclarationDescriptor descriptor = getDescriptorForReferenceExpression - (context.bindingContext(), expression.getOperation()); - return (descriptor instanceof FunctionDescriptor); - } + + //TODO: remove? + +// public static boolean isFunctionCall(@NotNull JetOperationExpression expression, +// @NotNull TranslationContext context) { +// DeclarationDescriptor descriptor = getDescriptorForReferenceExpression +// (context.bindingContext(), expression.getOperation()); +// return (descriptor instanceof FunctionDescriptor); +// } public static JsExpression translate(@NotNull JetUnaryExpression unaryExpression, @NotNull TranslationContext context) { @@ -111,7 +114,16 @@ public final class CallTranslator extends AbstractTranslator { } @NotNull - private JsNameRef calleeReference() { + private JsExpression calleeReference() { + //TODO: refactor + if (descriptor instanceof VariableAsFunctionDescriptor) { + VariableDescriptor variableDescriptor = ((VariableAsFunctionDescriptor) descriptor).getVariableDescriptor(); + if (variableDescriptor instanceof PropertyDescriptor) { + PropertyGetterDescriptor getter = ((PropertyDescriptor) variableDescriptor).getGetter(); + assert getter != null; + return (new CallTranslator(null, new ArrayList(), getter, context())).translate(); + } + } if (context().isDeclared(descriptor)) { return qualifiedMethodReference(); } diff --git a/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java index cdf398f12ae..3d2c7dca458 100644 --- a/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java @@ -16,7 +16,8 @@ import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.utils.BindingUtils; -import org.jetbrains.k2js.translate.utils.PsiUtils; + +import static org.jetbrains.k2js.translate.utils.PsiUtils.getSelectorAsSimpleName; /** * @author Talanov Pavel @@ -67,7 +68,7 @@ public final class PropertyAccessTranslator extends AccessTranslator { public static boolean canBePropertyGetterCall(@NotNull JetQualifiedExpression expression, @NotNull TranslationContext context) { - JetSimpleNameExpression selector = PsiUtils.getSelectorAsSimpleName(expression); + JetSimpleNameExpression selector = getSelectorAsSimpleName(expression); if (selector == null) { return false; } @@ -95,9 +96,6 @@ public final class PropertyAccessTranslator extends AccessTranslator { return canBePropertyGetterCall(expression, context); } - - @NotNull - private final JetSimpleNameExpression expression; @Nullable private final JetExpression qualifier; @NotNull @@ -106,30 +104,28 @@ public final class PropertyAccessTranslator extends AccessTranslator { private PropertyAccessTranslator(@NotNull JetSimpleNameExpression simpleName, @NotNull TranslationContext context) { super(context); - this.expression = simpleName; this.qualifier = null; - this.propertyDescriptor = getNotNullPropertyDescriptor(); + this.propertyDescriptor = getPropertyDescriptor(simpleName); } private PropertyAccessTranslator(@NotNull JetQualifiedExpression qualifiedExpression, @NotNull TranslationContext context) { super(context); - this.expression = getNotNullSelector(qualifiedExpression); this.qualifier = qualifiedExpression.getReceiverExpression(); - this.propertyDescriptor = getNotNullPropertyDescriptor(); + this.propertyDescriptor = getPropertyDescriptor(getNotNullSelector(qualifiedExpression)); } @Override @NotNull public JsExpression translateAsGet() { - JsName getterName = getNotNullGetterName(); + JsName getterName = getGetterName(); return qualifiedAccessorInvocation(getterName); } @Override @NotNull public JsExpression translateAsSet(@NotNull JsExpression toSetTo) { - JsName setterName = getNotNullSetterName(); + JsName setterName = getSetterName(); JsInvocation setterCall = qualifiedAccessorInvocation(setterName); setterCall.getArguments().add(toSetTo); return setterCall; @@ -155,77 +151,42 @@ public final class PropertyAccessTranslator extends AccessTranslator { @NotNull private static JetSimpleNameExpression getNotNullSelector(@NotNull JetQualifiedExpression qualifiedExpression) { - JetSimpleNameExpression selectorExpression = PsiUtils.getSelectorAsSimpleName(qualifiedExpression); + JetSimpleNameExpression selectorExpression = getSelectorAsSimpleName(qualifiedExpression); assert selectorExpression != null : MESSAGE; return selectorExpression; } @NotNull - private JsName getNotNullGetterName() { - JsName getterName = getNullableGetterName(); - assert getterName != null : MESSAGE; - return getterName; - } - - @Nullable - private JsName getNullableGetterName() { + private JsName getGetterName() { PropertyGetterDescriptor getter = getGetterDescriptor(); - - if (getter == null) return null; - return context().getNameForDescriptor(getter); } - @Nullable + @NotNull private PropertyGetterDescriptor getGetterDescriptor() { - PropertyDescriptor property = getNullablePropertyDescriptor(); - if (property == null) { - return null; - } - PropertyGetterDescriptor getter = property.getGetter(); - if (getter == null) { - return null; - } + PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); + assert getter != null; return getter; } @NotNull - private JsName getNotNullSetterName() { - JsName setterName = getNullableSetterName(); - assert setterName != null : MESSAGE; - return setterName; - } - - @Nullable - private JsName getNullableSetterName() { + private JsName getSetterName() { PropertySetterDescriptor setter = getSetterDescriptor(); - - if (setter == null) return null; - return context().getNameForDescriptor(setter); } - @Nullable + @NotNull private PropertySetterDescriptor getSetterDescriptor() { - PropertyDescriptor property = getNullablePropertyDescriptor(); - if (property == null) { - return null; - } - PropertySetterDescriptor setter = property.getSetter(); - if (setter == null) { - return null; - } + PropertySetterDescriptor setter = propertyDescriptor.getSetter(); + assert setter != null; return setter; } - @Nullable - private PropertyDescriptor getNullablePropertyDescriptor() { - return BindingUtils.getPropertyDescriptorForSimpleName(context().bindingContext(), expression); - } @NotNull - private PropertyDescriptor getNotNullPropertyDescriptor() { - PropertyDescriptor propertyDescriptor = getNullablePropertyDescriptor(); + private PropertyDescriptor getPropertyDescriptor(@NotNull JetSimpleNameExpression expression) { + PropertyDescriptor propertyDescriptor = + BindingUtils.getPropertyDescriptorForSimpleName(context().bindingContext(), expression); assert propertyDescriptor != null; return propertyDescriptor; } diff --git a/translator/test/org/jetbrains/k2js/test/FunctionTest.java b/translator/test/org/jetbrains/k2js/test/FunctionTest.java index b5155e10af0..96bfe89d54d 100644 --- a/translator/test/org/jetbrains/k2js/test/FunctionTest.java +++ b/translator/test/org/jetbrains/k2js/test/FunctionTest.java @@ -54,5 +54,10 @@ public class FunctionTest extends AbstractExpressionTest { testFooBoxIsOk("closureWithParameterAndBoxing.jet"); } + @Test + public void enclosingThis() throws Exception { + testFunctionOutput("enclosingThis.jet", "Anonymous", "box", "OK"); + } + } diff --git a/translator/testFiles/expression/function/cases/enclosingThis.jet b/translator/testFiles/expression/function/cases/enclosingThis.jet new file mode 100644 index 00000000000..93ae48c580f --- /dev/null +++ b/translator/testFiles/expression/function/cases/enclosingThis.jet @@ -0,0 +1,12 @@ +class Point(val x:Int, val y:Int) { + fun mul() : fun (scalar:Int):Point { + return { (scalar:Int):Point => Point(x * scalar, y * scalar) } + } +} + +val m = Point(2, 3).mul() : fun (scalar:Int):Point + +fun box() : String { + val answer = m(5) + return if (answer.x == 10 && answer.y == 15) "OK" else "FAIL" +}