From fec7539f8c9b669f1309f940a79bf3f330744dfb Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Thu, 17 Nov 2011 14:14:47 +0400 Subject: [PATCH] Supported (Variable is Type expression) for user defined classes. --- .../google/dart/compiler/util/AstUtil.java | 4 + .../k2js/translate/AbstractTranslator.java | 12 --- .../k2js/translate/BindingUtils.java | 34 +++++-- .../k2js/translate/ExpressionVisitor.java | 14 +++ .../org/jetbrains/k2js/translate/Namer.java | 6 +- .../k2js/translate/NamespaceTranslator.java | 2 +- .../k2js/translate/OperationTranslator.java | 22 +++-- .../k2js/translate/OperatorTable.java | 27 +++++- .../jetbrains/k2js/translate/Translation.java | 5 ++ .../translate/TypeOperationTranslator.java | 90 +++++++++++++++++++ .../jetbrains/k2js/test/KotlinLibTest.java | 29 +++++- .../org/jetbrains/k2js/test/RTTITest.java | 22 +++++ .../k2js/test/RhinoFunctionResultChecker.java | 43 +++++++-- .../k2js/test/RhinoPropertyTypesChecker.java | 2 +- .../jetbrains/k2js/test/TranslationTest.java | 8 +- .../kotlinLib/cases/isAncestorType.js | 7 ++ .../kotlinLib/cases/isComplexTest.js | 24 +++++ .../kotlinLib/cases/isNotOtherType.js | 8 ++ .../testFiles/kotlinLib/cases/isSameType.js | 6 ++ translator/testFiles/kotlin_lib.js | 20 ++++- .../testFiles/rtti/cases/isSameClass.kt | 7 ++ 21 files changed, 348 insertions(+), 44 deletions(-) create mode 100644 translator/src/org/jetbrains/k2js/translate/TypeOperationTranslator.java create mode 100644 translator/test/org/jetbrains/k2js/test/RTTITest.java create mode 100644 translator/testFiles/kotlinLib/cases/isAncestorType.js create mode 100644 translator/testFiles/kotlinLib/cases/isComplexTest.js create mode 100644 translator/testFiles/kotlinLib/cases/isNotOtherType.js create mode 100644 translator/testFiles/kotlinLib/cases/isSameType.js create mode 100644 translator/testFiles/rtti/cases/isSameClass.kt diff --git a/js/src/com/google/dart/compiler/util/AstUtil.java b/js/src/com/google/dart/compiler/util/AstUtil.java index 2ea618c8bea..a1ba71ce077 100644 --- a/js/src/com/google/dart/compiler/util/AstUtil.java +++ b/js/src/com/google/dart/compiler/util/AstUtil.java @@ -268,4 +268,8 @@ public class AstUtil { result.setStatements(statements); return result; } + + public static JsPrefixOperation negation(JsExpression expression) { + return new JsPrefixOperation(JsUnaryOperator.NOT, expression); + } } diff --git a/translator/src/org/jetbrains/k2js/translate/AbstractTranslator.java b/translator/src/org/jetbrains/k2js/translate/AbstractTranslator.java index 6072b4c4b23..6f44e0846db 100644 --- a/translator/src/org/jetbrains/k2js/translate/AbstractTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/AbstractTranslator.java @@ -1,9 +1,7 @@ package org.jetbrains.k2js.translate; 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.jet.lang.resolve.BindingContext; /** * @author Talanov Pavel @@ -26,14 +24,4 @@ public abstract class AbstractTranslator { protected TranslationContext translationContext() { return context; } - - @NotNull - protected BindingContext bindingContext() { - return context.bindingContext(); - } - - @NotNull - protected JsScope scope() { - return context.enclosingScope(); - } } diff --git a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java index 42e183eb81b..794cd6ecb28 100644 --- a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java @@ -91,17 +91,23 @@ public final class BindingUtils { Collection superclassTypes = classDescriptor.getTypeConstructor().getSupertypes(); List superClassDescriptors = new ArrayList(); for (JetType type : superclassTypes) { - DeclarationDescriptor superClassDescriptor = - type.getConstructor().getDeclarationDescriptor(); - assert superClassDescriptor instanceof ClassDescriptor - : "Superclass descriptor of a type should be of type ClassDescriptor"; - if (isNotAny(superClassDescriptor)) { - superClassDescriptors.add((ClassDescriptor) superClassDescriptor); + ClassDescriptor result = getClassDescriptorForType(type); + if (isNotAny(result)) { + superClassDescriptors.add(result); } } 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) { List superclassDescriptors = getSuperclassDescriptors(context, classDeclaration); return (findAncestorClass(superclassDescriptors) != null); @@ -113,8 +119,22 @@ public final class BindingUtils { 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? - private static boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) { + static private boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) { return !superClassDescriptor.getName().equals("Any"); } diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java index a72ad7771ea..a83dc2301b6 100644 --- a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java @@ -350,5 +350,19 @@ public final class ExpressionVisitor extends TranslatorVisitor { } +// @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); + } + } diff --git a/translator/src/org/jetbrains/k2js/translate/Namer.java b/translator/src/org/jetbrains/k2js/translate/Namer.java index 676ff9f2a48..533bfa6a411 100644 --- a/translator/src/org/jetbrains/k2js/translate/Namer.java +++ b/translator/src/org/jetbrains/k2js/translate/Namer.java @@ -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 { @@ -71,5 +71,9 @@ public final class Namer { return AstUtil.newQualifiedNameRef("Trait.create"); } + public static JsNameRef isOperationReference() { + return AstUtil.newQualifiedNameRef("isType"); + } + } diff --git a/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java b/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java index 492d9402374..d5f4606efea 100644 --- a/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java @@ -33,7 +33,7 @@ public final class NamespaceTranslator extends AbstractTranslator { public JsBlock translate(@NotNull JetNamespace namespace) { // TODO support multiple namespaces 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)); TranslationContext newContext = translationContext().newNamespace(namespace); JsFunction dummyFunction = JsFunction.getAnonymousFunctionWithScope diff --git a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java index 9fd3af25a71..11420e841b4 100644 --- a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java @@ -80,18 +80,21 @@ public final class OperationTranslator extends AbstractTranslator { return setterCall; } - @NotNull - private JetToken getOperationToken(@NotNull JetBinaryExpression expression) { - return (JetToken) expression.getOperationToken(); - } - @NotNull private JsExpression translateAsBinaryOperation(@NotNull JetBinaryExpression expression) { JsExpression left = AstUtil.convertToExpression (Translation.translateExpression(expression.getLeft(), translationContext())); JsExpression right = translateRightExpression(expression); - JetToken jetOperationToken = getOperationToken(expression); - return new JsBinaryOperation(OperatorTable.getBinaryOperator(jetOperationToken), left, right); + JetToken token = getOperationToken(expression); + 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 @@ -102,5 +105,10 @@ public final class OperationTranslator extends AbstractTranslator { (Translation.translateExpression(rightExpression, translationContext())); } + @NotNull + private JetToken getOperationToken(@NotNull JetBinaryExpression expression) { + return (JetToken) expression.getOperationToken(); + } + } diff --git a/translator/src/org/jetbrains/k2js/translate/OperatorTable.java b/translator/src/org/jetbrains/k2js/translate/OperatorTable.java index d9970e7122a..748f86441e6 100644 --- a/translator/src/org/jetbrains/k2js/translate/OperatorTable.java +++ b/translator/src/org/jetbrains/k2js/translate/OperatorTable.java @@ -1,7 +1,10 @@ package org.jetbrains.k2js.translate; 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.util.AstUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; @@ -14,9 +17,9 @@ import java.util.Map; */ public final class OperatorTable { - private static Map binaryOperatorsMap = new HashMap(); private static Map unaryOperatorsMap = new HashMap(); + private static Map operatorToFunctionNameReference = new HashMap(); static { unaryOperatorsMap.put(JetTokens.PLUSPLUS, JsUnaryOperator.INC); //++ @@ -43,6 +46,27 @@ public final class OperatorTable { 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 public static JsBinaryOperator getBinaryOperator(@NotNull JetToken token) { assert JetTokens.OPERATIONS.contains(token) : "Token should represent an operation!"; @@ -59,4 +83,5 @@ public final class OperatorTable { return (token == JetTokens.EQ); } + } diff --git a/translator/src/org/jetbrains/k2js/translate/Translation.java b/translator/src/org/jetbrains/k2js/translate/Translation.java index 5c9d7749b18..f6f4f4b22a0 100644 --- a/translator/src/org/jetbrains/k2js/translate/Translation.java +++ b/translator/src/org/jetbrains/k2js/translate/Translation.java @@ -46,6 +46,11 @@ public final class Translation { return DeclarationTranslator.newInstance(context); } + @NotNull + static public TypeOperationTranslator typeOperationTranslator(@NotNull TranslationContext context) { + return TypeOperationTranslator.newInstance(context); + } + @NotNull static public JsNode translateExpression(@NotNull JetExpression expression, @NotNull TranslationContext context) { return expressionTranslator(context).translate(expression); diff --git a/translator/src/org/jetbrains/k2js/translate/TypeOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/TypeOperationTranslator.java new file mode 100644 index 00000000000..11e3aa1750a --- /dev/null +++ b/translator/src/org/jetbrains/k2js/translate/TypeOperationTranslator.java @@ -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; +// } + + +} diff --git a/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java b/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java index 249a9ba7c2c..9fd8b52ce4f 100644 --- a/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java +++ b/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java @@ -34,10 +34,12 @@ public class KotlinLibTest extends TranslationTest { @Test public void kotlinJsLibRunsWithRhino() throws Exception { - Context context = Context.enter(); - Scriptable scope = context.initStandardObjects(); - runFileWithRhino(kotlinLibraryPath(), context, scope); - Context.exit(); + runRhinoTest(Arrays.asList(kotlinLibraryPath()), new RhinoResultChecker() { + @Override + public void runChecks(Context context, Scriptable scope) throws Exception { + //do nothing + } + }); } @Test @@ -64,4 +66,23 @@ public class KotlinLibTest extends TranslationTest { 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)); + } + + } diff --git a/translator/test/org/jetbrains/k2js/test/RTTITest.java b/translator/test/org/jetbrains/k2js/test/RTTITest.java new file mode 100644 index 00000000000..517451f1a69 --- /dev/null +++ b/translator/test/org/jetbrains/k2js/test/RTTITest.java @@ -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"); + } + +} diff --git a/translator/test/org/jetbrains/k2js/test/RhinoFunctionResultChecker.java b/translator/test/org/jetbrains/k2js/test/RhinoFunctionResultChecker.java index 5b0fb36bd09..34a40a3ae17 100644 --- a/translator/test/org/jetbrains/k2js/test/RhinoFunctionResultChecker.java +++ b/translator/test/org/jetbrains/k2js/test/RhinoFunctionResultChecker.java @@ -1,5 +1,6 @@ package org.jetbrains.k2js.test; +import org.jetbrains.annotations.Nullable; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.NativeObject; @@ -16,27 +17,55 @@ public final class RhinoFunctionResultChecker implements RhinoResultChecker { final String functionName; final Object expectedResult; - public RhinoFunctionResultChecker(String namespaceName, String functionName, Object expectedResult) { + public RhinoFunctionResultChecker(@Nullable String namespaceName, String functionName, Object expectedResult) { this.namespaceName = namespaceName; this.functionName = functionName; this.expectedResult = expectedResult; } + public RhinoFunctionResultChecker(String functionName, Object expectedResult) { + this(null, functionName, expectedResult); + } + @Override public void runChecks(Context context, Scriptable scope) throws Exception { 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); System.out.println(report); } private Object extractAndCallFunctionObject(String namespaceName, String functionName, Context cx, Scriptable scope) { - NativeObject namespaceObject = RhinoUtils.extractObject(namespaceName, scope); - Object box = namespaceObject.get(functionName, namespaceObject); - assertTrue("Function " + functionName + " not defined in namespace " + namespaceName, box instanceof Function); + Object functionObject; + if (namespaceName != null) { + 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[] = {}; - Function function = (Function) box; - return function.call(cx, scope, scope, functionArgs); + return functionObject.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; } } diff --git a/translator/test/org/jetbrains/k2js/test/RhinoPropertyTypesChecker.java b/translator/test/org/jetbrains/k2js/test/RhinoPropertyTypesChecker.java index 8e25bb880c3..a9e1ab2a723 100644 --- a/translator/test/org/jetbrains/k2js/test/RhinoPropertyTypesChecker.java +++ b/translator/test/org/jetbrains/k2js/test/RhinoPropertyTypesChecker.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertTrue; /** * @author Talanov Pavel */ -public class RhinoPropertyTypesChecker implements RhinoResultChecker { +public final class RhinoPropertyTypesChecker implements RhinoResultChecker { final private String objectName; final private Map> propertyToType; diff --git a/translator/test/org/jetbrains/k2js/test/TranslationTest.java b/translator/test/org/jetbrains/k2js/test/TranslationTest.java index 8263ca5c11b..3a6454b59ea 100644 --- a/translator/test/org/jetbrains/k2js/test/TranslationTest.java +++ b/translator/test/org/jetbrains/k2js/test/TranslationTest.java @@ -46,12 +46,16 @@ public abstract class TranslationTest { protected void testFunctionOutput(String filename, String namespaceName, 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(); args.src = getInputFilePath(filename); args.outputDir = getOutputFilePath(filename); K2JSTranslator.translate(args); - runRhinoTest(generateFilenameList(args.outputDir), - new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult)); } abstract protected List generateFilenameList(String inputfile); diff --git a/translator/testFiles/kotlinLib/cases/isAncestorType.js b/translator/testFiles/kotlinLib/cases/isAncestorType.js new file mode 100644 index 00000000000..29fea2ff1b1 --- /dev/null +++ b/translator/testFiles/kotlinLib/cases/isAncestorType.js @@ -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)); +} \ No newline at end of file diff --git a/translator/testFiles/kotlinLib/cases/isComplexTest.js b/translator/testFiles/kotlinLib/cases/isComplexTest.js new file mode 100644 index 00000000000..c935e77afc0 --- /dev/null +++ b/translator/testFiles/kotlinLib/cases/isComplexTest.js @@ -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() +} \ No newline at end of file diff --git a/translator/testFiles/kotlinLib/cases/isNotOtherType.js b/translator/testFiles/kotlinLib/cases/isNotOtherType.js new file mode 100644 index 00000000000..624f1584c89 --- /dev/null +++ b/translator/testFiles/kotlinLib/cases/isNotOtherType.js @@ -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)); +} \ No newline at end of file diff --git a/translator/testFiles/kotlinLib/cases/isSameType.js b/translator/testFiles/kotlinLib/cases/isSameType.js new file mode 100644 index 00000000000..bb8dfb4e7db --- /dev/null +++ b/translator/testFiles/kotlinLib/cases/isSameType.js @@ -0,0 +1,6 @@ +var A = Class.create(); +var a = new A; + +test = function() { + return isType(a, A); +} \ No newline at end of file diff --git a/translator/testFiles/kotlin_lib.js b/translator/testFiles/kotlin_lib.js index 2e100bfc744..9eccea4f81b 100644 --- a/translator/testFiles/kotlin_lib.js +++ b/translator/testFiles/kotlin_lib.js @@ -6,6 +6,17 @@ function $A(iterable) { 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 Class = (function() { @@ -32,10 +43,17 @@ var Class = (function() { } + klass.addMethods( + { + get_class : function () { + return klass; + } + }); + if (parent != null) { klass.addMethods( { - 'super_init' : function () { + super_init : function () { this.initializing = this.initializing.superclass; this.initializing.prototype.initialize.apply(this, arguments) } diff --git a/translator/testFiles/rtti/cases/isSameClass.kt b/translator/testFiles/rtti/cases/isSameClass.kt new file mode 100644 index 00000000000..49517d74b05 --- /dev/null +++ b/translator/testFiles/rtti/cases/isSameClass.kt @@ -0,0 +1,7 @@ +namespace foo + +class A() { + +} + +fun box() = (A() is A) \ No newline at end of file