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.$interval = 1000 / 30;
|
||||
{
|
||||
var tmp$5;
|
||||
var tmp$4;
|
||||
var tmp$3;
|
||||
var tmp$2;
|
||||
@@ -170,15 +169,9 @@
|
||||
}
|
||||
}
|
||||
));
|
||||
$(this.get_canvas()).resize((tmp$4 = this , function () {
|
||||
setInterval((tmp$4 = this , function () {
|
||||
{
|
||||
tmp$4.updateSize();
|
||||
}
|
||||
}
|
||||
));
|
||||
setInterval((tmp$5 = this , function () {
|
||||
{
|
||||
tmp$5.draw();
|
||||
tmp$4.draw();
|
||||
}
|
||||
}
|
||||
), this.get_interval());
|
||||
@@ -217,11 +210,6 @@
|
||||
this.$dragOff = tmp$0;
|
||||
}, get_interval:function () {
|
||||
return this.$interval;
|
||||
}, updateSize:function () {
|
||||
{
|
||||
this.set_width(this.get_canvas().width);
|
||||
this.set_height(this.get_canvas().height);
|
||||
}
|
||||
}, mousePos_0:function (e) {
|
||||
{
|
||||
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.reference.AccessTranslator;
|
||||
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.utils.BindingUtils;
|
||||
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.jet.lang.psi.*;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.expression.QualifiedExpressionTranslator;
|
||||
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;
|
||||
|
||||
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.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
@@ -11,8 +9,6 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.backingFieldReference;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
* <p/>
|
||||
@@ -24,36 +20,24 @@ public final class KotlinPropertyAccessTranslator extends PropertyAccessTranslat
|
||||
private final JsExpression qualifier;
|
||||
@NotNull
|
||||
private final PropertyDescriptor propertyDescriptor;
|
||||
private final boolean isBackingFieldAccess;
|
||||
@NotNull
|
||||
ResolvedCall<?> resolvedCall;
|
||||
|
||||
//TODO: too many params in constructor
|
||||
/*package*/ KotlinPropertyAccessTranslator(@NotNull PropertyDescriptor descriptor,
|
||||
@Nullable JsExpression qualifier,
|
||||
boolean isBackingFieldAccess,
|
||||
@NotNull ResolvedCall<?> resolvedCall,
|
||||
@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.qualifier = qualifier;
|
||||
this.propertyDescriptor = descriptor.getOriginal();
|
||||
this.isBackingFieldAccess = isBackingFieldAccess;
|
||||
this.resolvedCall = resolvedCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsExpression translateAsGet() {
|
||||
if (isBackingFieldAccess) {
|
||||
return backingFieldGet();
|
||||
} else {
|
||||
return getterCall();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression backingFieldGet() {
|
||||
return backingFieldReference(context(), propertyDescriptor);
|
||||
return getterCall();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -64,11 +48,8 @@ public final class KotlinPropertyAccessTranslator extends PropertyAccessTranslat
|
||||
@Override
|
||||
@NotNull
|
||||
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
|
||||
if (isBackingFieldAccess) {
|
||||
return backingFieldAssignment(toSetTo);
|
||||
} else {
|
||||
return setterCall(toSetTo);
|
||||
}
|
||||
|
||||
return setterCall(toSetTo);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -76,10 +57,4 @@ public final class KotlinPropertyAccessTranslator extends PropertyAccessTranslat
|
||||
return CallTranslator.translate(qualifier, Arrays.asList(toSetTo),
|
||||
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)) {
|
||||
return new NativePropertyAccessTranslator(descriptor, /*qualifier = */ null, context);
|
||||
} else {
|
||||
return new KotlinPropertyAccessTranslator(descriptor, /*qualifier = */ null, /*backingFieldAccess = */ false,
|
||||
resolvedCall, context);
|
||||
return new KotlinPropertyAccessTranslator(descriptor, /*qualifier = */ null, resolvedCall, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,13 +38,11 @@ public abstract class PropertyAccessTranslator extends AccessTranslator {
|
||||
@Nullable JsExpression qualifier,
|
||||
@NotNull TranslationContext context) {
|
||||
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(expression, context);
|
||||
if (isNativeObject(propertyDescriptor)) {
|
||||
if (isNativeObject(propertyDescriptor) || isBackingFieldReference(expression)) {
|
||||
return new NativePropertyAccessTranslator(propertyDescriptor, qualifier, context);
|
||||
}
|
||||
ResolvedCall<?> resolvedCall = getResolvedCall(context.bindingContext(), expression);
|
||||
boolean backingFieldAccess = isBackingFieldReference(expression);
|
||||
return new KotlinPropertyAccessTranslator(propertyDescriptor, qualifier,
|
||||
backingFieldAccess, resolvedCall, context);
|
||||
return new KotlinPropertyAccessTranslator(propertyDescriptor, qualifier, resolvedCall, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -105,13 +102,6 @@ public abstract class PropertyAccessTranslator extends AccessTranslator {
|
||||
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
|
||||
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.JsExpression;
|
||||
@@ -8,9 +8,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
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.utils.PsiUtils.getNotNullSimpleNameSelector;
|
||||
@@ -32,13 +29,7 @@ public final class QualifiedExpressionTranslator {
|
||||
JsExpression receiver = translateReceiver(expression, context);
|
||||
PropertyAccessTranslator result =
|
||||
PropertyAccessTranslator.newInstance(getNotNullSimpleNameSelector(expression), receiver, context);
|
||||
//TODO: util if this code duplicates
|
||||
if (expression instanceof JetSafeQualifiedExpression) {
|
||||
result.setCallType(PropertyAccessTranslator.CallType.SAFE);
|
||||
}
|
||||
if (expression instanceof JetDotQualifiedExpression) {
|
||||
result.setCallType(PropertyAccessTranslator.CallType.NORMAL);
|
||||
}
|
||||
result.setCallType(CallType.getCallTypeForQualifierExpression(expression));
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
public void testSafeAccess() throws Exception {
|
||||
testFooBoxIsTrue("safeAccess.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user