work on safe acess
implement callType better KotlinPropertyAccessTranslator
This commit is contained in:
@@ -114,7 +114,6 @@
|
|||||||
this.$dragOff = new creatures.Vector_0(0, 0);
|
this.$dragOff = new creatures.Vector_0(0, 0);
|
||||||
this.$interval = 1000 / 30;
|
this.$interval = 1000 / 30;
|
||||||
{
|
{
|
||||||
var tmp$5;
|
|
||||||
var tmp$4;
|
var tmp$4;
|
||||||
var tmp$3;
|
var tmp$3;
|
||||||
var tmp$2;
|
var tmp$2;
|
||||||
@@ -170,15 +169,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
$(this.get_canvas()).resize((tmp$4 = this , function () {
|
setInterval((tmp$4 = this , function () {
|
||||||
{
|
{
|
||||||
tmp$4.updateSize();
|
tmp$4.draw();
|
||||||
}
|
|
||||||
}
|
|
||||||
));
|
|
||||||
setInterval((tmp$5 = this , function () {
|
|
||||||
{
|
|
||||||
tmp$5.draw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
), this.get_interval());
|
), this.get_interval());
|
||||||
@@ -217,11 +210,6 @@
|
|||||||
this.$dragOff = tmp$0;
|
this.$dragOff = tmp$0;
|
||||||
}, get_interval:function () {
|
}, get_interval:function () {
|
||||||
return this.$interval;
|
return this.$interval;
|
||||||
}, updateSize:function () {
|
|
||||||
{
|
|
||||||
this.set_width(this.get_canvas().width);
|
|
||||||
this.set_height(this.get_canvas().height);
|
|
||||||
}
|
|
||||||
}, mousePos_0:function (e) {
|
}, mousePos_0:function (e) {
|
||||||
{
|
{
|
||||||
var offset = new creatures.Vector_0(0, 0);
|
var offset = new creatures.Vector_0(0, 0);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.jetbrains.k2js.translate.operation.IncrementTranslator;
|
|||||||
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
||||||
import org.jetbrains.k2js.translate.reference.AccessTranslator;
|
import org.jetbrains.k2js.translate.reference.AccessTranslator;
|
||||||
import org.jetbrains.k2js.translate.reference.CallTranslator;
|
import org.jetbrains.k2js.translate.reference.CallTranslator;
|
||||||
|
import org.jetbrains.k2js.translate.reference.QualifiedExpressionTranslator;
|
||||||
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.expression.QualifiedExpressionTranslator;
|
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package org.jetbrains.k2js.translate.reference;
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsConditional;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNullLiteral;
|
||||||
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression;
|
||||||
|
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||||
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
|
|
||||||
|
import static com.google.dart.compiler.util.AstUtil.newSequence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pavel Talanov
|
||||||
|
*/
|
||||||
|
public enum CallType {
|
||||||
|
SAFE {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
JsExpression mutateSelector(@NotNull JsExpression selector, @NotNull TranslationContext context) {
|
||||||
|
TemporaryVariable temporaryVariable = context.declareTemporary(selector);
|
||||||
|
return newSequence(temporaryVariable.assignmentExpression(), temporaryVariable.nameReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
JsExpression mutateExpression(@NotNull JsExpression mutatedSelector,
|
||||||
|
@NotNull JsExpression expressionWithMutatedSelector,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
JsNullLiteral nullLiteral = context.program().getNullLiteral();
|
||||||
|
//TODO: find similar not null checks
|
||||||
|
JsBinaryOperation notNullCheck = AstUtil.notEqual(expressionWithMutatedSelector, nullLiteral);
|
||||||
|
return new JsConditional(notNullCheck, expressionWithMutatedSelector, nullLiteral);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//TODO: bang qualifier is not implemented in frontend for now
|
||||||
|
// BANG,
|
||||||
|
NORMAL {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
JsExpression mutateSelector(@NotNull JsExpression selector, @NotNull TranslationContext context) {
|
||||||
|
// do not mutate
|
||||||
|
return selector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
JsExpression mutateExpression(@NotNull JsExpression mutatedSelector,
|
||||||
|
@NotNull JsExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
// do not mutate
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
abstract JsExpression mutateSelector(@NotNull JsExpression selector, @NotNull TranslationContext context);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
abstract JsExpression mutateExpression(@NotNull JsExpression mutatedSelector,
|
||||||
|
@NotNull JsExpression expression,
|
||||||
|
@NotNull TranslationContext context);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static CallType getCallTypeForQualifierExpression(@NotNull JetQualifiedExpression expression) {
|
||||||
|
if (expression instanceof JetSafeQualifiedExpression) {
|
||||||
|
return SAFE;
|
||||||
|
}
|
||||||
|
assert expression instanceof JetDotQualifiedExpression;
|
||||||
|
return NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+3
-28
@@ -1,8 +1,6 @@
|
|||||||
package org.jetbrains.k2js.translate.reference;
|
package org.jetbrains.k2js.translate.reference;
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
@@ -11,8 +9,6 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.backingFieldReference;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
* <p/>
|
* <p/>
|
||||||
@@ -24,36 +20,24 @@ public final class KotlinPropertyAccessTranslator extends PropertyAccessTranslat
|
|||||||
private final JsExpression qualifier;
|
private final JsExpression qualifier;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final PropertyDescriptor propertyDescriptor;
|
private final PropertyDescriptor propertyDescriptor;
|
||||||
private final boolean isBackingFieldAccess;
|
|
||||||
@NotNull
|
@NotNull
|
||||||
ResolvedCall<?> resolvedCall;
|
ResolvedCall<?> resolvedCall;
|
||||||
|
|
||||||
//TODO: too many params in constructor
|
//TODO: too many params in constructor
|
||||||
/*package*/ KotlinPropertyAccessTranslator(@NotNull PropertyDescriptor descriptor,
|
/*package*/ KotlinPropertyAccessTranslator(@NotNull PropertyDescriptor descriptor,
|
||||||
@Nullable JsExpression qualifier,
|
@Nullable JsExpression qualifier,
|
||||||
boolean isBackingFieldAccess,
|
|
||||||
@NotNull ResolvedCall<?> resolvedCall,
|
@NotNull ResolvedCall<?> resolvedCall,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.qualifier = qualifier;
|
this.qualifier = qualifier;
|
||||||
this.propertyDescriptor = descriptor.getOriginal();
|
this.propertyDescriptor = descriptor.getOriginal();
|
||||||
this.isBackingFieldAccess = isBackingFieldAccess;
|
|
||||||
this.resolvedCall = resolvedCall;
|
this.resolvedCall = resolvedCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression translateAsGet() {
|
public JsExpression translateAsGet() {
|
||||||
if (isBackingFieldAccess) {
|
return getterCall();
|
||||||
return backingFieldGet();
|
|
||||||
} else {
|
|
||||||
return getterCall();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsExpression backingFieldGet() {
|
|
||||||
return backingFieldReference(context(), propertyDescriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -64,11 +48,8 @@ public final class KotlinPropertyAccessTranslator extends PropertyAccessTranslat
|
|||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
|
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
|
||||||
if (isBackingFieldAccess) {
|
|
||||||
return backingFieldAssignment(toSetTo);
|
return setterCall(toSetTo);
|
||||||
} else {
|
|
||||||
return setterCall(toSetTo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -76,10 +57,4 @@ public final class KotlinPropertyAccessTranslator extends PropertyAccessTranslat
|
|||||||
return CallTranslator.translate(qualifier, Arrays.asList(toSetTo),
|
return CallTranslator.translate(qualifier, Arrays.asList(toSetTo),
|
||||||
resolvedCall, propertyDescriptor.getSetter(), context());
|
resolvedCall, propertyDescriptor.getSetter(), context());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsExpression backingFieldAssignment(@NotNull JsExpression toSetTo) {
|
|
||||||
JsNameRef backingFieldReference = backingFieldReference(context(), propertyDescriptor);
|
|
||||||
return AstUtil.newAssignment(backingFieldReference, toSetTo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-13
@@ -29,8 +29,7 @@ public abstract class PropertyAccessTranslator extends AccessTranslator {
|
|||||||
if (isNativeObject(descriptor)) {
|
if (isNativeObject(descriptor)) {
|
||||||
return new NativePropertyAccessTranslator(descriptor, /*qualifier = */ null, context);
|
return new NativePropertyAccessTranslator(descriptor, /*qualifier = */ null, context);
|
||||||
} else {
|
} else {
|
||||||
return new KotlinPropertyAccessTranslator(descriptor, /*qualifier = */ null, /*backingFieldAccess = */ false,
|
return new KotlinPropertyAccessTranslator(descriptor, /*qualifier = */ null, resolvedCall, context);
|
||||||
resolvedCall, context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,13 +38,11 @@ public abstract class PropertyAccessTranslator extends AccessTranslator {
|
|||||||
@Nullable JsExpression qualifier,
|
@Nullable JsExpression qualifier,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(expression, context);
|
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(expression, context);
|
||||||
if (isNativeObject(propertyDescriptor)) {
|
if (isNativeObject(propertyDescriptor) || isBackingFieldReference(expression)) {
|
||||||
return new NativePropertyAccessTranslator(propertyDescriptor, qualifier, context);
|
return new NativePropertyAccessTranslator(propertyDescriptor, qualifier, context);
|
||||||
}
|
}
|
||||||
ResolvedCall<?> resolvedCall = getResolvedCall(context.bindingContext(), expression);
|
ResolvedCall<?> resolvedCall = getResolvedCall(context.bindingContext(), expression);
|
||||||
boolean backingFieldAccess = isBackingFieldReference(expression);
|
return new KotlinPropertyAccessTranslator(propertyDescriptor, qualifier, resolvedCall, context);
|
||||||
return new KotlinPropertyAccessTranslator(propertyDescriptor, qualifier,
|
|
||||||
backingFieldAccess, resolvedCall, context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -105,13 +102,6 @@ public abstract class PropertyAccessTranslator extends AccessTranslator {
|
|||||||
return canBePropertyGetterCall(expression, context);
|
return canBePropertyGetterCall(expression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CallType {
|
|
||||||
SAFE,
|
|
||||||
//TODO: bang qualifier is not implemented in frontend for now
|
|
||||||
BANG,
|
|
||||||
NORMAL
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: we use normal by default but may cause bugs
|
//TODO: we use normal by default but may cause bugs
|
||||||
private /*var*/ CallType callType = CallType.NORMAL;
|
private /*var*/ CallType callType = CallType.NORMAL;
|
||||||
|
|
||||||
|
|||||||
+2
-11
@@ -1,4 +1,4 @@
|
|||||||
package org.jetbrains.k2js.translate.expression;
|
package org.jetbrains.k2js.translate.reference;
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsConditional;
|
import com.google.dart.compiler.backend.js.ast.JsConditional;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
@@ -8,9 +8,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.reference.AccessTranslator;
|
|
||||||
import org.jetbrains.k2js.translate.reference.CallTranslator;
|
|
||||||
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.general.Translation.translateAsExpression;
|
import static org.jetbrains.k2js.translate.general.Translation.translateAsExpression;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getNotNullSimpleNameSelector;
|
import static org.jetbrains.k2js.translate.utils.PsiUtils.getNotNullSimpleNameSelector;
|
||||||
@@ -32,13 +29,7 @@ public final class QualifiedExpressionTranslator {
|
|||||||
JsExpression receiver = translateReceiver(expression, context);
|
JsExpression receiver = translateReceiver(expression, context);
|
||||||
PropertyAccessTranslator result =
|
PropertyAccessTranslator result =
|
||||||
PropertyAccessTranslator.newInstance(getNotNullSimpleNameSelector(expression), receiver, context);
|
PropertyAccessTranslator.newInstance(getNotNullSimpleNameSelector(expression), receiver, context);
|
||||||
//TODO: util if this code duplicates
|
result.setCallType(CallType.getCallTypeForQualifierExpression(expression));
|
||||||
if (expression instanceof JetSafeQualifiedExpression) {
|
|
||||||
result.setCallType(PropertyAccessTranslator.CallType.SAFE);
|
|
||||||
}
|
|
||||||
if (expression instanceof JetDotQualifiedExpression) {
|
|
||||||
result.setCallType(PropertyAccessTranslator.CallType.NORMAL);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
class A() {
|
||||||
|
var c = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() {
|
||||||
|
var a1 : A? = A()
|
||||||
|
var a2 : A? = null
|
||||||
|
a1?.c++
|
||||||
|
a2?.c++
|
||||||
|
a2 = a1
|
||||||
|
a2?.c++
|
||||||
|
return (a2?.c == 5)
|
||||||
|
}
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package org.jetbrains.k2js.test;
|
|
||||||
|
|
||||||
import org.jetbrains.k2js.facade.K2JSTranslatorApplet;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.mozilla.javascript.Context;
|
|
||||||
import org.mozilla.javascript.Scriptable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Pavel Talanov
|
|
||||||
*/
|
|
||||||
public final class AppletTest extends TranslationTest {
|
|
||||||
|
|
||||||
final private static String MAIN = "applet/";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String mainDirectory() {
|
|
||||||
return MAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSimple() throws Exception {
|
|
||||||
evaluateCodeWithParameters("fun main(args : Array<String>) {}", " a 3 1 2134", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void testSystemOutTest() throws Exception {
|
|
||||||
evaluateCodeWithParameters("class A() {} fun main(args : Array<String>) { var a = A();}", "", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void evaluateCodeWithParameters(String kotlinCode, String paramString, String expectedResult)
|
|
||||||
throws Exception {
|
|
||||||
String programCode = (new K2JSTranslatorApplet())
|
|
||||||
.translateToJS(kotlinCode, paramString);
|
|
||||||
Assert.assertEquals(evaluateStringWithRhino(programCode), expectedResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private String evaluateStringWithRhino(String programCode) throws Exception {
|
|
||||||
Context context = Context.enter();
|
|
||||||
Scriptable scope = context.initStandardObjects();
|
|
||||||
runFileWithRhino(kotlinLibraryPath(), context, scope);
|
|
||||||
Object result = context.evaluateString(scope, programCode, "program code", 1, null);
|
|
||||||
Context.exit();
|
|
||||||
assert result instanceof String : "Must evaluate to string! Evaluated to: " + result;
|
|
||||||
return (String) result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -62,8 +62,13 @@ public final class PropertyAccessTest extends TranslationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void classUsesNamespaceProperties() throws Exception {
|
public void testClassUsesNamespaceProperties() throws Exception {
|
||||||
testFooBoxIsTrue("classUsesNamespaceProperties.kt");
|
testFooBoxIsTrue("classUsesNamespaceProperties.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testSafeAccess() throws Exception {
|
||||||
|
testFooBoxIsTrue("safeAccess.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user