KT-1361: "this" is not treated correctly when object is created.

This commit is contained in:
pTalanov
2012-03-13 14:30:26 +04:00
parent 50a42a2f07
commit 15437cbbf6
5 changed files with 113 additions and 5 deletions
@@ -73,6 +73,14 @@ public final class MiscTest extends AbstractExpressionTest {
checkFooBoxIsOk("KT-740-2.kt");
}
public void testKt1361_1() throws Exception {
checkFooBoxIsTrue("KT-1361-1.kt");
}
public void testKt1361_2() throws Exception {
checkFooBoxIsTrue("KT-1361-2.kt");
}
//TODO: depends on KT-1198
//TODO: look into BindingContext.VARIABLE_REASSIGNMENT
// public void testKt740_3() throws Exception {
@@ -24,7 +24,9 @@ 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.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
@@ -33,11 +35,12 @@ import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.ArrayList;
import java.util.List;
import static com.google.dart.compiler.util.AstUtil.newSequence;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.findAncestorClass;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getSuperclassDescriptors;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getPrimaryConstructorParameters;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getThisObject;
/**
* @author Pavel Talanov
@@ -57,7 +60,13 @@ public final class ClassTranslator extends AbstractTranslator {
@NotNull
public static JsInvocation generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
@NotNull TranslationContext context) {
return (new ClassTranslator(classDeclaration, context)).translateClass();
return (new ClassTranslator(classDeclaration, context)).translateClassOrObjectCreation();
}
@NotNull
public static JsExpression generateObjectLiteralExpression(@NotNull JetObjectLiteralExpression objectLiteralExpression,
@NotNull TranslationContext context) {
return (new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), context)).translateObjectLiteralExpression();
}
@NotNull
@@ -76,7 +85,25 @@ public final class ClassTranslator extends AbstractTranslator {
}
@NotNull
private JsInvocation translateClass() {
private JsExpression translateObjectLiteralExpression() {
ClassDescriptor containingClass = getContainingClass(descriptor);
if (containingClass == null) {
return translateClassOrObjectCreation();
}
return translateAsObjectCreationExpressionWithEnclosingThisSaved(containingClass);
}
@NotNull
private JsExpression translateAsObjectCreationExpressionWithEnclosingThisSaved(@NotNull ClassDescriptor containingClass) {
TemporaryVariable thisAlias = context().declareTemporary(getThisObject(context(), containingClass));
aliaser().setAliasForThis(containingClass, thisAlias.name());
JsBinaryOperation result = newSequence(thisAlias.assignmentExpression(), translateClassOrObjectCreation());
aliaser().removeAliasForThis(containingClass);
return result;
}
@NotNull
private JsInvocation translateClassOrObjectCreation() {
JsInvocation jsClassDeclaration = classCreateMethodInvocation();
addSuperclassReferences(jsClassDeclaration);
addClassOwnDeclarations(jsClassDeclaration);
@@ -399,7 +399,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
public JsNode visitObjectLiteralExpression(@NotNull JetObjectLiteralExpression expression,
@NotNull TranslationContext context) {
return ClassTranslator.generateClassCreationExpression(expression.getObjectDeclaration(), context);
return ClassTranslator.generateObjectLiteralExpression(expression, context);
}
@Override
@@ -0,0 +1,21 @@
//This is not treated correctly when object is created.
package foo
class B {
val d = true
fun f() : Boolean {
val c = object {
fun foo() : Boolean {
return d
}
}
return c.foo()
}
}
fun box() : Boolean {
return B().f()
}
@@ -0,0 +1,52 @@
package foo
class Data(val rawData : Array<Int>, val width : Int, val height : Int) {
fun get(x : Int, y : Int) : ColorLike {
return object : ColorLike {
override val red: Int = rawData[(y * width + x) * 4 + 0];
override val green: Int = rawData[(y * width + x) * 4 + 1];
override val blue: Int = rawData[(y * width + x) * 4 + 2];
}
}
fun set(x : Int, y : Int, color : ColorLike) {
rawData[(y * width + x) * 4 + 0] = color.red;
rawData[(y * width + x) * 4 + 1] = color.green;
rawData[(y * width + x) * 4 + 2] = color.blue;
}
fun each(block : (x : Int, y : Int)->Unit) {
for (x in 0..width - 1) {
for (y in 0..height - 1) {
block(x, y)
}
}
}
}
class Color(r : Int, g : Int, b : Int) : ColorLike {
override val red: Int = r
override val green: Int = g
override val blue: Int = b
}
trait ColorLike {
val red : Int;
val green : Int;
val blue : Int;
}
fun box() : Boolean {
val d = Data(Array(4) {0}, 1, 1)
if (d[0, 0].red != 0) {
return false
}
if (d[0, 0].green != 0) {
return false
}
if (d[0, 0].blue != 0) {
return false
}
return true
}