lots of api tweaks in jslib

some kotlin_lib functions
added support for native properties
added simple api for Canvas2D
This commit is contained in:
Pavel Talanov
2012-02-01 22:09:50 +04:00
parent b43b559ca6
commit 85a57b3cf9
16 changed files with 334 additions and 178 deletions
+2 -3
View File
@@ -1,7 +1,6 @@
package js.annotations; package js.annotations;
annotation class NativeClass() {} annotation class Native(name : String = "")
annotation class NativeFun(name : String)
annotation class LibraryClass() {} annotation class LibraryClass() {}
annotation class LibraryFun(name : String) {} annotation class LibraryFun(name : String = "") {}
+15 -6
View File
@@ -2,16 +2,25 @@ package js;
import js.annotations.LibraryFun import js.annotations.LibraryFun
import js.annotations.LibraryClass import js.annotations.LibraryClass
import js.annotations.Native
LibraryFun("println") LibraryFun("println")
fun println() fun println() {}
LibraryFun("println") LibraryFun("println")
fun println(s : Any?) fun println(s : Any?) {}
LibraryFun("print") LibraryFun("print")
fun print(s : Any?) fun print(s : Any?) {}
LibraryFun("parseInt") LibraryFun("parseInt")
fun parseInt(s : String) : Int fun parseInt(s : String) : Int = 0
LibraryClass LibraryClass
open class Exception() open class Exception() {}
LibraryClass LibraryClass
class NumberFormatException() : Exception() class NumberFormatException() : Exception() {}
Native
fun setTimeout(callback : ()-> Unit) {}
Native
fun setInterval(callback : ()-> Unit, ms : Int) {}
Native
fun setInterval(callback : ()-> Unit) {}
+8 -2
View File
@@ -1,11 +1,17 @@
package js package js
import java.util.*; import java.util.*;
import js.annotations.LibraryFun
class Json() { class Json() {
fun set(paramName : String, value : Any?) {}
fun get(paramName : String) : Any? = null
} }
LibraryFun("jsonSet")
fun Json.set(paramName : String, value : Any?) : Unit {}
LibraryFun("jsonGet")
fun Json.get(paramName : String) : Any? = null
fun <K, V> Map<K, V>.toJson() : Json = Json() fun <K, V> Map<K, V>.toJson() : Json = Json()
LibraryFun("jsonFromTuples")
fun json(vararg pairs : Tuple2<String, Any?>) = Json() fun json(vararg pairs : Tuple2<String, Any?>) = Json()
+7 -7
View File
@@ -2,7 +2,7 @@ package jquery;
import js.annotations.*; import js.annotations.*;
NativeClass Native
class JQuery() { class JQuery() {
fun addClass(className : String) : JQuery = this; fun addClass(className : String) : JQuery = this;
fun addClass(f : DomElement.(Int, String)->String) = this; fun addClass(f : DomElement.(Int, String)->String) = this;
@@ -35,15 +35,15 @@ open class DomElement() {
//val document = object : DomElement() {} //val document = object : DomElement() {}
NativeFun("$") Native("$")
fun jq(selector : String) = JQuery(); fun jq(selector : String) = JQuery();
NativeFun("$") Native("$")
fun jq(selector : String, context : DomElement) = JQuery(); fun jq(selector : String, context : DomElement) = JQuery();
NativeFun("$") Native("$")
fun jq(callback : () -> Unit) = JQuery(); fun jq(callback : () -> Unit) = JQuery();
NativeFun("$") Native("$")
fun jq(obj : JQuery) = JQuery(); fun jq(obj : JQuery) = JQuery();
NativeFun("$") Native("$")
fun jq(el : DomElement) = JQuery(); fun jq(el : DomElement) = JQuery();
NativeFun("$") Native("$")
fun jq() = JQuery(); fun jq() = JQuery();
+39 -11
View File
@@ -3,32 +3,60 @@ package raphael
import js.annotations.*; import js.annotations.*;
import js.*; import js.*;
NativeClass Native
class Element() { open class Element() {
fun attr(name : String, value : String) : Element = this fun attr(name : String, value : Any?) : Element = this
fun attr(nameToValue : Json) : Element = this fun attr(nameToValue : Json) : Element = this
fun mouseover(handler : () -> Unit) = this fun click(handler : Element.()-> Unit) = this;
fun mouseover(handler : Element.() -> Unit) = this
fun mouseout(handler : Element.() -> Unit) = this
fun getTotalLength() : Double = 0.0 fun getTotalLength() : Double = 0.0
fun getPointAtLength(length : Double) : Point {}
fun animate(params : Json, ms : Int, callback : ()-> Unit) : Element {}
fun animate(params : Json, ms : Int, s : String) : Element {}
fun animate(params : Json, ms : Int) : Element {}
//fun mouse //fun mouse
} }
NativeClass Native
class Set() : Element() {
fun push(el : Element) {}
}
Native
class Paper() { class Paper() {
fun path(pathString : String) : Element = Element(); fun path(pathString : String) : Element = Element();
fun path() : Element = Element(); fun path() : Element = Element();
fun ellipse(x : Int, y : Int, rx : Int, ry : Int) : Element = Element(); fun ellipse(x : Int, y : Int, rx : Int, ry : Int) : Element {}
fun circle(x : Int, y : Int, r : Int) : Element {}
fun set() : Set {}
val customAttributes : Json = Json();
} }
NativeFun("Raphael") Native("Raphael")
fun Raphael(elementId : String, width : Int, height : Int) : Paper = Paper(); fun Raphael(elementId : String, width : Int, height : Int) : Paper = Paper();
NativeFun("Raphael") Native("Raphael")
fun Raphael(elementId : String, width : Int, height : Int, initFun : Paper.() -> Unit) : Unit {} fun Raphael(elementId : String, width : Int, height : Int, initFun : Paper.() -> Unit) : Unit {}
NativeClass Native
val Raphael = object { fun getColor() : Color {}
fun getColor() : String = "" Native
fun resetColors() {}
Native
class Color() {}
Native
class Point() {
val x = 0
val y = 0
val alpha = 0
} }
@@ -30,7 +30,8 @@ public abstract class Config {
PATH_TO_JS_LIB_SRC + "\\core\\javalang.kt", PATH_TO_JS_LIB_SRC + "\\core\\javalang.kt",
PATH_TO_JS_LIB_SRC + "\\core\\core.kt", PATH_TO_JS_LIB_SRC + "\\core\\core.kt",
PATH_TO_JS_LIB_SRC + "\\raphael\\raphael.kt", PATH_TO_JS_LIB_SRC + "\\raphael\\raphael.kt",
PATH_TO_JS_LIB_SRC + "\\core\\json.kt" PATH_TO_JS_LIB_SRC + "\\core\\json.kt",
PATH_TO_JS_LIB_SRC + "\\html5\\core.kt"
); );
@@ -193,9 +193,8 @@ public final class TranslationContext {
return dynamicContext.jsBlock(); return dynamicContext.jsBlock();
} }
//TODO: deletE?
@NotNull @NotNull
private DeclarationFacade declarationFacade() { public DeclarationFacade declarationFacade() {
return staticContext.getDeclarationFacade(); return staticContext.getDeclarationFacade();
} }
} }
@@ -4,7 +4,6 @@ import com.google.dart.compiler.backend.js.ast.JsName;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.k2js.translate.context.NamingScope; import org.jetbrains.k2js.translate.context.NamingScope;
@@ -20,14 +19,14 @@ public class AnnotatedDeclarationVisitor extends AbstractDeclarationVisitor {
private final String classAnnotationFQName; private final String classAnnotationFQName;
@NotNull @NotNull
private final String funAnnotationFQName; private final String memberAnnotationFQName;
/*package*/ AnnotatedDeclarationVisitor(@NotNull Declarations declarations, /*package*/ AnnotatedDeclarationVisitor(@NotNull Declarations declarations,
@NotNull String classAnnotationFQName, @NotNull String classAnnotationFQName,
@NotNull String funAnnotationFQName) { @NotNull String memberAnnotationFQName) {
super(declarations); super(declarations);
this.classAnnotationFQName = classAnnotationFQName; this.classAnnotationFQName = classAnnotationFQName;
this.funAnnotationFQName = funAnnotationFQName; this.memberAnnotationFQName = memberAnnotationFQName;
} }
@NotNull @NotNull
@@ -61,13 +60,11 @@ public class AnnotatedDeclarationVisitor extends AbstractDeclarationVisitor {
if (descriptor instanceof NamespaceDescriptor) { if (descriptor instanceof NamespaceDescriptor) {
return true; return true;
} }
if (descriptor instanceof FunctionDescriptor) {
return isAnnotatedFunction((FunctionDescriptor) descriptor);
}
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
return isAnnotatedClass((ClassDescriptor) descriptor); return isAnnotatedClass((ClassDescriptor) descriptor);
} }
return false;
return isAnnotatedMember(descriptor);
} }
@Override @Override
@@ -76,38 +73,28 @@ public class AnnotatedDeclarationVisitor extends AbstractDeclarationVisitor {
} }
//TODO: refactor
@NotNull @NotNull
public String getName(@NotNull DeclarationDescriptor descriptor) { public String getName(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof FunctionDescriptor) { if (hasMemberAnnotation(descriptor)) {
return getNameForFunction((FunctionDescriptor) descriptor); String name = annotationStringParameter(descriptor, memberAnnotationFQName);
} if (!(name.isEmpty())) {
if (descriptor instanceof ClassDescriptor) { return name;
return getNameForClass((ClassDescriptor) descriptor); }
} return descriptor.getName();
throw new AssertionError();
}
@NotNull
private String getNameForFunction(@NotNull FunctionDescriptor descriptor) {
if (hasFunctionAnnotation(descriptor)) {
return annotationStringParameter(descriptor, funAnnotationFQName);
} }
if (declaredInAnnotatedClass(descriptor)) { if (declaredInAnnotatedClass(descriptor)) {
return descriptor.getName(); return descriptor.getName();
} }
if (hasClassAnnotation(descriptor)) {
return descriptor.getName();
}
throw new AssertionError("Use isAnnotatedFunction to check"); throw new AssertionError("Use isAnnotatedFunction to check");
} }
@NotNull
private String getNameForClass(@NotNull ClassDescriptor descriptor) {
if (hasClassAnnotation(descriptor)) {
return descriptor.getName();
}
throw new AssertionError("Use isAnnotatedClass to check");
}
public boolean isAnnotatedFunction(@NotNull FunctionDescriptor functionDescriptor) { public boolean isAnnotatedMember(@NotNull DeclarationDescriptor descriptor) {
return hasFunctionAnnotation(functionDescriptor) || declaredInAnnotatedClass(functionDescriptor); return hasMemberAnnotation(descriptor) || declaredInAnnotatedClass(descriptor);
} }
public boolean isAnnotatedClass(@NotNull ClassDescriptor classDescriptor) { public boolean isAnnotatedClass(@NotNull ClassDescriptor classDescriptor) {
@@ -121,8 +108,8 @@ public class AnnotatedDeclarationVisitor extends AbstractDeclarationVisitor {
} }
private boolean hasFunctionAnnotation(@NotNull DeclarationDescriptor descriptor) { private boolean hasMemberAnnotation(@NotNull DeclarationDescriptor descriptor) {
return (getAnnotationByName(descriptor, funAnnotationFQName) != null); return (getAnnotationByName(descriptor, memberAnnotationFQName) != null);
} }
private boolean hasClassAnnotation(@NotNull DeclarationDescriptor descriptor) { private boolean hasClassAnnotation(@NotNull DeclarationDescriptor descriptor) {
@@ -4,9 +4,9 @@ import com.google.common.collect.Sets;
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.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import java.util.Set; import java.util.Set;
@@ -16,16 +16,14 @@ import java.util.Set;
public final class AnnotationsUtils { public final class AnnotationsUtils {
@NotNull @NotNull
public static final String NATIVE_FUNCTION_ANNOTATION_FQNAME = "js.annotations.NativeFun"; public static final String NATIVE_ANNOTATION_FQNAME = "js.annotations.Native";
@NotNull
public static final String NATIVE_CLASS_ANNOTATION_FQNAME = "js.annotations.NativeClass";
@NotNull @NotNull
public static final String LIBRARY_FUNCTION_ANNOTATION_FQNAME = "js.annotations.LibraryFun"; public static final String LIBRARY_FUNCTION_ANNOTATION_FQNAME = "js.annotations.LibraryFun";
@NotNull @NotNull
public static final String LIBRARY_CLASS_ANNOTATION_FQNAME = "js.annotations.LibraryClass"; public static final String LIBRARY_CLASS_ANNOTATION_FQNAME = "js.annotations.LibraryClass";
@NotNull @NotNull
public static Set<String> INTERNAL_ANNOTATIONS_FQNAMES = Sets.newHashSet( public static Set<String> INTERNAL_ANNOTATIONS_FQNAMES = Sets.newHashSet(
NATIVE_CLASS_ANNOTATION_FQNAME, NATIVE_FUNCTION_ANNOTATION_FQNAME, NATIVE_ANNOTATION_FQNAME,
LIBRARY_CLASS_ANNOTATION_FQNAME, LIBRARY_FUNCTION_ANNOTATION_FQNAME); LIBRARY_CLASS_ANNOTATION_FQNAME, LIBRARY_FUNCTION_ANNOTATION_FQNAME);
private AnnotationsUtils() { private AnnotationsUtils() {
@@ -46,12 +44,21 @@ public final class AnnotationsUtils {
} }
@NotNull @NotNull
public static String annotationStringParameter(@NotNull FunctionDescriptor declarationDescriptor, public static String annotationStringParameter(@NotNull DeclarationDescriptor declarationDescriptor,
@NotNull String annotationFQName) { @NotNull String annotationFQName) {
AnnotationDescriptor annotationDescriptor = AnnotationDescriptor annotationDescriptor =
getAnnotationByName(declarationDescriptor, annotationFQName); getAnnotationByName(declarationDescriptor, annotationFQName);
assert annotationDescriptor != null; assert annotationDescriptor != null;
Object value = annotationDescriptor.getValueArguments().iterator().next().getValue(); //TODO: this is a quick fix for unsupported default args problem
if (annotationDescriptor.getValueArguments().isEmpty()) {
return "";
}
CompileTimeConstant<?> constant = annotationDescriptor.getValueArguments().iterator().next();
//TODO: this is a quick fix for unsupported default args problem
if (constant == null) {
return "";
}
Object value = constant.getValue();
assert value instanceof String : "Native function annotation should have one String parameter"; assert value instanceof String : "Native function annotation should have one String parameter";
return (String) value; return (String) value;
} }
@@ -2,8 +2,7 @@ package org.jetbrains.k2js.translate.context.declaration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import static org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils.NATIVE_CLASS_ANNOTATION_FQNAME; import static org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils.NATIVE_ANNOTATION_FQNAME;
import static org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils.NATIVE_FUNCTION_ANNOTATION_FQNAME;
/** /**
* @author Pavel Talanov * @author Pavel Talanov
@@ -11,6 +10,6 @@ import static org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils.
public final class NativeDeclarationVisitor extends AnnotatedDeclarationVisitor { public final class NativeDeclarationVisitor extends AnnotatedDeclarationVisitor {
/*package*/ NativeDeclarationVisitor(@NotNull Declarations nativeDeclarations) { /*package*/ NativeDeclarationVisitor(@NotNull Declarations nativeDeclarations) {
super(nativeDeclarations, NATIVE_CLASS_ANNOTATION_FQNAME, NATIVE_FUNCTION_ANNOTATION_FQNAME); super(nativeDeclarations, NATIVE_ANNOTATION_FQNAME, NATIVE_ANNOTATION_FQNAME);
} }
} }
@@ -21,8 +21,9 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForRe
*/ */
public final class ArrayAccessTranslator extends AccessTranslator { public final class ArrayAccessTranslator extends AccessTranslator {
public static ArrayAccessTranslator newInstance(@NotNull JetArrayAccessExpression expression, /*package*/
@NotNull TranslationContext context) { static ArrayAccessTranslator newInstance(@NotNull JetArrayAccessExpression expression,
@NotNull TranslationContext context) {
return new ArrayAccessTranslator(expression, context); return new ArrayAccessTranslator(expression, context);
} }
@@ -0,0 +1,83 @@
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;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.k2js.translate.context.TranslationContext;
import java.util.Arrays;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.backingFieldReference;
/**
* @author Pavel Talanov
*/
public final class KotlinPropertyAccessTranslator extends PropertyAccessTranslator {
@Nullable
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);
}
@NotNull
private JsExpression getterCall() {
return CallTranslator.translate(qualifier, resolvedCall, propertyDescriptor.getGetter(), context());
}
@Override
@NotNull
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
if (isBackingFieldAccess) {
return backingFieldAssignment(toSetTo);
} else {
return setterCall(toSetTo);
}
}
@NotNull
private JsExpression setterCall(@NotNull JsExpression toSetTo) {
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);
}
}
@@ -0,0 +1,66 @@
package org.jetbrains.k2js.translate.reference;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
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.PropertyDescriptor;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getExpectedThisDescriptor;
/**
* @author Pavel Talanov
*/
public final class NativePropertyAccessTranslator extends PropertyAccessTranslator {
@Nullable
private final JsExpression qualifier;
@NotNull
private final PropertyDescriptor propertyDescriptor;
/*package*/
NativePropertyAccessTranslator(@NotNull PropertyDescriptor descriptor,
@Nullable JsExpression qualifier,
@NotNull TranslationContext context) {
super(context);
this.qualifier = qualifier;
this.propertyDescriptor = descriptor.getOriginal();
}
@Override
@NotNull
public JsExpression translateAsGet() {
JsName nativePropertyName = context().getNameForDescriptor(propertyDescriptor);
JsExpression realQualifier = getQualifier();
if (realQualifier != null) {
return AstUtil.qualified(nativePropertyName, realQualifier);
} else {
return nativePropertyName.makeRef();
}
}
@Override
@NotNull
public JsExpression translateAsSet(@NotNull JsExpression setTo) {
return AstUtil.assignment(translateAsGet(), setTo);
}
@Nullable
public JsExpression getQualifier() {
if (qualifier != null) {
return qualifier;
}
assert !propertyDescriptor.getReceiverParameter().exists() : "Cant have native extension properties.";
DeclarationDescriptor expectedThisDescriptor = getExpectedThisDescriptor(propertyDescriptor);
if (expectedThisDescriptor == null) {
return null;
}
return TranslationUtils.getThisObject(context(), expectedThisDescriptor);
}
}
@@ -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.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
@@ -13,32 +11,57 @@ import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import java.util.Arrays;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall; import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getSelectorAsSimpleName; import static org.jetbrains.k2js.translate.utils.PsiUtils.getSelectorAsSimpleName;
import static org.jetbrains.k2js.translate.utils.PsiUtils.isBackingFieldReference; import static org.jetbrains.k2js.translate.utils.PsiUtils.isBackingFieldReference;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.backingFieldReference;
/** /**
* @author Pavel Talanov * @author Pavel Talanov
*/ */
public final class PropertyAccessTranslator extends AccessTranslator { public abstract class PropertyAccessTranslator extends AccessTranslator {
@NotNull @NotNull
private static PropertyDescriptor getPropertyDescriptor(@NotNull JetSimpleNameExpression expression, public static PropertyAccessTranslator newInstance(@NotNull PropertyDescriptor descriptor,
@NotNull TranslationContext context) { @NotNull ResolvedCall<?> resolvedCall,
@NotNull TranslationContext context) {
if (isNativeProperty(descriptor, context)) {
return new NativePropertyAccessTranslator(descriptor, /*qualifier = */ null, context);
} else {
return new KotlinPropertyAccessTranslator(descriptor, /*qualifier = */ null, /*backingFieldAccess = */ false,
resolvedCall, context);
}
}
@NotNull
public static PropertyAccessTranslator newInstance(@NotNull JetSimpleNameExpression expression,
@Nullable JsExpression qualifier,
@NotNull TranslationContext context) {
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(expression, context);
if (isNativeProperty(propertyDescriptor, context)) {
return new NativePropertyAccessTranslator(propertyDescriptor, qualifier, context);
}
ResolvedCall<?> resolvedCall = getResolvedCall(context.bindingContext(), expression);
boolean backingFieldAccess = isBackingFieldReference(expression);
return new KotlinPropertyAccessTranslator(propertyDescriptor, qualifier,
backingFieldAccess, resolvedCall, context);
}
@NotNull
/*package*/ static PropertyDescriptor getPropertyDescriptor(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
DeclarationDescriptor descriptor = DeclarationDescriptor descriptor =
getDescriptorForReferenceExpression(context.bindingContext(), expression); getDescriptorForReferenceExpression(context.bindingContext(), expression);
assert descriptor instanceof PropertyDescriptor : "Must be a property descriptor."; assert descriptor instanceof PropertyDescriptor : "Must be a property descriptor.";
return (PropertyDescriptor) descriptor; return (PropertyDescriptor) descriptor;
} }
@NotNull @NotNull
public static JsExpression translateAsPropertyGetterCall(@NotNull PropertyDescriptor descriptor, /*package*/
@NotNull ResolvedCall<?> resolvedCall, static JsExpression translateAsPropertyGetterCall(@NotNull PropertyDescriptor descriptor,
@NotNull TranslationContext context) { @NotNull ResolvedCall<?> resolvedCall,
@NotNull TranslationContext context) {
return (newInstance(descriptor, resolvedCall, context)) return (newInstance(descriptor, resolvedCall, context))
.translateAsGet(); .translateAsGet();
} }
@@ -51,23 +74,6 @@ public final class PropertyAccessTranslator extends AccessTranslator {
.translateAsGet(); .translateAsGet();
} }
@NotNull
private static PropertyAccessTranslator newInstance(@NotNull PropertyDescriptor descriptor,
@NotNull ResolvedCall<?> resolvedCall,
@NotNull TranslationContext context) {
return new PropertyAccessTranslator(descriptor, null, false, resolvedCall, context);
}
@NotNull
public static PropertyAccessTranslator newInstance(@NotNull JetSimpleNameExpression expression,
@Nullable JsExpression qualifier,
@NotNull TranslationContext context) {
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(expression, context);
ResolvedCall<?> resolvedCall = getResolvedCall(context.bindingContext(), expression);
boolean backingFieldAccess = isBackingFieldReference(expression);
return new PropertyAccessTranslator(propertyDescriptor, qualifier,
backingFieldAccess, resolvedCall, context);
}
public static boolean canBePropertyGetterCall(@NotNull JetQualifiedExpression expression, public static boolean canBePropertyGetterCall(@NotNull JetQualifiedExpression expression,
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
@@ -101,65 +107,13 @@ public final class PropertyAccessTranslator extends AccessTranslator {
return canBePropertyGetterCall(expression, context); return canBePropertyGetterCall(expression, context);
} }
@Nullable private static boolean isNativeProperty(@NotNull PropertyDescriptor propertyDescriptor,
private final JsExpression qualifier; @NotNull TranslationContext context) {
@NotNull return context.declarationFacade().getNativeDeclarations().hasDeclaredName(propertyDescriptor);
private final PropertyDescriptor propertyDescriptor; }
private final boolean isBackingFieldAccess;
@NotNull
ResolvedCall<?> resolvedCall;
private PropertyAccessTranslator(@NotNull PropertyDescriptor descriptor, protected PropertyAccessTranslator(@NotNull TranslationContext context) {
@Nullable JsExpression qualifier,
boolean isBackingFieldAccess,
@NotNull ResolvedCall<?> resolvedCall,
@NotNull TranslationContext context) {
super(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);
}
@NotNull
private JsExpression getterCall() {
return CallTranslator.translate(qualifier, resolvedCall, propertyDescriptor.getGetter(), context());
}
@Override
@NotNull
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
if (isBackingFieldAccess) {
return backingFieldAssignment(toSetTo);
} else {
return setterCall(toSetTo);
}
}
@NotNull
private JsExpression setterCall(@NotNull JsExpression toSetTo) {
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);
}
}
@@ -13,13 +13,11 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
public final class ReferenceAccessTranslator extends AccessTranslator { public final class ReferenceAccessTranslator extends AccessTranslator {
@NotNull @NotNull
public static ReferenceAccessTranslator newInstance(@NotNull JetSimpleNameExpression expression, /*package*/ static ReferenceAccessTranslator newInstance(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
return new ReferenceAccessTranslator(expression, context); return new ReferenceAccessTranslator(expression, context);
} }
//TODO: condider evaluating only once
@NotNull @NotNull
private final JetSimpleNameExpression expression; private final JetSimpleNameExpression expression;
@@ -32,12 +30,14 @@ public final class ReferenceAccessTranslator extends AccessTranslator {
@Override @Override
@NotNull @NotNull
public JsExpression translateAsGet() { public JsExpression translateAsGet() {
//TODO: consider evaluating only once
return ReferenceTranslator.translateSimpleName(expression, context()); return ReferenceTranslator.translateSimpleName(expression, context());
} }
@Override @Override
@NotNull @NotNull
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) { public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
//TODO: consider evaluating only once
JsExpression reference = ReferenceTranslator.translateSimpleName(expression, context()); JsExpression reference = ReferenceTranslator.translateSimpleName(expression, context());
assert reference instanceof JsNameRef; assert reference instanceof JsNameRef;
return AstUtil.newAssignment((JsNameRef) reference, toSetTo); return AstUtil.newAssignment((JsNameRef) reference, toSetTo);
+29 -12
View File
@@ -122,8 +122,9 @@
; ;
function create() { function create() {
var parent = null, properties = $A(arguments); var parent = null, properties = $A(arguments);
if (typeof (properties[0]) == "function") if (typeof (properties[0]) == "function") {
parent = properties.shift(); parent = properties.shift();
}
function klass() { function klass() {
this.initializing = klass; this.initializing = klass;
@@ -160,8 +161,9 @@
for (var i = 0, length = properties.length; i < length; i++) for (var i = 0, length = properties.length; i < length; i++)
klass.addMethods(properties[i]); klass.addMethods(properties[i]);
if (!klass.prototype.initialize) if (!klass.prototype.initialize) {
klass.prototype.initialize = emptyFunction; klass.prototype.initialize = emptyFunction;
}
klass.prototype.constructor = klass; klass.prototype.constructor = klass;
return klass; return klass;
@@ -313,9 +315,9 @@
Kotlin.parseInt = Kotlin.parseInt =
function (str) { function (str) {
return parseInt(str); return parseInt(str);
} }
; ;
Kotlin.System = function () { Kotlin.System = function () {
@@ -325,7 +327,8 @@
if (obj !== undefined) { if (obj !== undefined) {
if (obj == null || typeof obj != "object") { if (obj == null || typeof obj != "object") {
output += obj; output += obj;
} else { }
else {
output += obj.toString(); output += obj.toString();
} }
} }
@@ -507,7 +510,9 @@
next:function () { next:function () {
return this.arr[this.i++]; return this.arr[this.i++];
}, },
get_hasNext:function() { return this.hasNext()} get_hasNext:function () {
return this.hasNext()
}
} }
); );
@@ -519,7 +524,7 @@
return obj.toString(); return obj.toString();
}; };
Kotlin.jsonFromTuples = function(pairArr) { Kotlin.jsonFromTuples = function (pairArr) {
var i = pairArr.length; var i = pairArr.length;
var res = {}; var res = {};
while (i > 0) { while (i > 0) {
@@ -529,6 +534,14 @@
return res; return res;
}; };
Kotlin.jsonSet = function (obj, attrName, value) {
obj[attrName] = value;
};
Kotlin.jsonGet = function (obj, attrName) {
return obj[attrName];
};
/** /**
* Copyright 2010 Tim Down. * Copyright 2010 Tim Down.
@@ -570,7 +583,8 @@
var itemsAfterDeleted, i, len; var itemsAfterDeleted, i, len;
if (idx === arr.length - 1) { if (idx === arr.length - 1) {
arr.length = idx; arr.length = idx;
} else { }
else {
itemsAfterDeleted = arr.slice(idx + 1); itemsAfterDeleted = arr.slice(idx + 1);
arr.length = idx; arr.length = idx;
for (i = 0, len = itemsAfterDeleted.length; i < len; ++i) { for (i = 0, len = itemsAfterDeleted.length; i < len; ++i) {
@@ -589,7 +603,8 @@
return (typeof hashCode == "string") ? hashCode : hashObject(hashCode); return (typeof hashCode == "string") ? hashCode : hashObject(hashCode);
} else if (typeof obj.toString == FUNCTION) { } else if (typeof obj.toString == FUNCTION) {
return obj.toString(); return obj.toString();
} else { }
else {
try { try {
return String(obj); return String(obj);
} catch (ex) { } catch (ex) {
@@ -759,11 +774,13 @@
// This bucket entry is the current mapping of key to value, so replace old value and we're done. // This bucket entry is the current mapping of key to value, so replace old value and we're done.
oldValue = bucketEntry[1]; oldValue = bucketEntry[1];
bucketEntry[1] = value; bucketEntry[1] = value;
} else { }
else {
// The bucket does not contain an entry for this key, so add one // The bucket does not contain an entry for this key, so add one
bucket.addEntry(key, value); bucket.addEntry(key, value);
} }
} else { }
else {
// No bucket exists for the key, so create one and put our key/value mapping in // No bucket exists for the key, so create one and put our key/value mapping in
bucket = new Bucket(hash, key, value, equalityFunction); bucket = new Bucket(hash, key, value, equalityFunction);
buckets[buckets.length] = bucket; buckets[buckets.length] = bucket;