diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 7461fcc2c73..70548cd4624 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -11,42 +11,22 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -169,7 +149,7 @@
-
+
@@ -182,20 +162,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -284,19 +251,47 @@
-
+
-
-
+
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -305,14 +300,41 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
@@ -322,60 +344,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -392,7 +360,7 @@
-
+
@@ -496,21 +464,21 @@
@@ -647,7 +615,7 @@
-
+
@@ -669,7 +637,7 @@
-
+
@@ -677,6 +645,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -982,8 +968,74 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -992,14 +1044,14 @@
-
+
-
-
+
+
-
-
-
+
+
+
@@ -1012,59 +1064,45 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
-
+
-
+
-
-
+
+
@@ -1072,80 +1110,9 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1311,11 +1278,11 @@
-
-
-
-
-
+
+
+
+
+
localhost
@@ -1378,7 +1345,7 @@
-
+
@@ -1390,8 +1357,8 @@
-
-
+
+
@@ -1436,7 +1403,7 @@
-
+
@@ -1449,7 +1416,6 @@
-
@@ -1474,6 +1440,7 @@
+
@@ -1483,102 +1450,58 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
-
-
-
-
-
-
+
@@ -1590,12 +1513,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
diff --git a/translator/src/org/jetbrains/k2js/translate/context/Aliaser.java b/translator/src/org/jetbrains/k2js/translate/context/Aliaser.java
index e58cb35e6e1..a3810e0ba7a 100644
--- a/translator/src/org/jetbrains/k2js/translate/context/Aliaser.java
+++ b/translator/src/org/jetbrains/k2js/translate/context/Aliaser.java
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import java.util.HashMap;
import java.util.Map;
+import java.util.Stack;
//TODO: code gets duplicated
public class Aliaser {
@@ -19,54 +20,46 @@ public class Aliaser {
@NotNull
private final Map aliasesForDescriptors = new HashMap();
@NotNull
- private final Map aliasesForThis = new HashMap();
- @NotNull
- private final Map aliasesForReceiver = new HashMap();
+ private final Map> aliasesForThis
+ = new HashMap>();
private Aliaser() {
}
+ //TODO: refactor
@NotNull
public JsNameRef getAliasForThis(@NotNull DeclarationDescriptor descriptor) {
- JsName aliasName = aliasesForThis.get(descriptor.getOriginal());
+ Stack aliasStack = aliasesForThis.get(descriptor.getOriginal());
+ assert !aliasStack.empty();
+ JsName aliasName = aliasStack.peek();
assert aliasName != null : "This " + descriptor.getOriginal() + " doesn't have an alias.";
return aliasName.makeRef();
}
public void setAliasForThis(@NotNull DeclarationDescriptor descriptor, @NotNull JsName alias) {
- aliasesForThis.put(descriptor.getOriginal(), alias);
+ Stack aliasStack = aliasesForThis.get(descriptor.getOriginal());
+ if (aliasStack == null) {
+ aliasStack = new Stack();
+ aliasesForThis.put(descriptor, aliasStack);
+ }
+ aliasStack.push(alias);
}
+ //TODO: make the reference null
public void removeAliasForThis(@NotNull DeclarationDescriptor descriptor) {
- JsName removed = aliasesForThis.remove(descriptor.getOriginal());
- assert removed != null;
+ Stack aliasStack = aliasesForThis.get(descriptor.getOriginal());
+ assert !aliasStack.empty();
+ aliasStack.pop();
}
public boolean hasAliasForThis(@NotNull DeclarationDescriptor descriptor) {
- return (aliasesForThis.containsKey(descriptor.getOriginal()));
+ Stack aliasStack = aliasesForThis.get(descriptor.getOriginal());
+ if (aliasStack == null) {
+ return false;
+ }
+ return (!aliasStack.empty());
}
- @NotNull
- public JsNameRef getAliasForReceiver(@NotNull DeclarationDescriptor descriptor) {
- JsName aliasName = aliasesForReceiver.get(descriptor.getOriginal());
- assert aliasName != null : "This descriptor doesn't have an alias.";
- return aliasName.makeRef();
- }
-
- public void setAliasForReceiver(@NotNull DeclarationDescriptor descriptor, @NotNull JsName alias) {
- aliasesForReceiver.put(descriptor.getOriginal(), alias);
- }
-
- public void removeAliasForReceiver(@NotNull DeclarationDescriptor descriptor) {
- JsName removed = aliasesForReceiver.remove(descriptor.getOriginal());
- assert removed != null;
- }
-
- public boolean hasAliasForReceiver(@NotNull DeclarationDescriptor descriptor) {
- return (aliasesForReceiver.containsKey(descriptor.getOriginal()));
- }
-
-
@NotNull
public JsName getAliasForDeclaration(@NotNull DeclarationDescriptor declaration) {
JsName alias = aliasesForDescriptors.get(declaration.getOriginal());
diff --git a/translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java b/translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java
index c1af24612f7..fcee52116c6 100644
--- a/translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java
+++ b/translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java
@@ -165,9 +165,10 @@ public final class TranslationContext {
return dynamicContext.declareLocalVariable(declarationDescriptor);
}
+ //TODO: consider moving somewhere
@NotNull
public TemporaryVariable newAliasForThis(@NotNull DeclarationDescriptor descriptor) {
- JsExpression thisQualifier = TranslationUtils.getThisQualifier(this, descriptor);
+ JsExpression thisQualifier = TranslationUtils.getThisObject(this, descriptor);
TemporaryVariable aliasForThis = dynamicContext.declareTemporary(thisQualifier);
aliaser().setAliasForThis(descriptor, aliasForThis.name());
return aliasForThis;
diff --git a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
index 55190515182..e0e4955b334 100644
--- a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
+++ b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
@@ -20,6 +20,7 @@ import org.jetbrains.k2js.translate.reference.AccessTranslator;
import org.jetbrains.k2js.translate.reference.CallTranslator;
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
import org.jetbrains.k2js.translate.utils.BindingUtils;
+import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.List;
@@ -373,16 +374,16 @@ public final class ExpressionVisitor extends TranslatorVisitor {
return Translation.functionTranslator(expression, context).translateAsLiteral();
}
+
+ //TODO: refactor
+ //TODO: strange logic. look where it should be applied
@Override
@NotNull
public JsNode visitThisExpression(@NotNull JetThisExpression expression,
@NotNull TranslationContext context) {
DeclarationDescriptor descriptor =
getDescriptorForReferenceExpression(context.bindingContext(), expression.getInstanceReference());
- if (context.aliaser().hasAliasForThis(descriptor)) {
- return context.aliaser().getAliasForThis(descriptor);
- }
- return new JsThisRef();
+ return TranslationUtils.getThisObject(context, descriptor);
}
@Override
@@ -405,4 +406,4 @@ public final class ExpressionVisitor extends TranslatorVisitor {
@NotNull TranslationContext context) {
return TryTranslator.translate(expression, context);
}
-}
+}
\ No newline at end of file
diff --git a/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java
index 1866e963ae8..fcb5162d970 100644
--- a/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java
@@ -3,10 +3,7 @@ package org.jetbrains.k2js.translate.expression;
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.DeclarationDescriptor;
-import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
-import org.jetbrains.jet.lang.descriptors.Modality;
-import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
+import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
@@ -20,8 +17,7 @@ import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
-import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getExpectedReceiverDescriptor;
-import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getExpectedThisDescriptor;
+import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.functionWithScope;
@@ -70,17 +66,17 @@ public final class FunctionTranslator extends AbstractTranslator {
return new JsPropertyInitializer(functionName.makeRef(), function);
}
-
//TODO: refactor
@NotNull
public JsExpression translateAsLiteral() {
- DeclarationDescriptor expectedThisDescriptor = getExpectedThisDescriptor(descriptor);
- if (expectedThisDescriptor == null) {
+ assert getExpectedThisDescriptor(descriptor) == null;
+ ClassDescriptor containingClass = getContainingClass(descriptor);
+ if (containingClass == null) {
return generateFunctionObject();
}
- TemporaryVariable aliasForThis = context().newAliasForThis(expectedThisDescriptor);
+ TemporaryVariable aliasForThis = context().newAliasForThis(containingClass);
JsFunction function = generateFunctionObject();
- context().removeAliasForThis(expectedThisDescriptor);
+ context().removeAliasForThis(containingClass);
return AstUtil.newSequence(aliasForThis.assignmentExpression(), function);
}
@@ -95,14 +91,16 @@ public final class FunctionTranslator extends AbstractTranslator {
private void restoreContext() {
if (isExtensionFunction()) {
- functionBodyContext.removeAliasForThis(getExpectedReceiverDescriptor(descriptor));
+ DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(descriptor);
+ assert expectedReceiverDescriptor != null : "Extension functions should always have receiver descriptors.";
+ functionBodyContext.aliaser().removeAliasForThis(expectedReceiverDescriptor);
}
}
+ @NotNull
private JsFunction createFunctionObject() {
if (isDeclaration()) {
- return functionWithScope
- (context().getScopeForElement((JetDeclaration) functionDeclaration));
+ return functionWithScope(context().getScopeForElement((JetDeclaration) functionDeclaration));
}
if (isLiteral()) {
//TODO: look into
@@ -147,8 +145,8 @@ public final class FunctionTranslator extends AbstractTranslator {
List statements = bodyBlock.getStatements();
int lastIndex = statements.size() - 1;
JsStatement lastStatement = statements.get(lastIndex);
- statements.set(lastIndex,
- new JsReturn(AstUtil.extractExpressionFromStatement(lastStatement)));
+ JsReturn returnStatement = new JsReturn(AstUtil.extractExpressionFromStatement(lastStatement));
+ statements.set(lastIndex, returnStatement);
}
@NotNull
@@ -186,7 +184,8 @@ public final class FunctionTranslator extends AbstractTranslator {
//TODO: dont do this
JsName receiver = functionBodyContext.jsScope().declareName(RECEIVER_PARAMETER_NAME);
DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(descriptor);
- context().aliaser().setAliasForReceiver(expectedReceiverDescriptor, receiver);
+ assert expectedReceiverDescriptor != null;
+ context().aliaser().setAliasForThis(expectedReceiverDescriptor, receiver);
jsParameters.add(new JsParameter(receiver));
}
}
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
index a572335a530..a4d1b3bfd2e 100644
--- a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
@@ -12,19 +12,18 @@ import org.jetbrains.jet.lang.resolve.calls.DefaultValueArgument;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument;
+import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
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.intrinsic.FunctionIntrinsic;
-import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.*;
import static com.google.dart.compiler.util.AstUtil.not;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
-import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getVariableDescriptorForVariableAsFunction;
-import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isConstructorDescriptor;
+import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
@@ -187,7 +186,7 @@ public final class CallTranslator extends AbstractTranslator {
}
@Nullable
- private final JsExpression receiver;
+ private JsExpression receiver;
@NotNull
private final List arguments;
@@ -227,11 +226,19 @@ public final class CallTranslator extends AbstractTranslator {
return methodCall();
}
+ //TODO: refactor
@NotNull
private JsExpression extensionFunctionCall() {
List argumentList = new ArrayList();
+ if (receiver == null) {
+ DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(descriptor);
+ assert expectedReceiverDescriptor != null;
+ receiver = getThisObject(context(), expectedReceiverDescriptor);
+ }
argumentList.add(receiver);
argumentList.addAll(arguments);
+ //Now the rest of the code can work as if it was simple method invocation
+ receiver = null;
return AstUtil.newInvocation(calleeReference(), argumentList);
}
@@ -263,7 +270,7 @@ public final class CallTranslator extends AbstractTranslator {
@NotNull
private JsExpression calleeReference() {
- if (DescriptorUtils.isVariableDescriptor(descriptor)) {
+ if (isVariableDescriptor(descriptor)) {
//TODO: write tests on this cases
VariableDescriptor variableDescriptor =
getVariableDescriptorForVariableAsFunction((VariableAsFunctionDescriptor) descriptor);
@@ -282,23 +289,26 @@ public final class CallTranslator extends AbstractTranslator {
@NotNull
private JsExpression qualifiedMethodReference(@NotNull DeclarationDescriptor descriptor) {
- JsExpression methodReference = ReferenceTranslator.translateAsLocalNameReference(descriptor, context());
- //TODO: should insert checks for IMPLICIT RECEIVER
- if (isExtensionFunction()) {
- return extensionFunctionReference(methodReference);
- } else if (receiver != null) {
- AstUtil.setQualifier(methodReference, receiver);
+ JsExpression thisObject = thisObject();
+ if (thisObject == null) {
+ return ReferenceTranslator.translateAsFQReference(descriptor, context());
}
+ JsExpression methodReference = ReferenceTranslator.translateAsLocalNameReference(descriptor, context());
+ AstUtil.setQualifier(methodReference, thisObject);
return methodReference;
}
- @NotNull
- private JsExpression extensionFunctionReference(@NotNull JsExpression methodReference) {
- JsExpression qualifier = TranslationUtils.getImplicitReceiver(context(), resolvedCall.getReceiverArgument());
- if (qualifier != null) {
- AstUtil.setQualifier(methodReference, qualifier);
+ @Nullable
+ private JsExpression thisObject() {
+ if (receiver != null) {
+ return receiver;
}
- return methodReference;
+ ReceiverDescriptor thisObject = resolvedCall.getThisObject();
+ if (!thisObject.exists()) {
+ return null;
+ }
+ DeclarationDescriptor expectedThisDescriptor = getDeclarationDescriptorForReceiver(thisObject);
+ return TranslationUtils.getThisObject(context(), expectedThisDescriptor);
}
@NotNull
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/ReferenceTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/ReferenceTranslator.java
index 629a702b766..571cd1a4592 100644
--- a/translator/src/org/jetbrains/k2js/translate/reference/ReferenceTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/reference/ReferenceTranslator.java
@@ -31,8 +31,9 @@ public final class ReferenceTranslator {
@NotNull
public static JsExpression translateAsFQReference(@NotNull DeclarationDescriptor referencedDescriptor,
@NotNull TranslationContext context) {
-
- assert context.hasQualifierForDescriptor(referencedDescriptor);
+ if (!context.hasQualifierForDescriptor(referencedDescriptor)) {
+ return translateAsLocalNameReference(referencedDescriptor, context);
+ }
JsName referencedName = context.getNameForDescriptor(referencedDescriptor);
JsExpression qualifier = context.getQualifierForDescriptor(referencedDescriptor);
return AstUtil.qualified(referencedName, qualifier);
diff --git a/translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java
index 65fe643f690..fead9bfe34e 100644
--- a/translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java
+++ b/translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java
@@ -140,11 +140,17 @@ public final class DescriptorUtils {
//TODO: why callable descriptor
@Nullable
- public static DeclarationDescriptor getExpectedThisDescriptor(@NotNull CallableDescriptor functionDescriptor) {
- ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
- if (!receiverParameter.exists()) {
+ public static DeclarationDescriptor getExpectedThisDescriptor(@NotNull CallableDescriptor callableDescriptor) {
+ ReceiverDescriptor expectedThisObject = callableDescriptor.getExpectedThisObject();
+ if (!expectedThisObject.exists()) {
return null;
}
+ return getDeclarationDescriptorForReceiver(expectedThisObject);
+ }
+
+ @NotNull
+ public static DeclarationDescriptor getDeclarationDescriptorForReceiver
+ (@NotNull ReceiverDescriptor receiverParameter) {
DeclarationDescriptor declarationDescriptor =
receiverParameter.getType().getConstructor().getDeclarationDescriptor();
//TODO: WHY assert?
@@ -153,14 +159,25 @@ public final class DescriptorUtils {
}
@Nullable
- public static DeclarationDescriptor getExpectedReceiverDescriptor(@NotNull CallableDescriptor functionDescriptor) {
- ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
+ public static DeclarationDescriptor getExpectedReceiverDescriptor(@NotNull CallableDescriptor callableDescriptor) {
+ ReceiverDescriptor receiverParameter = callableDescriptor.getReceiverParameter();
if (!receiverParameter.exists()) {
return null;
}
- DeclarationDescriptor declarationDescriptor =
- functionDescriptor.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor();
- assert declarationDescriptor != null;
- return declarationDescriptor.getOriginal();
+ return getDeclarationDescriptorForReceiver(receiverParameter);
}
+
+ //TODO: maybe we have similar routine
+ @Nullable
+ public static ClassDescriptor getContainingClass(@NotNull DeclarationDescriptor descriptor) {
+ DeclarationDescriptor containing = descriptor.getContainingDeclaration();
+ while (containing != null) {
+ if (containing instanceof ClassDescriptor) {
+ return (ClassDescriptor) containing;
+ }
+ containing = containing.getContainingDeclaration();
+ }
+ return null;
+ }
+
}
diff --git a/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java
index e82efdec090..8acfc2eb227 100644
--- a/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java
+++ b/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java
@@ -4,6 +4,7 @@ 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.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
@@ -17,6 +18,7 @@ import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
+import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getExpectedReceiverDescriptor;
/**
* @author Pavel Talanov
@@ -108,16 +110,27 @@ public final class TranslationUtils {
return reference;
}
+ //TODO: refactor
@NotNull
- public static JsExpression getThisQualifier(@NotNull TranslationContext context,
- @NotNull DeclarationDescriptor correspondingDeclaration) {
- JsExpression qualifier;
- if (context.aliaser().hasAliasForThis(correspondingDeclaration)) {
- qualifier = context.aliaser().getAliasForThis(correspondingDeclaration);
- } else {
- qualifier = new JsThisRef();
+ public static JsExpression getThisObject(@NotNull TranslationContext context,
+ @NotNull DeclarationDescriptor correspondingDeclaration) {
+ JsExpression thisRef = null;
+ if (correspondingDeclaration instanceof ClassDescriptor) {
+ if (context.aliaser().hasAliasForThis(correspondingDeclaration)) {
+ thisRef = context.aliaser().getAliasForThis(correspondingDeclaration);
+ }
}
- return qualifier;
+ if (correspondingDeclaration instanceof FunctionDescriptor) {
+ DeclarationDescriptor receiverDescriptor = getExpectedReceiverDescriptor((FunctionDescriptor) correspondingDeclaration);
+ assert receiverDescriptor != null;
+ if (context.aliaser().hasAliasForThis(receiverDescriptor)) {
+ thisRef = context.aliaser().getAliasForThis(receiverDescriptor);
+ }
+ }
+ if (thisRef != null) {
+ return thisRef;
+ }
+ return new JsThisRef();
}
@NotNull
@@ -196,7 +209,7 @@ public final class TranslationUtils {
DeclarationDescriptor correspondingDescriptor =
receiverDescriptor.getType().getConstructor().getDeclarationDescriptor();
assert correspondingDescriptor != null;
- return context.aliaser().getAliasForReceiver(correspondingDescriptor);
+ return context.aliaser().getAliasForThis(correspondingDescriptor);
}
@Nullable
diff --git a/translator/test/org/jetbrains/k2js/test/ExtensionFunctionTest.java b/translator/test/org/jetbrains/k2js/test/ExtensionFunctionTest.java
index 92ca95609ba..7e17b28c870 100644
--- a/translator/test/org/jetbrains/k2js/test/ExtensionFunctionTest.java
+++ b/translator/test/org/jetbrains/k2js/test/ExtensionFunctionTest.java
@@ -52,4 +52,9 @@ public final class ExtensionFunctionTest extends TranslationTest {
public void extensionInsideFunctionLiteral() throws Exception {
testFooBoxIsTrue("extensionInsideFunctionLiteral.kt");
}
+
+ @Test
+ public void genericExtension() throws Exception {
+ testFooBoxIsOk("generic.kt");
+ }
}
diff --git a/translator/testFiles/examples/cases/enclosingThis.jet b/translator/testFiles/examples/cases/enclosingThis.jet
deleted file mode 100644
index d227b3a2cc9..00000000000
--- a/translator/testFiles/examples/cases/enclosingThis.jet
+++ /dev/null
@@ -1,12 +0,0 @@
-class Point(val x:Int, val y:Int) {
- fun mul() : (scalar:Int)->Point {
- return { (scalar:Int):Point -> Point(x * scalar, y * scalar) }
- }
-}
-
-val m = Point(2, 3).mul() : (scalar:Int)->Point
-
-fun box() : String {
- val answer = m(5)
- return if (answer.x == 10 && answer.y == 15) "OK" else "FAIL"
-}
diff --git a/translator/testFiles/extensionFunction/cases/generic.kt b/translator/testFiles/extensionFunction/cases/generic.kt
new file mode 100644
index 00000000000..d13147d5d22
--- /dev/null
+++ b/translator/testFiles/extensionFunction/cases/generic.kt
@@ -0,0 +1,24 @@
+package foo
+
+import java.util.*
+
+fun ArrayList.findAll(predicate: (T) -> Boolean): ArrayList {
+ val result = ArrayList()
+ for(val t in this) {
+ if (predicate(t)) result.add(t)
+ }
+ return result
+}
+
+
+fun box(): String {
+ val list: ArrayList = ArrayList()
+
+ list.add(2)
+ list.add(3)
+ list.add(5)
+
+
+ val m: ArrayList = list.findAll({(name: Int) -> name < 4})
+ return if (m.size() == 2) "OK" else "fail"
+}