Supported (Variable is Type expression) for user defined classes.
This commit is contained in:
@@ -268,4 +268,8 @@ public class AstUtil {
|
|||||||
result.setStatements(statements);
|
result.setStatements(statements);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JsPrefixOperation negation(JsExpression expression) {
|
||||||
|
return new JsPrefixOperation(JsUnaryOperator.NOT, expression);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package org.jetbrains.k2js.translate;
|
package org.jetbrains.k2js.translate;
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsProgram;
|
import com.google.dart.compiler.backend.js.ast.JsProgram;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsScope;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
@@ -26,14 +24,4 @@ public abstract class AbstractTranslator {
|
|||||||
protected TranslationContext translationContext() {
|
protected TranslationContext translationContext() {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
protected BindingContext bindingContext() {
|
|
||||||
return context.bindingContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
protected JsScope scope() {
|
|
||||||
return context.enclosingScope();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,17 +91,23 @@ public final class BindingUtils {
|
|||||||
Collection<? extends JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
|
Collection<? extends JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
|
||||||
List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
|
List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
|
||||||
for (JetType type : superclassTypes) {
|
for (JetType type : superclassTypes) {
|
||||||
DeclarationDescriptor superClassDescriptor =
|
ClassDescriptor result = getClassDescriptorForType(type);
|
||||||
type.getConstructor().getDeclarationDescriptor();
|
if (isNotAny(result)) {
|
||||||
assert superClassDescriptor instanceof ClassDescriptor
|
superClassDescriptors.add(result);
|
||||||
: "Superclass descriptor of a type should be of type ClassDescriptor";
|
|
||||||
if (isNotAny(superClassDescriptor)) {
|
|
||||||
superClassDescriptors.add((ClassDescriptor) superClassDescriptor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return superClassDescriptors;
|
return superClassDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
static public ClassDescriptor getClassDescriptorForType(@NotNull JetType type) {
|
||||||
|
DeclarationDescriptor superClassDescriptor =
|
||||||
|
type.getConstructor().getDeclarationDescriptor();
|
||||||
|
assert superClassDescriptor instanceof ClassDescriptor
|
||||||
|
: "Superclass descriptor of a type should be of type ClassDescriptor";
|
||||||
|
return (ClassDescriptor) superClassDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
static public boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClass classDeclaration) {
|
static public boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClass classDeclaration) {
|
||||||
List<ClassDescriptor> superclassDescriptors = getSuperclassDescriptors(context, classDeclaration);
|
List<ClassDescriptor> superclassDescriptors = getSuperclassDescriptors(context, classDeclaration);
|
||||||
return (findAncestorClass(superclassDescriptors) != null);
|
return (findAncestorClass(superclassDescriptors) != null);
|
||||||
@@ -113,8 +119,22 @@ public final class BindingUtils {
|
|||||||
return isStatement;
|
return isStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
static public JetType getTypeByReference(@NotNull BindingContext context,
|
||||||
|
@NotNull JetTypeReference typeReference) {
|
||||||
|
JetType result = context.get(BindingContext.TYPE, typeReference);
|
||||||
|
assert result != null : "TypeReference should reference a type";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
static public ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context,
|
||||||
|
@NotNull JetTypeReference typeReference) {
|
||||||
|
return getClassDescriptorForType(getTypeByReference(context, typeReference));
|
||||||
|
}
|
||||||
|
|
||||||
//TODO better implementation?
|
//TODO better implementation?
|
||||||
private static boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) {
|
static private boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) {
|
||||||
return !superClassDescriptor.getName().equals("Any");
|
return !superClassDescriptor.getName().equals("Any");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -350,5 +350,19 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// @NotNull
|
||||||
|
// public JsNode visitBinaryWithTypeRHSExpression(@NotNull JetBinaryExpressionWithTypeRHS expression,
|
||||||
|
// @NotNull TranslationContext context) {
|
||||||
|
// return Translation.typeOperationTranslator(context).translate(expression);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public JsNode visitIsExpression(@NotNull JetIsExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
return Translation.typeOperationTranslator(context).translateIsExpression(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.google.dart.compiler.util.AstUtil;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class is a complete dummy and needs a lot of work
|
* This class is a complete dummy and should completely change in the future
|
||||||
*/
|
*/
|
||||||
public final class Namer {
|
public final class Namer {
|
||||||
|
|
||||||
@@ -71,5 +71,9 @@ public final class Namer {
|
|||||||
return AstUtil.newQualifiedNameRef("Trait.create");
|
return AstUtil.newQualifiedNameRef("Trait.create");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JsNameRef isOperationReference() {
|
||||||
|
return AstUtil.newQualifiedNameRef("isType");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public final class NamespaceTranslator extends AbstractTranslator {
|
|||||||
public JsBlock translate(@NotNull JetNamespace namespace) {
|
public JsBlock translate(@NotNull JetNamespace namespace) {
|
||||||
// TODO support multiple namespaces
|
// TODO support multiple namespaces
|
||||||
JsBlock block = program().getFragmentBlock(0);
|
JsBlock block = program().getFragmentBlock(0);
|
||||||
JsName namespaceName = scope().declareName(Namer.getNameForNamespace(namespace.getName()));
|
JsName namespaceName = translationContext().enclosingScope().declareName(Namer.getNameForNamespace(namespace.getName()));
|
||||||
block.addStatement(namespaceInitStatement(namespaceName));
|
block.addStatement(namespaceInitStatement(namespaceName));
|
||||||
TranslationContext newContext = translationContext().newNamespace(namespace);
|
TranslationContext newContext = translationContext().newNamespace(namespace);
|
||||||
JsFunction dummyFunction = JsFunction.getAnonymousFunctionWithScope
|
JsFunction dummyFunction = JsFunction.getAnonymousFunctionWithScope
|
||||||
|
|||||||
@@ -80,18 +80,21 @@ public final class OperationTranslator extends AbstractTranslator {
|
|||||||
return setterCall;
|
return setterCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JetToken getOperationToken(@NotNull JetBinaryExpression expression) {
|
|
||||||
return (JetToken) expression.getOperationToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression translateAsBinaryOperation(@NotNull JetBinaryExpression expression) {
|
private JsExpression translateAsBinaryOperation(@NotNull JetBinaryExpression expression) {
|
||||||
JsExpression left = AstUtil.convertToExpression
|
JsExpression left = AstUtil.convertToExpression
|
||||||
(Translation.translateExpression(expression.getLeft(), translationContext()));
|
(Translation.translateExpression(expression.getLeft(), translationContext()));
|
||||||
JsExpression right = translateRightExpression(expression);
|
JsExpression right = translateRightExpression(expression);
|
||||||
JetToken jetOperationToken = getOperationToken(expression);
|
JetToken token = getOperationToken(expression);
|
||||||
return new JsBinaryOperation(OperatorTable.getBinaryOperator(jetOperationToken), left, right);
|
if (OperatorTable.hasCorrespondingBinaryOperator(token)) {
|
||||||
|
return new JsBinaryOperation(OperatorTable.getBinaryOperator(token), left, right);
|
||||||
|
}
|
||||||
|
if (OperatorTable.hasCorrespondingFunctionInvocation(token)) {
|
||||||
|
JsInvocation functionInvocation = OperatorTable.getCorrespondingFunctionInvocation(token);
|
||||||
|
functionInvocation.setArguments(Arrays.asList(left, right));
|
||||||
|
return functionInvocation;
|
||||||
|
}
|
||||||
|
throw new AssertionError("Unsupported token encountered: " + token.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -102,5 +105,10 @@ public final class OperationTranslator extends AbstractTranslator {
|
|||||||
(Translation.translateExpression(rightExpression, translationContext()));
|
(Translation.translateExpression(rightExpression, translationContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JetToken getOperationToken(@NotNull JetBinaryExpression expression) {
|
||||||
|
return (JetToken) expression.getOperationToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package org.jetbrains.k2js.translate;
|
package org.jetbrains.k2js.translate;
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
|
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsUnaryOperator;
|
import com.google.dart.compiler.backend.js.ast.JsUnaryOperator;
|
||||||
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lexer.JetToken;
|
import org.jetbrains.jet.lexer.JetToken;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
@@ -14,9 +17,9 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public final class OperatorTable {
|
public final class OperatorTable {
|
||||||
|
|
||||||
|
|
||||||
private static Map<JetToken, JsBinaryOperator> binaryOperatorsMap = new HashMap<JetToken, JsBinaryOperator>();
|
private static Map<JetToken, JsBinaryOperator> binaryOperatorsMap = new HashMap<JetToken, JsBinaryOperator>();
|
||||||
private static Map<JetToken, JsUnaryOperator> unaryOperatorsMap = new HashMap<JetToken, JsUnaryOperator>();
|
private static Map<JetToken, JsUnaryOperator> unaryOperatorsMap = new HashMap<JetToken, JsUnaryOperator>();
|
||||||
|
private static Map<JetToken, JsNameRef> operatorToFunctionNameReference = new HashMap<JetToken, JsNameRef>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
unaryOperatorsMap.put(JetTokens.PLUSPLUS, JsUnaryOperator.INC); //++
|
unaryOperatorsMap.put(JetTokens.PLUSPLUS, JsUnaryOperator.INC); //++
|
||||||
@@ -43,6 +46,27 @@ public final class OperatorTable {
|
|||||||
binaryOperatorsMap.put(JetTokens.PERC, JsBinaryOperator.MOD);
|
binaryOperatorsMap.put(JetTokens.PERC, JsBinaryOperator.MOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
operatorToFunctionNameReference.put(JetTokens.IS_KEYWORD, Namer.isOperationReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static boolean hasCorrespondingBinaryOperator(@NotNull JetToken token) {
|
||||||
|
return binaryOperatorsMap.containsKey(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
static boolean hasCorrespondingFunctionInvocation(@NotNull JetToken token) {
|
||||||
|
return operatorToFunctionNameReference.containsKey(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsInvocation getCorrespondingFunctionInvocation(@NotNull JetToken token) {
|
||||||
|
JsNameRef functionReference = operatorToFunctionNameReference.get(token);
|
||||||
|
assert functionReference != null : "Token should represent a function call!";
|
||||||
|
return AstUtil.newInvocation(functionReference);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsBinaryOperator getBinaryOperator(@NotNull JetToken token) {
|
public static JsBinaryOperator getBinaryOperator(@NotNull JetToken token) {
|
||||||
assert JetTokens.OPERATIONS.contains(token) : "Token should represent an operation!";
|
assert JetTokens.OPERATIONS.contains(token) : "Token should represent an operation!";
|
||||||
@@ -59,4 +83,5 @@ public final class OperatorTable {
|
|||||||
return (token == JetTokens.EQ);
|
return (token == JetTokens.EQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ public final class Translation {
|
|||||||
return DeclarationTranslator.newInstance(context);
|
return DeclarationTranslator.newInstance(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
static public TypeOperationTranslator typeOperationTranslator(@NotNull TranslationContext context) {
|
||||||
|
return TypeOperationTranslator.newInstance(context);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public JsNode translateExpression(@NotNull JetExpression expression, @NotNull TranslationContext context) {
|
static public JsNode translateExpression(@NotNull JetExpression expression, @NotNull TranslationContext context) {
|
||||||
return expressionTranslator(context).translate(expression);
|
return expressionTranslator(context).translate(expression);
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package org.jetbrains.k2js.translate;
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsName;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||||
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetIsExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypePattern;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public final class TypeOperationTranslator extends AbstractTranslator {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static TypeOperationTranslator newInstance(@NotNull TranslationContext context) {
|
||||||
|
return new TypeOperationTranslator(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TypeOperationTranslator(@NotNull TranslationContext context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @NotNull
|
||||||
|
// public JsExpression translate(@NotNull JetBinaryExpressionWithTypeRHS expression) {
|
||||||
|
// JsExpression left = AstUtil.convertToExpression
|
||||||
|
// (Translation.translateExpression(expression.getLeft(), translationContext()));
|
||||||
|
// JsNameRef right = getClassReference(expression);
|
||||||
|
// JetToken token = getOperationToken(expression);
|
||||||
|
// if (OperatorTable.hasCorrespondingFunctionInvocation(token)) {
|
||||||
|
// JsInvocation functionInvocation = OperatorTable.getCorrespondingFunctionInvocation(token);
|
||||||
|
// functionInvocation.setArguments(Arrays.asList(left, right));
|
||||||
|
// return functionInvocation;
|
||||||
|
// }
|
||||||
|
// throw new AssertionError("Unsupported token encountered: " + token.toString());
|
||||||
|
// }
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
JsExpression translateIsExpression(@NotNull JetIsExpression expression) {
|
||||||
|
JsExpression left = AstUtil.convertToExpression
|
||||||
|
(Translation.translateExpression(expression.getLeftHandSide(), translationContext()));
|
||||||
|
JsExpression resultingExpression = translateTypePattern(left, (JetTypePattern) expression.getPattern());
|
||||||
|
if (expression.isNegated()) {
|
||||||
|
return AstUtil.negation(resultingExpression);
|
||||||
|
}
|
||||||
|
return resultingExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsExpression translateTypePattern(@NotNull JsExpression expressionToMatch,
|
||||||
|
@NotNull JetTypePattern pattern) {
|
||||||
|
return AstUtil.newInvocation(Namer.isOperationReference(), expressionToMatch, getClassReference(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsExpression getClassReference(@NotNull JetTypePattern pattern) {
|
||||||
|
JetTypeReference typeReference = pattern.getTypeReference();
|
||||||
|
assert typeReference != null : "Type pattern should contain a type reference";
|
||||||
|
return getClassNameReferenceForTypeReference(typeReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @NotNull
|
||||||
|
// private JsNameRef getClassReference(@NotNull JetBinaryExpressionWithTypeRHS expression) {
|
||||||
|
// JetTypeReference typeReference = expression.getRight();
|
||||||
|
// assert typeReference != null : "Binary type expression should have a right expression";
|
||||||
|
// return getClassNameReferenceForTypeReference(typeReference);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsNameRef getClassNameReferenceForTypeReference(@NotNull JetTypeReference typeReference) {
|
||||||
|
ClassDescriptor referencedClass = BindingUtils.getClassDescriptorForTypeReference
|
||||||
|
(translationContext().bindingContext(), typeReference);
|
||||||
|
//TODO should reference class by full name here
|
||||||
|
JsName className = translationContext().getNameForDescriptor(referencedClass);
|
||||||
|
return translationContext().getNamespaceQualifiedReference(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @NotNull
|
||||||
|
// private JetToken getOperationToken(@NotNull JetBinaryExpressionWithTypeRHS expression) {
|
||||||
|
// JetSimpleNameExpression operationExpression = expression.getOperationSign();
|
||||||
|
// IElementType elementType = operationExpression.getReferencedNameElementType();
|
||||||
|
// assert elementType instanceof JetToken : "Binary type operation should have IElementType of type JetToken";
|
||||||
|
// return (JetToken) elementType;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -34,10 +34,12 @@ public class KotlinLibTest extends TranslationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void kotlinJsLibRunsWithRhino() throws Exception {
|
public void kotlinJsLibRunsWithRhino() throws Exception {
|
||||||
Context context = Context.enter();
|
runRhinoTest(Arrays.asList(kotlinLibraryPath()), new RhinoResultChecker() {
|
||||||
Scriptable scope = context.initStandardObjects();
|
@Override
|
||||||
runFileWithRhino(kotlinLibraryPath(), context, scope);
|
public void runChecks(Context context, Scriptable scope) throws Exception {
|
||||||
Context.exit();
|
//do nothing
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -64,4 +66,23 @@ public class KotlinLibTest extends TranslationTest {
|
|||||||
new RhinoPropertyTypesChecker("foo", propertyToType));
|
new RhinoPropertyTypesChecker("foo", propertyToType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isSameType() throws Exception {
|
||||||
|
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("isSameType.js")),
|
||||||
|
new RhinoFunctionResultChecker("test", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAncestorType() throws Exception {
|
||||||
|
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("isAncestorType.js")),
|
||||||
|
new RhinoFunctionResultChecker("test", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isComplexTest() throws Exception {
|
||||||
|
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("isComplexTest.js")),
|
||||||
|
new RhinoFunctionResultChecker("test", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.jetbrains.k2js.test;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public class RTTITest extends AbstractClassTest {
|
||||||
|
|
||||||
|
final private static String MAIN = "rtti/";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String mainDirectory() {
|
||||||
|
return MAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isSameClass() throws Exception {
|
||||||
|
testFooBoxIsTrue("isSameClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.jetbrains.k2js.test;
|
package org.jetbrains.k2js.test;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.mozilla.javascript.Context;
|
import org.mozilla.javascript.Context;
|
||||||
import org.mozilla.javascript.Function;
|
import org.mozilla.javascript.Function;
|
||||||
import org.mozilla.javascript.NativeObject;
|
import org.mozilla.javascript.NativeObject;
|
||||||
@@ -16,27 +17,55 @@ public final class RhinoFunctionResultChecker implements RhinoResultChecker {
|
|||||||
final String functionName;
|
final String functionName;
|
||||||
final Object expectedResult;
|
final Object expectedResult;
|
||||||
|
|
||||||
public RhinoFunctionResultChecker(String namespaceName, String functionName, Object expectedResult) {
|
public RhinoFunctionResultChecker(@Nullable String namespaceName, String functionName, Object expectedResult) {
|
||||||
this.namespaceName = namespaceName;
|
this.namespaceName = namespaceName;
|
||||||
this.functionName = functionName;
|
this.functionName = functionName;
|
||||||
this.expectedResult = expectedResult;
|
this.expectedResult = expectedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RhinoFunctionResultChecker(String functionName, Object expectedResult) {
|
||||||
|
this(null, functionName, expectedResult);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runChecks(Context context, Scriptable scope) throws Exception {
|
public void runChecks(Context context, Scriptable scope) throws Exception {
|
||||||
Object result = extractAndCallFunctionObject(namespaceName, functionName, context, scope);
|
Object result = extractAndCallFunctionObject(namespaceName, functionName, context, scope);
|
||||||
assertTrue("Result is not what expected!", result.equals(expectedResult));
|
assertTrue("Result is not what expected! Exprected: " + expectedResult + " Evaluated : " + result,
|
||||||
|
result.equals(expectedResult));
|
||||||
String report = namespaceName + "." + functionName + "() = " + Context.toString(result);
|
String report = namespaceName + "." + functionName + "() = " + Context.toString(result);
|
||||||
System.out.println(report);
|
System.out.println(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object extractAndCallFunctionObject(String namespaceName, String functionName,
|
private Object extractAndCallFunctionObject(String namespaceName, String functionName,
|
||||||
Context cx, Scriptable scope) {
|
Context cx, Scriptable scope) {
|
||||||
NativeObject namespaceObject = RhinoUtils.extractObject(namespaceName, scope);
|
Object functionObject;
|
||||||
Object box = namespaceObject.get(functionName, namespaceObject);
|
if (namespaceName != null) {
|
||||||
assertTrue("Function " + functionName + " not defined in namespace " + namespaceName, box instanceof Function);
|
functionObject = extractFunctionFromObject(namespaceName, functionName, scope);
|
||||||
|
} else {
|
||||||
|
functionObject = extractFunctionFromGlobalScope(functionName, scope);
|
||||||
|
}
|
||||||
|
return callFunctionAndCheckResults(cx, scope, (Function) functionObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object callFunctionAndCheckResults(Context cx, Scriptable scope, Function functionObject) {
|
||||||
Object functionArgs[] = {};
|
Object functionArgs[] = {};
|
||||||
Function function = (Function) box;
|
return functionObject.call(cx, scope, scope, functionArgs);
|
||||||
return function.call(cx, scope, scope, functionArgs);
|
}
|
||||||
|
|
||||||
|
private Object extractFunctionFromGlobalScope(String functionName, Scriptable scope) {
|
||||||
|
Object functionObject;
|
||||||
|
functionObject = scope.get(functionName, scope);
|
||||||
|
assertTrue("Function " + functionName + " is not defined in global scope",
|
||||||
|
functionObject instanceof Function);
|
||||||
|
return functionObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object extractFunctionFromObject(String namespaceName, String functionName, Scriptable scope) {
|
||||||
|
Object functionObject;
|
||||||
|
NativeObject namespaceObject = RhinoUtils.extractObject(namespaceName, scope);
|
||||||
|
functionObject = namespaceObject.get(functionName, namespaceObject);
|
||||||
|
assertTrue("Function " + functionName + " is not defined in namespace " + namespaceName,
|
||||||
|
functionObject instanceof Function);
|
||||||
|
return functionObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import static org.junit.Assert.assertTrue;
|
|||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
*/
|
*/
|
||||||
public class RhinoPropertyTypesChecker implements RhinoResultChecker {
|
public final class RhinoPropertyTypesChecker implements RhinoResultChecker {
|
||||||
|
|
||||||
final private String objectName;
|
final private String objectName;
|
||||||
final private Map<String, Class<? extends Scriptable>> propertyToType;
|
final private Map<String, Class<? extends Scriptable>> propertyToType;
|
||||||
|
|||||||
@@ -46,12 +46,16 @@ public abstract class TranslationTest {
|
|||||||
|
|
||||||
protected void testFunctionOutput(String filename, String namespaceName,
|
protected void testFunctionOutput(String filename, String namespaceName,
|
||||||
String functionName, Object expectedResult) throws Exception {
|
String functionName, Object expectedResult) throws Exception {
|
||||||
|
translateFile(filename);
|
||||||
|
runRhinoTest(generateFilenameList(getOutputFilePath(filename)),
|
||||||
|
new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void translateFile(String filename) {
|
||||||
K2JSTranslator.Arguments args = new K2JSTranslator.Arguments();
|
K2JSTranslator.Arguments args = new K2JSTranslator.Arguments();
|
||||||
args.src = getInputFilePath(filename);
|
args.src = getInputFilePath(filename);
|
||||||
args.outputDir = getOutputFilePath(filename);
|
args.outputDir = getOutputFilePath(filename);
|
||||||
K2JSTranslator.translate(args);
|
K2JSTranslator.translate(args);
|
||||||
runRhinoTest(generateFilenameList(args.outputDir),
|
|
||||||
new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected List<String> generateFilenameList(String inputfile);
|
abstract protected List<String> generateFilenameList(String inputfile);
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
var A = Class.create();
|
||||||
|
var B = Class.create(A);
|
||||||
|
var b = new B;
|
||||||
|
|
||||||
|
test = function() {
|
||||||
|
return (isType(b, A) && isType(b, B));
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
var A = Class.create();
|
||||||
|
var B = Class.create(A);
|
||||||
|
var b = new B;
|
||||||
|
var C = Class.create(B);
|
||||||
|
var c = new C;
|
||||||
|
var E = Class.create(A)
|
||||||
|
var e = new E;
|
||||||
|
|
||||||
|
test1 = function() {
|
||||||
|
b2 = b
|
||||||
|
return (isType(b, A) && isType(b, B));
|
||||||
|
}
|
||||||
|
|
||||||
|
test2 = function() {
|
||||||
|
return (isType(c, C) && isType(c, B) && isType(c, A) && (!isType(c, E)));
|
||||||
|
}
|
||||||
|
|
||||||
|
test3 = function() {
|
||||||
|
return isType(e, E) && !isType(e, B) && !isType(e, C) && isType(e, A)
|
||||||
|
}
|
||||||
|
|
||||||
|
test = function() {
|
||||||
|
return test1() && test2() && test3()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
var A = Class.create();
|
||||||
|
var B = Class.create(A);
|
||||||
|
var C = Class.create();
|
||||||
|
var c = new C;
|
||||||
|
|
||||||
|
test = function() {
|
||||||
|
return ((!isType(c, A)) && !isType(c, B));
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
var A = Class.create();
|
||||||
|
var a = new A;
|
||||||
|
|
||||||
|
test = function() {
|
||||||
|
return isType(a, A);
|
||||||
|
}
|
||||||
@@ -6,6 +6,17 @@ function $A(iterable) {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isType = function(object, class) {
|
||||||
|
current = object.get_class();
|
||||||
|
while (current !== class) {
|
||||||
|
if (current === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
current = current.superclass;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var emptyFunction = function() {}
|
var emptyFunction = function() {}
|
||||||
|
|
||||||
var Class = (function() {
|
var Class = (function() {
|
||||||
@@ -32,10 +43,17 @@ var Class = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
klass.addMethods(
|
||||||
|
{
|
||||||
|
get_class : function () {
|
||||||
|
return klass;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
klass.addMethods(
|
klass.addMethods(
|
||||||
{
|
{
|
||||||
'super_init' : function () {
|
super_init : function () {
|
||||||
this.initializing = this.initializing.superclass;
|
this.initializing = this.initializing.superclass;
|
||||||
this.initializing.prototype.initialize.apply(this, arguments)
|
this.initializing.prototype.initialize.apply(this, arguments)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace foo
|
||||||
|
|
||||||
|
class A() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = (A() is A)
|
||||||
Reference in New Issue
Block a user