Requested only one commit pull request (was: https://github.com/JetBrains/kotlin/pull/59/files).

Note: all tests passed, but I haven't tested this build in real life (opposite to my master branch).

Don't remember about critical issue — http://youtrack.jetbrains.com/issue/KT-2154 Fix for this issue is not included in this patch (because unrelated). Fix for it and for all other unrelated changes will be opened as separated pull-requests.
This commit is contained in:
develar
2012-06-04 18:12:38 +04:00
committed by pTalanov
parent 184d3fb16e
commit d4d300d0e9
57 changed files with 1006 additions and 794 deletions
@@ -26,8 +26,8 @@ import org.jetbrains.k2js.test.rhino.RhinoResultChecker;
import org.jetbrains.k2js.test.utils.TranslationUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
@@ -44,6 +44,8 @@ public abstract class BasicTest extends TestWithEnvironment {
private static final String CASES = "cases/";
private static final String OUT = "out/";
private static final String KOTLIN_JS_LIB = pathToTestFilesRoot() + "kotlin_lib.js";
private static final String KOTLIN_JS_LIB_ECMA_3 = pathToTestFilesRoot() + "kotlin_lib_ecma3.js";
private static final String KOTLIN_JS_LIB_ECMA_5 = pathToTestFilesRoot() + "kotlin_lib_ecma5.js";
private static final String EXPECTED = "expected/";
@NotNull
@@ -87,28 +89,32 @@ public abstract class BasicTest extends TestWithEnvironment {
assert success;
}
protected List<String> additionalJSFiles() {
return Collections.singletonList(KOTLIN_JS_LIB);
protected List<String> additionalJSFiles(EcmaVersion ecmaVersion) {
List<String> list = new ArrayList<String>(2);
list.add(ecmaVersion == EcmaVersion.v5 ? KOTLIN_JS_LIB_ECMA_5 : KOTLIN_JS_LIB_ECMA_3);
list.add(KOTLIN_JS_LIB);
return list;
}
protected void generateJavaScriptFiles(@NotNull String kotlinFilename,
@NotNull MainCallParameters mainCallParameters,
@NotNull EnumSet<EcmaVersion> ecmaVersions) throws Exception {
@NotNull Iterable<EcmaVersion> ecmaVersions) throws Exception {
generateJavaScriptFiles(Collections.singletonList(getInputFilePath(kotlinFilename)), kotlinFilename, mainCallParameters,
ecmaVersions);
}
protected void generateJavaScriptFiles(@NotNull List<String> files, @NotNull String testName,
@NotNull MainCallParameters mainCallParameters, @NotNull EnumSet<EcmaVersion> ecmaVersions)
@NotNull MainCallParameters mainCallParameters, @NotNull Iterable<EcmaVersion> ecmaVersions)
throws Exception {
for (EcmaVersion version : ecmaVersions) {
TranslationUtils.translateFiles(getProject(), files, getOutputFilePath(testName, version), mainCallParameters, version);
}
}
protected void runRhinoTests(@NotNull List<String> outputFilePaths, @NotNull RhinoResultChecker checker) throws Exception {
for (String outputFilePath : outputFilePaths) {
runRhinoTest(withAdditionalFiles(outputFilePath), checker, getRhinoTestVariables());
protected void runRhinoTests(@NotNull String filename, @NotNull Iterable<EcmaVersion> ecmaVersions, @NotNull RhinoResultChecker checker) throws Exception {
for (EcmaVersion ecmaVersion : ecmaVersions) {
runRhinoTest(withAdditionalFiles(getOutputFilePath(filename, ecmaVersion), ecmaVersion), checker, getRhinoTestVariables(),
ecmaVersion);
}
}
@@ -155,21 +161,12 @@ public abstract class BasicTest extends TestWithEnvironment {
}
@NotNull
protected List<String> withAdditionalFiles(@NotNull String inputFile) {
List<String> allFiles = Lists.newArrayList(additionalJSFiles());
protected List<String> withAdditionalFiles(@NotNull String inputFile, EcmaVersion ecmaVersion) {
List<String> allFiles = Lists.newArrayList(additionalJSFiles(ecmaVersion));
allFiles.add(inputFile);
return allFiles;
}
@NotNull
protected List<String> getOutputFilePaths(@NotNull String filename, @NotNull EnumSet<EcmaVersion> ecmaVersions) {
List<String> result = Lists.newArrayList();
for (EcmaVersion ecmaVersion : ecmaVersions) {
result.add(getOutputFilePath(filename, ecmaVersion));
}
return result;
}
@NotNull
protected String getOutputFilePath(@NotNull String filename, @NotNull EcmaVersion ecmaVersion) {
return getOutputPath() + convertFileNameToDotJsFile(filename, ecmaVersion);
@@ -51,8 +51,7 @@ public abstract class MultipleFilesTranslationTest extends BasicTest {
@NotNull Object expectedResult)
throws Exception {
generateJsFromDir(dirName, ecmaVersions);
runRhinoTests(getOutputFilePaths(dirName + ".kt", ecmaVersions),
new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult));
runRhinoTests(dirName + ".kt", ecmaVersions, new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult));
}
public void checkFooBoxIsTrue(@NotNull String dirName) throws Exception {
@@ -47,8 +47,7 @@ public abstract class SingleFileTranslationTest extends BasicTest {
@NotNull String functionName,
@NotNull Object expectedResult) throws Exception {
generateJavaScriptFiles(kotlinFilename, MainCallParameters.noCall(), ecmaVersions);
runRhinoTests(getOutputFilePaths(kotlinFilename, ecmaVersions),
new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult));
runRhinoTests(kotlinFilename, ecmaVersions, new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult));
}
public void checkFooBoxIsTrue(@NotNull String filename, @NotNull EnumSet<EcmaVersion> ecmaVersions) throws Exception {
@@ -82,7 +81,7 @@ public abstract class SingleFileTranslationTest extends BasicTest {
@NotNull EnumSet<EcmaVersion> ecmaVersions,
String... args) throws Exception {
generateJavaScriptFiles(kotlinFilename, MainCallParameters.mainWithArguments(Lists.newArrayList(args)), ecmaVersions);
runRhinoTests(getOutputFilePaths(kotlinFilename, ecmaVersions), new RhinoSystemOutputChecker(expectedResult));
runRhinoTests(kotlinFilename, ecmaVersions, new RhinoSystemOutputChecker(expectedResult));
}
protected void performTestWithMain(@NotNull EnumSet<EcmaVersion> ecmaVersions,
@@ -21,7 +21,6 @@ import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author Pavel Talanov
@@ -61,7 +60,7 @@ public class RhinoFunctionResultChecker implements RhinoResultChecker {
private String functionCallString() {
String result = functionName + "()";
if (namespaceName != null) {
result = namespaceName + "." + result;
result = "Kotlin.defs." + namespaceName + "." + result;
}
return result;
}
@@ -17,6 +17,8 @@
package org.jetbrains.k2js.test.rhino;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.config.EcmaVersion;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
@@ -48,13 +50,19 @@ public final class RhinoUtils {
public static void runRhinoTest(@NotNull List<String> fileNames,
@NotNull RhinoResultChecker checker) throws Exception {
runRhinoTest(fileNames, checker, null);
runRhinoTest(fileNames, checker, null, EcmaVersion.defaultVersion());
}
public static void runRhinoTest(@NotNull List<String> fileNames,
@NotNull RhinoResultChecker checker,
Map<String,Object> variables) throws Exception {
@Nullable Map<String, Object> variables,
@NotNull EcmaVersion ecmaVersion) throws Exception {
Context context = Context.enter();
if (ecmaVersion == EcmaVersion.v5) {
// actually, currently, doesn't matter because dart doesn't produce js 1.8 code (expression closures)
context.setLanguageVersion(Context.VERSION_1_8);
}
Scriptable scope = context.initStandardObjects();
if (variables != null) {
Set<Map.Entry<String,Object>> entries = variables.entrySet();
@@ -18,12 +18,11 @@ package org.jetbrains.k2js.test.semantics;
import junit.framework.Test;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.test.BasicTest;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import org.jetbrains.k2js.translate.context.Namer;
import static org.jetbrains.k2js.test.utils.JsTestUtils.failsOnEcmaV5;
@SuppressWarnings("JUnitTestCaseWithNoTests")
public final class ExamplesTest extends SingleFileTranslationTest {
@@ -38,7 +37,7 @@ public final class ExamplesTest extends SingleFileTranslationTest {
@Override
public void runTest() throws Exception {
runFunctionOutputTest(failsOnEcmaV5(), filename, Namer.getRootNamespaceName(), "box", "OK");
runFunctionOutputTest(EcmaVersion.all(), filename, Namer.getRootNamespaceName(), "box", "OK");
}
public static Test suite() throws Exception {
@@ -18,8 +18,6 @@ package org.jetbrains.k2js.test.semantics;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import static org.jetbrains.k2js.test.utils.JsTestUtils.failsOnEcmaV5;
/**
* @author Pavel Talanov
*/
@@ -30,14 +28,14 @@ public final class ExtensionPropertyTest extends SingleFileTranslationTest {
}
public void testSimplePropertyWithGetter() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
public void testPropertyWithGetterAndSetter() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
public void testAbsExtension() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.k2js.test.semantics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import org.jetbrains.k2js.test.rhino.RhinoFunctionResultChecker;
import org.jetbrains.k2js.test.rhino.RhinoResultChecker;
@@ -35,7 +36,7 @@ public final class KotlinLibTest extends SingleFileTranslationTest {
}
public void testKotlinJsLibRunsWithRhino() throws Exception {
runRhinoTest(additionalJSFiles(), new RhinoResultChecker() {
runRhinoTest(additionalJSFiles(EcmaVersion.v3), new RhinoResultChecker() {
@Override
public void runChecks(Context context, Scriptable scope) throws Exception {
//do nothing
@@ -83,7 +84,7 @@ public final class KotlinLibTest extends SingleFileTranslationTest {
private void runJavascriptTest(@NotNull String filename) throws Exception {
runRhinoTest(withAdditionalFiles(cases(filename)),
runRhinoTest(withAdditionalFiles(cases(filename), EcmaVersion.v3),
new RhinoFunctionResultChecker("test", true));
}
@@ -20,8 +20,6 @@ import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.translate.context.Namer;
import org.mozilla.javascript.JavaScriptException;
import static org.jetbrains.k2js.test.utils.JsTestUtils.failsOnEcmaV5;
/**
* @author Pavel Talanov
* <p/>
@@ -38,7 +36,7 @@ public final class MiscTest extends AbstractExpressionTest {
}
public void testIntRange() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
@@ -47,7 +45,7 @@ public final class MiscTest extends AbstractExpressionTest {
}
public void testClassWithoutNamespace() throws Exception {
runFunctionOutputTest(failsOnEcmaV5(), "classWithoutNamespace.kt", Namer.getRootNamespaceName(), "box", true);
runFunctionOutputTest("classWithoutNamespace.kt", Namer.getRootNamespaceName(), "box", true);
}
public void testIfElseAsExpressionWithThrow() throws Exception {
@@ -73,7 +71,7 @@ public final class MiscTest extends AbstractExpressionTest {
}
public void testKt740_2() throws Exception {
checkFooBoxIsOk(failsOnEcmaV5(), "KT-740-2.kt");
checkFooBoxIsOk("KT-740-2.kt");
}
public void testKt1361_1() throws Exception {
@@ -89,7 +87,7 @@ public final class MiscTest extends AbstractExpressionTest {
}
public void testKt740_3() throws Exception {
checkFooBoxIsOk(failsOnEcmaV5(), "KT-740-3.kt");
checkFooBoxIsOk("KT-740-3.kt");
}
public void testFunInConstructor() throws Exception {
@@ -109,11 +107,11 @@ public final class MiscTest extends AbstractExpressionTest {
}
public void testExtensionLiteralCreatedAtNamespaceLevel() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
public void testTemporaryVariableCreatedInNamespaceInitializer() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
public void testWhenReturnedWithoutBlock() throws Exception {
@@ -37,8 +37,8 @@ public final class NativeInteropTest extends SingleFileTranslationTest {
}
@Override
protected List<String> additionalJSFiles() {
List<String> result = Lists.newArrayList(super.additionalJSFiles());
protected List<String> additionalJSFiles(EcmaVersion ecmaVersion) {
List<String> result = Lists.newArrayList(super.additionalJSFiles(ecmaVersion));
result.addAll(JsTestUtils.getAllFilesInDir(pathToTestFiles() + NATIVE));
return result;
}
@@ -18,8 +18,6 @@ package org.jetbrains.k2js.test.semantics;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import static org.jetbrains.k2js.test.utils.JsTestUtils.failsOnEcmaV5;
/**
* @author Pavel Talanov
*/
@@ -60,7 +58,7 @@ public final class OperatorOverloadingTest extends SingleFileTranslationTest {
public void testOperatorOverloadOnPropertyCallGetterAndSetterOnlyOnce() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
@@ -16,9 +16,10 @@
package org.jetbrains.k2js.test.semantics;
import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import static org.jetbrains.k2js.test.utils.JsTestUtils.failsOnEcmaV5;
import java.util.EnumSet;
/**
* @author Pavel Talanov
@@ -45,12 +46,12 @@ public final class PropertyAccessTest extends SingleFileTranslationTest {
public void testCustomGetter() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
public void testCustomSetter() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
public void testNamespacePropertyInitializer() throws Exception {
@@ -63,7 +64,7 @@ public final class PropertyAccessTest extends SingleFileTranslationTest {
}
public void testNamespaceCustomAccessors() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
@@ -74,4 +75,8 @@ public final class PropertyAccessTest extends SingleFileTranslationTest {
public void testExtensionLiteralSafeCall() throws Exception {
fooBoxTest();
}
public void testInitInstanceProperties() throws Exception {
fooBoxTest(EnumSet.of(EcmaVersion.v5));
}
}
@@ -18,8 +18,6 @@ package org.jetbrains.k2js.test.semantics;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import static org.jetbrains.k2js.test.utils.JsTestUtils.failsOnEcmaV5;
/**
* @author Pavel Talanov
*/
@@ -30,12 +28,12 @@ public final class RangeTest extends SingleFileTranslationTest {
}
public void testExplicitRange() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
public void testRangeSugarSyntax() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
@@ -18,8 +18,6 @@ package org.jetbrains.k2js.test.semantics;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import static org.jetbrains.k2js.test.utils.JsTestUtils.failsOnEcmaV5;
/**
* @author Pavel Talanov
*/
@@ -45,7 +43,7 @@ public final class StandardClassesTest extends SingleFileTranslationTest {
public void testArrayFunctionConstructor() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
@@ -62,6 +60,6 @@ public final class StandardClassesTest extends SingleFileTranslationTest {
public void testArraysIterator() throws Exception {
fooBoxTest(failsOnEcmaV5());
fooBoxTest();
}
}
}
@@ -21,7 +21,6 @@ import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.facade.MainCallParameters;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import org.jetbrains.k2js.test.rhino.RhinoFunctionNativeObjectResultChecker;
import org.jetbrains.k2js.test.rhino.RhinoFunctionResultChecker;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -44,11 +43,11 @@ public final class StdLibTest extends SingleFileTranslationTest {
@Override
protected void generateJavaScriptFiles(@NotNull String kotlinFilename,
@NotNull MainCallParameters mainCallParameters,
@NotNull EnumSet<EcmaVersion> ecmaVersions) throws Exception {
@NotNull Iterable<EcmaVersion> ecmaVersions) throws Exception {
List<String> files = Arrays.asList(getInputFilePath(kotlinFilename));
generateJavaScriptFiles(files, kotlinFilename, mainCallParameters, ecmaVersions);
runRhinoTests(getOutputFilePaths(kotlinFilename, ecmaVersions),
runRhinoTests(kotlinFilename, ecmaVersions,
new RhinoFunctionNativeObjectResultChecker("test.browser", "foo", "Some Dynamically Created Content!!!"));
}
@@ -17,6 +17,7 @@
package org.jetbrains.k2js.test.semantics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import org.mozilla.javascript.EcmaError;
@@ -18,8 +18,6 @@ package org.jetbrains.k2js.test.semantics;
import org.jetbrains.k2js.test.SingleFileTranslationTest;
import static org.jetbrains.k2js.test.utils.JsTestUtils.failsOnEcmaV5;
/**
* @author Pavel Talanov
*/
@@ -35,11 +33,11 @@ public final class WebDemoExamples2Test extends SingleFileTranslationTest {
}
public void testLife() throws Exception {
performTestWithMain(failsOnEcmaV5(), "life", "", "2");
performTestWithMain("life", "", "2");
}
public void testBuilder() throws Exception {
performTestWithMain(failsOnEcmaV5(), "builder", "");
performTestWithMain(failsOnEcmaV5(), "builder", "1", "over9000");
performTestWithMain("builder", "");
performTestWithMain("builder", "1", "over9000");
}
}
@@ -50,7 +50,6 @@ public final class JsTestUtils {
return failsOn(EcmaVersion.v5);
}
@NotNull
public static String convertFileNameToDotJsFile(@NotNull String filename, EcmaVersion ecmaVersion) {
String postFix = "_" + ecmaVersion.toString() + ".js";
@@ -57,7 +57,6 @@ public final class TranslationUtils {
JsProgram program = getTranslator(project, version).generateProgram(psiFiles, mainCallParameters);
FileWriter writer = new FileWriter(new File(outputFile));
try {
writer.write("\"use strict\";\n");
writer.write(CodeGenerator.toString(program));
}
finally {
@@ -30,10 +30,10 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
public final class Namer {
private static final String INITIALIZE_METHOD_NAME = "initialize";
private static final String CLASS_OBJECT_NAME = "Class";
private static final String TRAIT_OBJECT_NAME = "Trait";
private static final String NAMESPACE_OBJECT_NAME = "Namespace";
private static final String OBJECT_OBJECT_NAME = "object";
private static final String CLASS_OBJECT_NAME = "createClass";
private static final String TRAIT_OBJECT_NAME = "createTrait";
private static final String NAMESPACE_OBJECT_NAME = "createNamespace";
private static final String OBJECT_OBJECT_NAME = "createObject";
private static final String SETTER_PREFIX = "set_";
private static final String GETTER_PREFIX = "get_";
private static final String BACKING_FIELD_PREFIX = "$";
@@ -70,7 +70,11 @@ public final class Namer {
}
@NotNull
public static String getNameForAccessor(@NotNull String propertyName, boolean isGetter) {
public static String getNameForAccessor(@NotNull String propertyName, boolean isGetter, boolean useNativeAccessor) {
if (useNativeAccessor) {
return propertyName;
}
if (isGetter) {
return getNameForGetter(propertyName);
}
@@ -112,6 +116,12 @@ public final class Namer {
@NotNull
private final JsName objectName;
@NotNull
private final JsName isTypeName;
@NotNull
private final JsPropertyInitializer writablePropertyDescriptorField;
private Namer(@NotNull JsScope rootScope) {
kotlinName = rootScope.declareName(KOTLIN_OBJECT_NAME);
kotlinScope = new JsScope(rootScope, "Kotlin standard object");
@@ -119,26 +129,30 @@ public final class Namer {
namespaceName = kotlinScope.declareName(NAMESPACE_OBJECT_NAME);
className = kotlinScope.declareName(CLASS_OBJECT_NAME);
objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME);
isTypeName = kotlinScope.declareName("isType");
writablePropertyDescriptorField = new JsPropertyInitializer(new JsNameRef("writable"), rootScope.getProgram().getTrueLiteral());
}
@NotNull
public JsExpression classCreationMethodReference() {
return kotlin(createMethodReference(className));
return kotlin(className);
}
@NotNull
public JsExpression traitCreationMethodReference() {
return kotlin(createMethodReference(traitName));
return kotlin(traitName);
}
@NotNull
public JsExpression namespaceCreationMethodReference() {
return kotlin(createMethodReference(namespaceName));
return kotlin(namespaceName);
}
@NotNull
public JsExpression objectCreationMethodReference() {
return kotlin(createMethodReference(objectName));
return kotlin(objectName);
}
@NotNull
@@ -149,17 +163,15 @@ public final class Namer {
}
@NotNull
private static JsNameRef createMethodReference(@NotNull JsName name) {
JsNameRef qualifier = name.makeRef();
JsNameRef reference = AstUtil.newQualifiedNameRef("create");
setQualifier(reference, qualifier);
private JsExpression kotlin(@NotNull JsName name) {
JsNameRef reference = name.makeRef();
reference.setQualifier(kotlinName.makeRef());
return reference;
}
@NotNull
private JsExpression kotlin(@NotNull JsExpression reference) {
JsNameRef kotlinReference = kotlinName.makeRef();
setQualifier(reference, kotlinReference);
setQualifier(reference, kotlinName.makeRef());
return reference;
}
@@ -170,7 +182,12 @@ public final class Namer {
@NotNull
public JsExpression isOperationReference() {
return kotlin(AstUtil.newQualifiedNameRef("isType"));
return kotlin(isTypeName);
}
@NotNull
public JsPropertyInitializer writablePropertyDescriptorField() {
return writablePropertyDescriptorField;
}
@NotNull
@@ -30,6 +30,7 @@ import org.jetbrains.k2js.translate.context.generator.Rule;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import org.jetbrains.k2js.translate.utils.PredefinedAnnotation;
import java.util.Map;
@@ -200,10 +201,13 @@ public final class StaticContext {
return null;
}
boolean isGetter = descriptor instanceof PropertyGetterDescriptor;
String propertyName = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty().getName().getName();
String accessorName = Namer.getNameForAccessor(propertyName, isGetter);
final PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) descriptor;
String propertyName = accessorDescriptor.getCorrespondingProperty().getName().getName();
String accessorName = Namer.getNameForAccessor(propertyName, isGetter, !accessorDescriptor.getReceiverParameter().exists() && isEcma5());
NamingScope enclosingScope = getEnclosingScope(descriptor);
return enclosingScope.declareObfuscatableName(accessorName);
return isEcma5()
? enclosingScope.declareUnobfuscatableName(accessorName)
: enclosingScope.declareObfuscatableName(accessorName);
}
};
@@ -232,9 +236,7 @@ public final class StaticContext {
NamingScope enclosingScope = getEnclosingScope(descriptor);
if (isEcma5()) {
String name = descriptor.getName().getName();
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
if (!isDefaultAccessor(propertyDescriptor.getGetter()) || !isDefaultAccessor(propertyDescriptor.getSetter())) {
// _ is more preferable than $ should be discussed later
if (JsDescriptorUtils.isAsPrivate((PropertyDescriptor) descriptor)) {
name = '_' + name;
}
@@ -244,10 +246,6 @@ public final class StaticContext {
return enclosingScope.declareObfuscatableName(Namer.getKotlinBackingFieldName(descriptor.getName().getName()));
}
}
private boolean isDefaultAccessor(PropertyAccessorDescriptor accessorDescriptor) {
return accessorDescriptor == null || accessorDescriptor.isDefault();
}
};
//TODO: hack!
Rule<JsName> toStringHack = new Rule<JsName>() {
@@ -128,7 +128,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
@NotNull
private JsStatement generateDeclaration(@NotNull JetClass declaration) {
JsName localClassName = generateLocalAlias(declaration);
JsInvocation classDeclarationExpression =
JsExpression classDeclarationExpression =
Translation.translateClassDeclaration(declaration, localToGlobalClassName.inverse(), context());
return newVar(localClassName, classDeclarationExpression);
}
@@ -30,6 +30,7 @@ import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.ArrayList;
@@ -55,21 +56,21 @@ public final class ClassTranslator extends AbstractTranslator {
@NotNull
public static JsPropertyInitializer translateAsProperty(@NotNull JetClassOrObject classDeclaration,
@NotNull TranslationContext context) {
JsInvocation classCreationExpression =
JsExpression classCreationExpression =
generateClassCreationExpression(classDeclaration, context);
JsName className = context.getNameForElement(classDeclaration);
return new JsPropertyInitializer(className.makeRef(), classCreationExpression);
}
@NotNull
public static JsInvocation generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
@NotNull Map<JsName, JsName> aliasingMap,
@NotNull TranslationContext context) {
return (new ClassTranslator(classDeclaration, aliasingMap, context)).translateClassOrObjectCreation();
}
@NotNull
public static JsInvocation generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
@NotNull TranslationContext context) {
return (new ClassTranslator(classDeclaration, Collections.<JsName, JsName>emptyMap(), context)).translateClassOrObjectCreation();
@@ -122,9 +123,11 @@ public final class ClassTranslator extends AbstractTranslator {
}
@NotNull
private JsInvocation translateClassOrObjectCreation() {
private JsExpression translateClassOrObjectCreation() {
JsInvocation jsClassDeclaration = classCreateMethodInvocation();
addSuperclassReferences(jsClassDeclaration);
if (!isObject()) {
addSuperclassReferences(jsClassDeclaration);
}
addClassOwnDeclarations(jsClassDeclaration);
return jsClassDeclaration;
}
@@ -134,7 +137,7 @@ public final class ClassTranslator extends AbstractTranslator {
if (isObject()) {
return AstUtil.newInvocation(context().namer().objectCreationMethodReference());
}
else if (isTrait()) {
else if (isTrait() && !context().isEcma5()) {
return AstUtil.newInvocation(context().namer().traitCreationMethodReference());
}
else {
@@ -151,13 +154,47 @@ public final class ClassTranslator extends AbstractTranslator {
}
private void addClassOwnDeclarations(@NotNull JsInvocation jsClassDeclaration) {
JsObjectLiteral jsClassDescription = translateClassDeclarations();
jsClassDeclaration.getArguments().add(jsClassDescription);
TranslationContext classDeclarationContext = getClassDeclarationContext();
JsObjectLiteral properties = new JsObjectLiteral();
List<JsPropertyInitializer> propertyList = properties.getPropertyInitializers();
if (!isTrait()) {
JsFunction initializer = Translation.generateClassInitializerMethod(classDeclaration, classDeclarationContext);
if (context().isEcma5()) {
jsClassDeclaration.getArguments().add(isObject() ? initializer : JsAstUtils.encloseFunction(initializer));
}
else {
propertyList.add(InitializerUtils.generateInitializeMethod(initializer));
}
}
else if (context().isEcma5()) {
jsClassDeclaration.getArguments().add(context().program().getNullLiteral());
}
propertyList.addAll(translatePropertiesAsConstructorParameters(classDeclarationContext));
propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, classDeclarationContext));
if (!propertyList.isEmpty() || !context().isEcma5()) {
jsClassDeclaration.getArguments().add(properties);
}
}
private void addSuperclassReferences(@NotNull JsInvocation jsClassDeclaration) {
for (JsExpression superClassReference : getSuperclassNameReferences()) {
jsClassDeclaration.getArguments().add(superClassReference);
List<JsExpression> superClassReferences = getSuperclassNameReferences();
List<JsExpression> expressions = jsClassDeclaration.getArguments();
if (context().isEcma5()) {
if (superClassReferences.isEmpty()) {
jsClassDeclaration.getArguments().add(context().program().getNullLiteral());
return;
}
else if (superClassReferences.size() > 1) {
JsArrayLiteral arrayLiteral = new JsArrayLiteral();
jsClassDeclaration.getArguments().add(arrayLiteral);
expressions = arrayLiteral.getExpressions();
}
}
for (JsExpression superClassReference : superClassReferences) {
expressions.add(superClassReference);
}
}
@@ -206,21 +243,6 @@ public final class ClassTranslator extends AbstractTranslator {
return ancestorClass;
}
@NotNull
private JsObjectLiteral translateClassDeclarations() {
TranslationContext classDeclarationContext = getClassDeclarationContext();
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
if (!isTrait()) {
propertyList.add(Translation.generateClassInitializerMethod(classDeclaration, classDeclarationContext));
}
// skip for ecma5, because accessors defined via Object.defineProperties
if (!context().isEcma5()) {
propertyList.addAll(translatePropertiesAsConstructorParameters(classDeclarationContext));
}
propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, classDeclarationContext));
return JsAstUtils.newObjectLiteral(propertyList);
}
@NotNull
private List<JsPropertyInitializer> translatePropertiesAsConstructorParameters(@NotNull TranslationContext classDeclarationContext) {
List<JsPropertyInitializer> result = new ArrayList<JsPropertyInitializer>();
@@ -18,6 +18,7 @@ package org.jetbrains.k2js.translate.declaration;
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
@@ -25,20 +26,20 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDeclarationsForNamespace;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForObjectDeclaration;
/**
* @author Pavel Talanov
*/
public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPropertyInitializer>> {
@NotNull
public List<JsPropertyInitializer> traverseClass(@NotNull JetClassOrObject jetClass,
@NotNull TranslationContext context) {
@@ -69,7 +70,12 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPrope
@NotNull
public List<JsPropertyInitializer> visitNamedFunction(@NotNull JetNamedFunction expression,
@NotNull TranslationContext context) {
return Collections.singletonList(Translation.functionTranslator(expression, context).translateAsMethod());
JsPropertyInitializer o = Translation.functionTranslator(expression, context).translateAsMethod();
if (context.isEcma5()) {
final FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression);
o.setValueExpr(JsAstUtils.createPropertyDataDescriptor(descriptor.getModality().isOverridable(), o.getValueExpr(), context));
}
return Collections.singletonList(o);
}
@Override
@@ -92,6 +98,10 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPrope
@NotNull
public List<JsPropertyInitializer> visitObjectDeclarationName(@NotNull JetObjectDeclarationName expression,
@NotNull TranslationContext context) {
if (context.isEcma5()) {
return Collections.emptyList();
}
PropertyDescriptor propertyDescriptor =
getPropertyDescriptorForObjectDeclaration(context.bindingContext(), expression);
return PropertyTranslator.translateAccessors(propertyDescriptor, context);
@@ -17,8 +17,7 @@
package org.jetbrains.k2js.translate.declaration;
import com.google.common.collect.Lists;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.backend.js.ast.JsStatement;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
@@ -28,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
@@ -88,7 +88,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
private List<JsStatement> namespacesDeclarations() {
List<JsStatement> result = Lists.newArrayList();
List<NamespaceTranslator> namespaceTranslators = getTranslatorsForNonEmptyNamespaces();
result.addAll(declarationStatements(namespaceTranslators));
result.addAll(declarationStatements(namespaceTranslators, context()));
result.addAll(initializeStatements(namespaceTranslators));
return result;
}
@@ -103,10 +103,19 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
}
@NotNull
private static List<JsStatement> declarationStatements(@NotNull List<NamespaceTranslator> namespaceTranslators) {
private static List<JsStatement> declarationStatements(@NotNull List<NamespaceTranslator> namespaceTranslators, TranslationContext context) {
List<JsStatement> result = Lists.newArrayList();
JsNameRef defs = JsAstUtils.qualified(context.jsScope().declareName("defs"), context.namer().kotlinObject());
for (NamespaceTranslator translator : namespaceTranslators) {
result.add(translator.getDeclarationAsVar());
JsVars vars = translator.getDeclarationAsVar();
JsVars.JsVar var = vars.iterator().next();
JsNameRef ref = new JsNameRef(var.getName());
ref.setQualifier(defs);
result.add(vars);
result.add(JsAstUtils.assignment(ref, new JsNameRef(var.getName())).makeStmt());
}
return result;
}
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import java.util.ArrayList;
@@ -58,7 +59,7 @@ public final class NamespaceTranslator extends AbstractTranslator {
@NotNull
public JsStatement getDeclarationAsVar() {
public JsVars getDeclarationAsVar() {
return newVar(namespaceName, getNamespaceDeclaration());
}
@@ -70,7 +71,20 @@ public final class NamespaceTranslator extends AbstractTranslator {
@NotNull
private JsInvocation getNamespaceDeclaration() {
JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation();
namespaceDeclaration.getArguments().add(translateNamespaceMemberDeclarations());
JsFunction initializer = Translation.generateNamespaceInitializerMethod(descriptor, context());
List<JsPropertyInitializer> properties = new DeclarationBodyVisitor().traverseNamespace(descriptor, context());
if (context().isEcma5()) {
namespaceDeclaration.getArguments().add(initializer);
namespaceDeclaration.getArguments().add(newObjectLiteral(properties));
}
else {
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
propertyList.add(InitializerUtils.generateInitializeMethod(initializer));
propertyList.addAll(properties);
namespaceDeclaration.getArguments().add(newObjectLiteral(propertyList));
}
namespaceDeclaration.getArguments().add(getClassesAndNestedNamespaces());
return namespaceDeclaration;
}
@@ -108,12 +122,4 @@ public final class NamespaceTranslator extends AbstractTranslator {
}
return result;
}
@NotNull
private JsObjectLiteral translateNamespaceMemberDeclarations() {
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
propertyList.add(Translation.generateNamespaceInitializerMethod(descriptor, context()));
propertyList.addAll(new DeclarationBodyVisitor().traverseNamespace(descriptor, context()));
return newObjectLiteral(propertyList);
}
}
@@ -19,14 +19,18 @@ package org.jetbrains.k2js.translate.declaration;
import com.google.dart.compiler.backend.js.ast.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.expression.FunctionTranslator;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.ArrayList;
import java.util.Collections;
@@ -54,12 +58,19 @@ public final class PropertyTranslator extends AbstractTranslator {
static public List<JsPropertyInitializer> translateAccessors(@NotNull PropertyDescriptor descriptor,
@NotNull TranslationContext context) {
if (context.isEcma5()) {
if (context.isEcma5() && !JsDescriptorUtils.isAsPrivate(descriptor)) {
return Collections.emptyList();
}
PropertyTranslator propertyTranslator = new PropertyTranslator(descriptor, context);
return propertyTranslator.translate();
List<JsPropertyInitializer> propertyInitializers = propertyTranslator.translate();
if (context.isEcma5() && !descriptor.getReceiverParameter().exists()) {
JsObjectLiteral objectLiteral = new JsObjectLiteral();
objectLiteral.getPropertyInitializers().addAll(propertyInitializers);
return Collections.singletonList(
new JsPropertyInitializer(context.program().getStringLiteral(descriptor.getName().getName()), objectLiteral));
}
return propertyInitializers;
}
private PropertyTranslator(@NotNull PropertyDescriptor property, @NotNull TranslationContext context) {
@@ -123,8 +134,7 @@ public final class PropertyTranslator extends AbstractTranslator {
private JsPropertyInitializer generateDefaultGetter() {
PropertyGetterDescriptor getterDescriptor = property.getGetter();
assert getterDescriptor != null : "Getter descriptor should not be null";
return newNamedMethod(context().getNameForDescriptor(getterDescriptor),
generateDefaultGetterFunction(getterDescriptor));
return generateDefaultAccessor(getterDescriptor, generateDefaultGetterFunction(getterDescriptor));
}
@NotNull
@@ -139,8 +149,7 @@ public final class PropertyTranslator extends AbstractTranslator {
private JsPropertyInitializer generateDefaultSetter() {
PropertySetterDescriptor setterDescriptor = property.getSetter();
assert setterDescriptor != null : "Setter descriptor should not be null";
return newNamedMethod(context().getNameForDescriptor(setterDescriptor),
generateDefaultSetterFunction(setterDescriptor));
return generateDefaultAccessor(setterDescriptor, generateDefaultSetterFunction(setterDescriptor));
}
@NotNull
@@ -154,6 +163,15 @@ public final class PropertyTranslator extends AbstractTranslator {
return result;
}
private JsPropertyInitializer generateDefaultAccessor(PropertyAccessorDescriptor accessorDescriptor, JsFunction function) {
if (context().isEcma5()) {
return TranslationUtils.translateFunctionAsEcma5PropertyDescriptor(function, accessorDescriptor, context());
}
else {
return newNamedMethod(context().getNameForDescriptor(accessorDescriptor), function);
}
}
@NotNull
private TranslationContext propertyAccessContext(@NotNull PropertySetterDescriptor propertySetterDescriptor) {
return context().newDeclaration(propertySetterDescriptor);
@@ -161,6 +179,7 @@ public final class PropertyTranslator extends AbstractTranslator {
@NotNull
private JsPropertyInitializer translateCustomAccessor(@NotNull JetPropertyAccessor expression) {
return Translation.functionTranslator(expression, context()).translateAsMethod();
FunctionTranslator translator = Translation.functionTranslator(expression, context());
return context().isEcma5() ? translator.translateAsEcma5PropertyDescriptor() : translator.translateAsMethod();
}
}
@@ -129,6 +129,12 @@ public final class FunctionTranslator extends AbstractTranslator {
return functionObject;
}
@NotNull
public JsPropertyInitializer translateAsEcma5PropertyDescriptor() {
generateFunctionObject();
return TranslationUtils.translateFunctionAsEcma5PropertyDescriptor(functionObject, descriptor, context());
}
@NotNull
public JsPropertyInitializer translateAsMethod() {
JsName functionName = context().getNameForElement(functionDeclaration);
@@ -16,10 +16,7 @@
package org.jetbrains.k2js.translate.expression;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsInvocation;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -135,7 +132,19 @@ public final class PatternTranslator extends AbstractTranslator {
@NotNull
private JsExpression translateExpressionPattern(@NotNull JsExpression expressionToMatch, JetExpressionPattern pattern) {
JsExpression expressionToMatchAgainst = translateExpressionForExpressionPattern(pattern);
return equality(expressionToMatch, expressionToMatchAgainst);
JsBinaryOperation eq = equality(expressionToMatch, expressionToMatchAgainst);
// Uncaught TypeError: Cannot convert object to primitive value
if (context().isEcma5()) {
if (expressionToMatchAgainst instanceof JsNumberLiteral ||
expressionToMatchAgainst instanceof JsStringLiteral ||
expressionToMatchAgainst instanceof JsBooleanLiteral) {
JsNameRef valueOf = new JsNameRef("valueOf");
valueOf.setQualifier(expressionToMatch);
return and(valueOf, eq);
}
}
return eq;
}
@NotNull
@@ -21,15 +21,19 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetForExpression;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.reference.CallBuilder;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getHasNextCallable;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getIteratorFunction;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getNextFunction;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToBlock;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
@@ -81,7 +85,27 @@ public final class IteratorForTranslator extends ForTranslator {
@NotNull
private JsExpression hasNextMethodInvocation() {
CallableDescriptor hasNextFunction = getHasNextCallable(bindingContext(), getLoopRange(expression));
return translateMethodInvocation(iterator.reference(), hasNextFunction);
if (hasNextFunction instanceof FunctionDescriptor && !isJavaUtilIterator(hasNextFunction)) {
return translateMethodInvocation(iterator.reference(), hasNextFunction);
}
// develar: I don't know, why hasNext called as function for PropertyDescriptor, our JS side define it as property and all other code translate it as property
JsNameRef hasNext = new JsNameRef(Namer.getNameForAccessor("hasNext", true, context().isEcma5()));
hasNext.setQualifier(iterator.reference());
if (context().isEcma5()) {
return hasNext;
}
else {
JsInvocation invocation = new JsInvocation();
invocation.setQualifier(hasNext);
return invocation;
}
}
// kotlin iterator define hasNext as property, but java util as function, our js side expects as property
private static boolean isJavaUtilIterator(CallableDescriptor descriptor) {
final DeclarationDescriptor declaration = descriptor.getContainingDeclaration();
return declaration != null && declaration.getName().getName().equals("Iterator");
}
@NotNull
@@ -78,7 +78,7 @@ public final class Translation {
}
@NotNull
public static JsInvocation translateClassDeclaration(@NotNull JetClass classDeclaration,
public static JsExpression translateClassDeclaration(@NotNull JetClass classDeclaration,
@NotNull Map<JsName, JsName> aliasingMap,
@NotNull TranslationContext context) {
return ClassTranslator.generateClassCreationExpression(classDeclaration, aliasingMap, context);
@@ -128,14 +128,14 @@ public final class Translation {
//TODO: see if generate*Initializer methods fit somewhere else
@NotNull
public static JsPropertyInitializer generateClassInitializerMethod(@NotNull JetClassOrObject classDeclaration,
public static JsFunction generateClassInitializerMethod(@NotNull JetClassOrObject classDeclaration,
@NotNull TranslationContext context) {
final ClassInitializerTranslator classInitializerTranslator = new ClassInitializerTranslator(classDeclaration, context);
return classInitializerTranslator.generateInitializeMethod();
}
@NotNull
public static JsPropertyInitializer generateNamespaceInitializerMethod(@NotNull NamespaceDescriptor namespace,
public static JsFunction generateNamespaceInitializerMethod(@NotNull NamespaceDescriptor namespace,
@NotNull TranslationContext context) {
final NamespaceInitializerTranslator namespaceInitializerTranslator = new NamespaceInitializerTranslator(namespace, context);
return namespaceInitializerTranslator.generateInitializeMethod();
@@ -164,11 +164,17 @@ public final class Translation {
//TODO: move some of the code somewhere
JetStandardLibrary standardLibrary = JetStandardLibrary.getInstance();
StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext, ecmaVersion);
JsBlock block = staticContext.getProgram().getFragmentBlock(0);
JsProgram program = staticContext.getProgram();
JsBlock block = program.getGlobalBlock();
JsFunction rootFunction = JsAstUtils.createPackage(block.getStatements(), program.getScope());
List<JsStatement> statements = rootFunction.getBody().getStatements();
statements.add(program.getStringLiteral("use strict").makeStmt());
TranslationContext context = TranslationContext.rootContext(staticContext);
block.getStatements().addAll(translateFiles(files, context));
statements.addAll(translateFiles(files, context));
if (mainCallParameters.shouldBeGenerated()) {
block.getStatements().add(generateCallToMain(context, files, mainCallParameters.arguments()));
statements.add(generateCallToMain(context, files, mainCallParameters.arguments()));
}
JsNamer namer = new JsPrettyNamer();
namer.exec(context.program());
@@ -17,6 +17,7 @@
package org.jetbrains.k2js.translate.initializer;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
@@ -29,7 +30,6 @@ import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.ArrayList;
import java.util.List;
@@ -37,7 +37,6 @@ import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getPrimaryConstructorParameters;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateArgumentList;
/**
@@ -48,8 +47,6 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
private final JetClassOrObject classDeclaration;
@NotNull
private final List<JsStatement> initializerStatements = new ArrayList<JsStatement>();
@NotNull
private final JsObjectLiteral propertiesDefinition = new JsObjectLiteral();
public ClassInitializerTranslator(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) {
// Note: it's important we use scope for class descriptor because anonymous function used in property initializers
@@ -59,37 +56,45 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
}
@NotNull
public JsPropertyInitializer generateInitializeMethod() {
public JsFunction generateInitializeMethod() {
//TODO: it's inconsistent that we have scope for class and function for constructor, currently have problems implementing better way
ConstructorDescriptor primaryConstructor = getConstructor(bindingContext(), classDeclaration);
JsFunction result = context().getFunctionObject(primaryConstructor);
//NOTE: while we translate constructor parameters we also add property initializer statements
// for properties declared as constructor parameters
setParameters(result, translatePrimaryConstructorParameters());
mayBeAddCallToSuperMethod();
initializerStatements.addAll((InitializerVisitor.create(context())).traverseClass(classDeclaration, context()));
mayBeAddCallToSuperMethod(result);
initializerStatements.addAll(new InitializerVisitor().traverseClass(classDeclaration, context()));
result.getBody().getStatements().addAll(initializerStatements);
if (!propertiesDefinition.getPropertyInitializers().isEmpty()) {
result.getBody().getStatements().add(JsAstUtils.defineProperties(propertiesDefinition));
}
return InitializerUtils.generateInitializeMethod(result);
return result;
}
private void mayBeAddCallToSuperMethod() {
private void mayBeAddCallToSuperMethod(JsFunction initializer) {
if (hasAncestorClass(bindingContext(), classDeclaration)) {
JetDelegatorToSuperCall superCall = getSuperCall();
if (superCall == null) return;
addCallToSuperMethod(superCall);
addCallToSuperMethod(superCall, initializer);
}
}
private void addCallToSuperMethod(@NotNull JetDelegatorToSuperCall superCall) {
//TODO: can be problematic to maintain
JsName superMethodName = context().jsScope().declareName(Namer.superMethodName());
superMethodName.setObfuscatable(false);
private void addCallToSuperMethod(@NotNull JetDelegatorToSuperCall superCall, JsFunction initializer) {
List<JsExpression> arguments = translateArguments(superCall);
initializerStatements.add(convertToStatement(newInvocation(thisQualifiedReference(superMethodName), arguments)));
//TODO: can be problematic to maintain
if (context().isEcma5()) {
JsName ref = context().jsScope().declareName("$initializer");
initializer.setName(ref);
JsInvocation call = new JsInvocation();
call.setQualifier(AstUtil.newNameRef(AstUtil.newNameRef(ref.makeRef(), "baseInitializer"), "call"));
call.getArguments().add(new JsThisRef());
call.getArguments().addAll(arguments);
initializerStatements.add(call.makeStmt());
}
else {
JsName superMethodName = context().jsScope().declareName(Namer.superMethodName());
superMethodName.setObfuscatable(false);
initializerStatements.add(convertToStatement(newInvocation(thisQualifiedReference(superMethodName), arguments)));
}
}
@NotNull
@@ -140,13 +145,6 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
}
private void addInitializerOrPropertyDefinition(@NotNull JsNameRef initialValue, @NotNull PropertyDescriptor propertyDescriptor) {
if (context().isEcma5()) {
propertiesDefinition.getPropertyInitializers().add(JsAstUtils.propertyDescriptor(propertyDescriptor, initialValue, context()));
}
else {
JsStatement assignmentToBackingFieldExpression =
assignmentToBackingField(context(), propertyDescriptor, initialValue).makeStmt();
initializerStatements.add(assignmentToBackingFieldExpression);
}
initializerStatements.add(InitializerUtils.generateInitializerForProperty(context(), propertyDescriptor, initialValue));
}
}
@@ -1,37 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.k2js.translate.initializer;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.k2js.translate.context.TranslationContext;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
/**
* @author Pavel Talanov
*/
public final class Ecma3InitializerVisitor extends InitializerVisitor {
@Override
@Nullable
protected JsExpression generateInitializerForProperty(@NotNull PropertyDescriptor propertyDescriptor,
@NotNull JsExpression value, @NotNull TranslationContext context) {
return assignmentToBackingField(context, propertyDescriptor, value);
}
}
@@ -1,54 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.k2js.translate.initializer;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsObjectLiteral;
import com.google.dart.compiler.backend.js.ast.JsStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.List;
public final class Ecma5InitializerVisitor extends InitializerVisitor {
@NotNull
private final JsObjectLiteral propertiesDefinition = new JsObjectLiteral();
@Override
@Nullable
protected JsExpression generateInitializerForProperty(@NotNull PropertyDescriptor propertyDescriptor,
@NotNull JsExpression value, @NotNull TranslationContext context) {
propertiesDefinition.getPropertyInitializers().add(JsAstUtils.propertyDescriptor(propertyDescriptor, value, context));
return null;
}
@NotNull
@Override
protected List<JsStatement> generateInitializerStatements(@NotNull List<JetDeclaration> declarations,
@NotNull TranslationContext context) {
List<JsStatement> statements = super.generateInitializerStatements(declarations, context);
if (!propertiesDefinition.getPropertyInitializers().isEmpty()) {
JsStatement statement = JsAstUtils.defineProperties(propertiesDefinition);
statements.add(0, statement);
}
return statements;
}
}
@@ -16,12 +16,17 @@
package org.jetbrains.k2js.translate.initializer;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsFunction;
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
import com.google.dart.compiler.backend.js.ast.JsStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
/**
* @author Pavel Talanov
@@ -39,4 +44,15 @@ public final class InitializerUtils {
return initializer;
}
@NotNull
public static JsStatement generateInitializerForProperty(@NotNull TranslationContext context,
@NotNull PropertyDescriptor descriptor,
@NotNull JsExpression value) {
if (context.isEcma5()) {
return JsAstUtils.definePropertyDataDescriptor(descriptor, value, context).makeStmt();
}
else {
return assignmentToBackingField(context, descriptor, value).makeStmt();
}
}
}
@@ -21,7 +21,6 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsInvocation;
import com.google.dart.compiler.backend.js.ast.JsStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
@@ -29,7 +28,6 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.declaration.ClassTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.Arrays;
import java.util.Collections;
@@ -42,11 +40,7 @@ import static org.jetbrains.k2js.translate.utils.PsiUtils.getObjectDeclarationFo
/**
* @author Pavel Talanov
*/
public abstract class InitializerVisitor extends TranslatorVisitor<List<JsStatement>> {
static InitializerVisitor create(TranslationContext context) {
return context.isEcma5() ? new Ecma5InitializerVisitor() : new Ecma3InitializerVisitor();
}
public final class InitializerVisitor extends TranslatorVisitor<List<JsStatement>> {
@Override
@NotNull
public final List<JsStatement> visitProperty(@NotNull JetProperty property, @NotNull TranslationContext context) {
@@ -54,16 +48,16 @@ public abstract class InitializerVisitor extends TranslatorVisitor<List<JsStatem
if (initializer == null) {
return Collections.emptyList();
}
JsExpression initalizerForProperty = generateInitializerForProperty(getPropertyDescriptor(context.bindingContext(), property),
Translation.translateAsExpression(initializer, context),
context);
return JsAstUtils.nullableExpressionToStatementList(initalizerForProperty);
return generateInitializerForProperty(getPropertyDescriptor(context.bindingContext(), property),
Translation.translateAsExpression(initializer, context), context);
}
//TODO: should return JsStatement?
@Nullable
protected abstract JsExpression generateInitializerForProperty(@NotNull PropertyDescriptor descriptor,
@NotNull JsExpression expression, @NotNull TranslationContext context);
@NotNull
private static List<JsStatement> generateInitializerForProperty(@NotNull PropertyDescriptor descriptor,
@NotNull JsExpression value, @NotNull TranslationContext context) {
return Collections.singletonList(InitializerUtils.generateInitializerForProperty(context, descriptor, value));
}
@Override
@NotNull
@@ -85,13 +79,12 @@ public abstract class InitializerVisitor extends TranslatorVisitor<List<JsStatem
@NotNull TranslationContext context) {
PropertyDescriptor propertyDescriptor = getPropertyDescriptorForObjectDeclaration(context.bindingContext(), objectName);
JetObjectDeclaration objectDeclaration = getObjectDeclarationForName(objectName);
JsInvocation objectValue = ClassTranslator.generateClassCreationExpression(objectDeclaration, context);
JsExpression initializerForProperty = generateInitializerForProperty(propertyDescriptor, objectValue, context);
return JsAstUtils.nullableExpressionToStatementList(initializerForProperty);
JsExpression objectValue = ClassTranslator.generateClassCreationExpression(objectDeclaration, context);
return generateInitializerForProperty(propertyDescriptor, objectValue, context);
}
@NotNull
protected List<JsStatement> generateInitializerStatements(@NotNull List<JetDeclaration> declarations,
private List<JsStatement> generateInitializerStatements(@NotNull List<JetDeclaration> declarations,
@NotNull TranslationContext context) {
List<JsStatement> statements = Lists.newArrayList();
for (JetDeclaration declaration : declarations) {
@@ -42,14 +42,13 @@ public final class NamespaceInitializerTranslator {
}
@NotNull
public JsPropertyInitializer generateInitializeMethod() {
public JsFunction generateInitializeMethod() {
JsFunction result = JsAstUtils.createFunctionWithEmptyBody(namespaceContext.jsScope());
TranslationContext namespaceInitializerContext
= namespaceContext.innerContextWithGivenScopeAndBlock(result.getScope(), result.getBody());
List<JsStatement> initializerStatements = (InitializerVisitor.create(namespaceContext)).traverseNamespace(namespace,
namespaceInitializerContext);
List<JsStatement> initializerStatements = new InitializerVisitor().traverseNamespace(namespace, namespaceInitializerContext);
result.getBody().getStatements().addAll(initializerStatements);
return InitializerUtils.generateInitializeMethod(result);
return result;
}
}
@@ -16,10 +16,7 @@
package org.jetbrains.k2js.translate.intrinsic.primitive;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
import com.google.dart.compiler.backend.js.ast.JsBooleanLiteral;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsNew;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -53,10 +50,11 @@ public final class PrimitiveRangeToIntrinsic implements Intrinsic {
JsBinaryOperation rangeSize = sum(subtract(rangeEnd, rangeStart),
context.program().getNumberLiteral(1));
//TODO: provide a way not to hard code this value
JsNew numberRangeConstructorInvocation = new JsNew(AstUtil.newQualifiedNameRef("Kotlin.NumberRange"));
JsNameRef expr = AstUtil.newQualifiedNameRef("Kotlin.NumberRange");
HasArguments numberRangeConstructorInvocation = context.isEcma5() ? AstUtil.newInvocation(expr) : new JsNew(expr);
//TODO: add tests and correct expression for reversed ranges.
JsBooleanLiteral isRangeReversed = context.program().getFalseLiteral();
setArguments(numberRangeConstructorInvocation, rangeStart, rangeSize, isRangeReversed);
return numberRangeConstructorInvocation;
return (JsExpression) numberRangeConstructorInvocation;
}
}
@@ -17,10 +17,7 @@
package org.jetbrains.k2js.translate.reference;
import com.google.common.collect.Lists;
import com.google.dart.compiler.backend.js.ast.JsExpression;
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.JsNew;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -138,8 +135,14 @@ public final class CallTranslator extends AbstractTranslator {
@NotNull
private JsExpression constructorCall() {
JsExpression constructorReference = translateAsFunctionWithNoThisObject(descriptor);
JsNew constructorCall = new JsNew(constructorReference);
setArguments(constructorCall, arguments);
JsExpression constructorCall;
if (context().isEcma5() && !AnnotationsUtils.isNativeObject(resolvedCall.getCandidateDescriptor())) {
constructorCall = AstUtil.newInvocation(constructorReference);
}
else {
constructorCall = new JsNew(constructorReference);
}
((HasArguments) constructorCall).getArguments().addAll(arguments);
return constructorCall;
}
@@ -21,7 +21,6 @@ import com.google.dart.compiler.backend.js.ast.JsName;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
@@ -56,26 +55,8 @@ public final class ReferenceTranslator {
@NotNull
public static JsExpression translateAsLocalNameReference(@NotNull DeclarationDescriptor referencedDescriptor,
@NotNull TranslationContext context) {
DeclarationDescriptor effectiveDescriptor = getReferencedDescriptor(referencedDescriptor, context);
// Preconditions.checkNotNull(effectiveDescriptor, "Could not find DeclarationDescriptor for %s", referencedDescriptor);
return context.getNameForDescriptor(effectiveDescriptor).makeRef();
}
//TODO: should not be doing this
@NotNull
private static DeclarationDescriptor getReferencedDescriptor(@NotNull DeclarationDescriptor referencedDescriptor,
@NotNull TranslationContext context) {
DeclarationDescriptor effectiveDescriptor;
if (context.isEcma5() && referencedDescriptor instanceof PropertyAccessorDescriptor) {
effectiveDescriptor = ((PropertyAccessorDescriptor) referencedDescriptor).getCorrespondingProperty();
// Preconditions.checkNotNull(effectiveDescriptor, "No correspondingProperty available for descriptor %s", referencedDescriptor);
}
else {
effectiveDescriptor = referencedDescriptor;
// Preconditions.checkNotNull(effectiveDescriptor, "No referencedDescriptor available");
}
return effectiveDescriptor;
//Preconditions.checkNotNull(referencedDescriptor, "No referencedDescriptor available");
return context.getNameForDescriptor(referencedDescriptor).makeRef();
}
@NotNull
@@ -30,15 +30,12 @@ import java.util.*;
* @author Pavel Talanov
*/
public final class JsAstUtils {
private static final JsNameRef VALUE = new JsNameRef("value");
private static final JsPropertyInitializer WRITABLE = new JsPropertyInitializer(new JsNameRef("writable"), null);
private static final JsNameRef DEFINE_PROPERTIES = new JsNameRef("defineProperties");
private static final JsNameRef CREATE = new JsNameRef("create");
private static final JsNameRef DEFINE_PROPERTY = new JsNameRef("defineProperty");
private static final JsNameRef EMPTY_REF = new JsNameRef("");
static {
JsNameRef globalObjectReference = new JsNameRef("Object");
DEFINE_PROPERTIES.setQualifier(globalObjectReference);
CREATE.setQualifier(globalObjectReference);
DEFINE_PROPERTY.setQualifier(globalObjectReference);
}
private JsAstUtils() {
@@ -227,13 +224,13 @@ public final class JsAstUtils {
arguments.addAll(newArgs);
}
public static void setArguments(@NotNull JsNew invocation, @NotNull List<JsExpression> newArgs) {
public static void setArguments(@NotNull HasArguments invocation, @NotNull List<JsExpression> newArgs) {
List<JsExpression> arguments = invocation.getArguments();
assert arguments.isEmpty() : "Arguments already set.";
arguments.addAll(newArgs);
}
public static void setArguments(@NotNull JsNew invocation, JsExpression... arguments) {
public static void setArguments(@NotNull HasArguments invocation, JsExpression... arguments) {
setArguments(invocation, Arrays.asList(arguments));
}
@@ -287,36 +284,44 @@ public final class JsAstUtils {
}
@NotNull
public static JsStatement defineProperties(@NotNull JsObjectLiteral propertiesDefinition) {
return AstUtil.newInvocation(DEFINE_PROPERTIES, new JsThisRef(), propertiesDefinition).makeStmt();
public static JsInvocation definePropertyDataDescriptor(@NotNull PropertyDescriptor descriptor,
@NotNull JsExpression value,
@NotNull TranslationContext context) {
return AstUtil.newInvocation(DEFINE_PROPERTY, new JsThisRef(),
context.program().getStringLiteral(context.getNameForDescriptor(descriptor).getIdent()),
createPropertyDataDescriptor(descriptor.isVar(), value, context));
}
@NotNull
public static JsPropertyInitializer propertyDescriptor(@NotNull PropertyDescriptor descriptor,
@NotNull JsExpression value, @NotNull TranslationContext context) {
public static JsObjectLiteral createPropertyDataDescriptor(boolean writable,
@NotNull JsExpression value,
@NotNull TranslationContext context) {
JsObjectLiteral jsPropertyDescriptor = new JsObjectLiteral();
List<JsPropertyInitializer> meta = jsPropertyDescriptor.getPropertyInitializers();
meta.add(new JsPropertyInitializer(VALUE, value));
if (descriptor.isVar()) {
meta.add(getWritable(context));
meta.add(new JsPropertyInitializer(context.program().getStringLiteral("value"), value));
if (writable) {
meta.add(context.namer().writablePropertyDescriptorField());
}
// TODO: accessors
return new JsPropertyInitializer(context.getNameForDescriptor(descriptor).makeRef(), jsPropertyDescriptor);
return jsPropertyDescriptor;
}
@NotNull
private static JsPropertyInitializer getWritable(@NotNull TranslationContext context) {
if (WRITABLE.getValueExpr() == null) {
WRITABLE.setValueExpr(context.program().getTrueLiteral());
}
return WRITABLE;
public static JsInvocation encloseFunction(JsFunction function) {
JsInvocation blockFunctionInvocation = new JsInvocation();
blockFunctionInvocation.setQualifier(EMPTY_REF);
blockFunctionInvocation.getArguments().add(function);
return blockFunctionInvocation;
}
@NotNull
public static List<JsStatement> nullableExpressionToStatementList(@Nullable JsExpression initalizerForProperty) {
if (initalizerForProperty == null) {
return Collections.emptyList();
}
return Collections.<JsStatement>singletonList(initalizerForProperty.makeStmt());
public static JsFunction createPackage(List<JsStatement> to, JsScope scope) {
JsFunction packageBlockFunction = createFunctionWithEmptyBody(scope);
JsInvocation packageBlockFunctionInvocation = encloseFunction(packageBlockFunction);
JsInvocation packageBlock = new JsInvocation();
packageBlock.setQualifier(packageBlockFunctionInvocation);
to.add(packageBlock.makeStmt());
return packageBlockFunction;
}
}
@@ -281,4 +281,14 @@ public final class JsDescriptorUtils {
}
return null;
}
private static boolean isDefaultAccessor(@Nullable PropertyAccessorDescriptor accessorDescriptor) {
return accessorDescriptor == null || accessorDescriptor.isDefault();
}
public static boolean isAsPrivate(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getReceiverParameter().exists() ||
!isDefaultAccessor(propertyDescriptor.getGetter()) ||
!isDefaultAccessor(propertyDescriptor.getSetter());
}
}
@@ -45,6 +45,24 @@ public final class TranslationUtils {
private TranslationUtils() {
}
@NotNull
public static JsPropertyInitializer translateFunctionAsEcma5PropertyDescriptor(@NotNull JsFunction function,
@NotNull FunctionDescriptor descriptor,
@NotNull TranslationContext context) {
if (descriptor.getReceiverParameter().exists()) {
JsObjectLiteral meta = new JsObjectLiteral();
meta.getPropertyInitializers().add(new JsPropertyInitializer(context.program().getStringLiteral("value"), function));
if (descriptor.getModality().isOverridable()) {
meta.getPropertyInitializers().add(context.namer().writablePropertyDescriptorField());
}
return new JsPropertyInitializer(context.getNameForDescriptor(descriptor).makeRef(), meta);
}
else {
return new JsPropertyInitializer(
context.program().getStringLiteral(descriptor instanceof PropertyGetterDescriptor ? "get" : "set"), function);
}
}
@NotNull
public static JsBinaryOperation notNullCheck(@NotNull TranslationContext context,
@NotNull JsExpression expressionToCheck) {
@@ -10,6 +10,8 @@ var Test.b : Int
a = c - 1
}
val Test.d : Int = 44
fun box() : Boolean {
val c = Test()
if (c.a != 0) return false;
@@ -19,5 +21,6 @@ fun box() : Boolean {
c.b = 10;
if (c.a != 9) return false;
if (c.b != 27) return false;
if (c.d != 44) return false;
return true;
}
@@ -14,7 +14,7 @@
* limitations under the License.
*/
var map = new Kotlin.HashMap()
var map = Kotlin.$new(Kotlin.HashMap)()
map.put(3, 4)
map.put(6, 3)
@@ -38,4 +38,4 @@ function test() {
return true;
}
}
@@ -14,10 +14,10 @@
* limitations under the License.
*/
var A = Kotlin.Class.create();
var B = Kotlin.Class.create(A);
var A = Kotlin.createClass();
var B = Kotlin.createClass(A);
var b = new B;
test = function() {
return (Kotlin.isType(b, A) && Kotlin.isType(b, B));
}
}
@@ -14,12 +14,12 @@
* limitations under the License.
*/
var A = Kotlin.Class.create();
var B = Kotlin.Class.create(A);
var A = Kotlin.createClass();
var B = Kotlin.createClass(A);
var b = new B;
var C = Kotlin.Class.create(B);
var C = Kotlin.createClass(B);
var c = new C;
var E = Kotlin.Class.create(A)
var E = Kotlin.createClass(A)
var e = new E;
test1 = function() {
@@ -37,4 +37,4 @@ test3 = function() {
test = function() {
return test1() && test2() && test3()
}
}
@@ -14,11 +14,11 @@
* limitations under the License.
*/
var A = Kotlin.Class.create();
var B = Kotlin.Class.create(A);
var C = Kotlin.Class.create();
var A = Kotlin.createClass();
var B = Kotlin.createClass(A);
var C = Kotlin.createClass();
var c = new C;
test = function() {
return ((!isType(c, A)) && !isType(c, B));
}
}
@@ -14,9 +14,9 @@
* limitations under the License.
*/
var A = Kotlin.Class.create();
var a = new A;
var A = Kotlin.createClass();
var a = Kotlin.$new(A)();
test = function() {
return Kotlin.isType(a, A);
}
}
@@ -14,7 +14,7 @@
* limitations under the License.
*/
foo = Kotlin.Namespace.create({initialize:function(){
foo = Kotlin.createNamespace({initialize:function(){
}
, box:function(){
return !false;
@@ -16,7 +16,7 @@
{
classes = function(){
var A = Kotlin.Class.create({initialize:function(){
var A = Kotlin.createClass({initialize:function(){
this.$order = '';
{
this.set_order(this.get_order() + 'A');
@@ -29,14 +29,14 @@
return this.$order;
}
});
var B = Kotlin.Class.create(A, {initialize:function(){
var B = Kotlin.createClass(A, {initialize:function(){
this.super_init();
{
this.set_order(this.get_order() + 'B');
}
}
});
var C = Kotlin.Class.create(B, {initialize:function(){
var C = Kotlin.createClass(B, {initialize:function(){
this.super_init();
{
this.set_order(this.get_order() + 'C');
@@ -46,7 +46,7 @@
return {A:A, B:B, C:C};
}
();
foo = Kotlin.Namespace.create(classes, {initialize:function(){
foo = Kotlin.createNamespace(classes, {initialize:function(){
}
, box:function(){
return (new foo.C).get_order() === 'ABC' && (new foo.B).get_order() === 'AB' && (new foo.A).get_order() === 'A';
@@ -16,11 +16,11 @@
foo = {};
(function(foo){
foo.Test = Kotlin.Trait.create({addFoo:function(s){
foo.Test = Kotlin.createTrait({addFoo:function(s){
return s + 'FOO';
}
});
foo.ExtendedTest = Kotlin.Trait.create(foo.Test, {hooray:function(){
foo.ExtendedTest = Kotlin.createTrait(foo.Test, {hooray:function(){
return 'hooray';
}
});
+106 -404
View File
@@ -1,282 +1,5 @@
/**
* Copyright 2010 Tim Down.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Prototype JavaScript framework, version 1.6.1
* (c) 2005-2009 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://www.prototypejs.org/
*
*--------------------------------------------------------------------------*/
var Kotlin;
(function () {
"use strict";
function $A(iterable) {
if (!iterable) return [];
if ('toArray' in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
(function () {
function extend(destination, source) {
for (var property in source)
destination[property] = source[property];
return destination;
}
function keys(object) {
var results = [];
for (var property in object) {
if (object.hasOwnProperty(property)) {
results.push(property);
}
}
return results;
}
function values(object) {
var results = [];
for (var property in object)
results.push(object[property]);
return results;
}
extend(Object, {
extend:extend,
keys:Object.keys || keys,
values:values
});
})();
Object.extend(Function.prototype, (function () {
var slice = Array.prototype.slice;
function update(array, args) {
var arrayLength = array.length, length = args.length;
while (length--) array[arrayLength + length] = args[length];
return array;
}
function merge(array, args) {
array = slice.call(array, 0);
return update(array, args);
}
function argumentNames() {
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
}
function bind(context) {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
var __method = this, args = slice.call(arguments, 1);
return function () {
var a = merge(args, arguments);
return __method.apply(context, a);
};
}
function bindAsEventListener(context) {
var __method = this, args = slice.call(arguments, 1);
return function (event) {
var a = update([event || window.event], args);
return __method.apply(context, a);
};
}
function wrap(wrapper) {
var __method = this;
return function () {
var a = update([__method.bind(this)], arguments);
return wrapper.apply(this, a);
};
}
return {
argumentNames:argumentNames,
bind:bind,
bindAsEventListener:bindAsEventListener,
wrap:wrap
};
})());
var isType = function (object, klass) {
if (object === null) {
return false;
}
var current = object.get_class();
while (current !== klass) {
if (current === null) {
return false;
}
current = current.superclass;
}
return true;
};
var emptyFunction = function () {
};
var Class = (function () {
function subclass() {
}
function create() {
var parent = null, properties = $A(arguments);
if (typeof (properties[0]) == "function") {
parent = properties.shift();
}
function klass() {
this.initializing = klass;
this.initialize.apply(this, arguments);
}
Object.extend(klass, Class.Methods);
klass.superclass = parent;
klass.subclasses = [];
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass();
parent.subclasses.push(klass);
}
klass.addMethods(
{
get_class:function () {
return klass;
}
});
if (parent !== null) {
klass.addMethods(
{
super_init:function () {
this.initializing = this.initializing.superclass;
this.initializing.prototype.initialize.apply(this, arguments);
}
});
}
for (var i = 0, length = properties.length; i < length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize) {
klass.prototype.initialize = emptyFunction;
}
klass.prototype.constructor = klass;
return klass;
}
function addMethods(source) {
var ancestor = this.superclass && this.superclass.prototype,
properties = Object.keys(source);
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i], value = source[property];
if (ancestor && (typeof (value) == "function") &&
value.argumentNames()[0] == "$super") {
var method = value;
value = (function (m) {
return function () {
return ancestor[m].apply(this, arguments);
};
})(property).wrap(method);
}
this.prototype[property] = value;
}
return this;
}
return {
create:create,
Methods:{
addMethods:addMethods
}
};
})();
var Trait = (function () {
function add(object, source) {
var properties = Object.keys(source);
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i];
var value = source[property];
object[property] = value;
}
return this;
}
function create() {
var result = {};
for (var i = 0, length = arguments.length; i < length; i++) {
add(result, arguments[i]);
}
return result;
}
return {
create:create
};
})();
var Namespace = (function () {
function create() {
return Trait.create.apply(Trait, arguments);
}
return {
create:create
};
})();
var object = (function () {
function create() {
var singletonClass = Class.create.apply(Class, arguments);
return new singletonClass();
}
return {
create:create
};
})();
Kotlin = {};
Kotlin.Class = Class;
Kotlin.Namespace = Namespace;
Kotlin.Trait = Trait;
Kotlin.isType = isType;
Kotlin.object = object;
Kotlin.equals = function (obj1, obj2) {
if (typeof obj1 == "object") {
@@ -287,22 +10,66 @@ var Kotlin;
return (obj1 === obj2);
};
Kotlin.defs = {};
Kotlin.Exceptions = {};
Kotlin.Exception = Kotlin.Class.create();
Kotlin.RuntimeException = Kotlin.Class.create(Kotlin.Exception);
Kotlin.Exceptions.IndexOutOfBounds = Kotlin.Class.create(Kotlin.Exception);
Kotlin.Exceptions.NullPointerException = Kotlin.Class.create(Kotlin.Exception);
Kotlin.Exceptions.NoSuchElementException = Kotlin.Class.create(Kotlin.Exception);
Kotlin.Exceptions.IllegalArgumentException = Kotlin.Class.create(Kotlin.Exception);
Kotlin.Exceptions.IllegalStateException = Kotlin.Class.create(Kotlin.Exception);
Kotlin.Exceptions.IndexOutOfBoundsException = Kotlin.Class.create(Kotlin.Exception);
Kotlin.Exceptions.UnsupportedOperationException = Kotlin.Class.create(Kotlin.Exception);
Kotlin.Exception = Kotlin.$createClass();
Kotlin.RuntimeException = Kotlin.$createClass(Kotlin.Exception);
Kotlin.Exceptions.IndexOutOfBounds = Kotlin.$createClass(Kotlin.Exception);
Kotlin.Exceptions.NullPointerException = Kotlin.$createClass(Kotlin.Exception);
Kotlin.Exceptions.NoSuchElementException = Kotlin.$createClass(Kotlin.Exception);
Kotlin.Exceptions.IllegalArgumentException = Kotlin.$createClass(Kotlin.Exception);
Kotlin.Exceptions.IllegalStateException = Kotlin.$createClass(Kotlin.Exception);
Kotlin.Exceptions.IndexOutOfBoundsException = Kotlin.$createClass(Kotlin.Exception);
Kotlin.Exceptions.UnsupportedOperationException = Kotlin.$createClass(Kotlin.Exception);
Kotlin.throwNPE = function() {
throw new Kotlin.Exceptions.NullPointerException();
throw Kotlin.$new(Kotlin.Exceptions.NullPointerException)();
};
Kotlin.ArrayList = Class.create({
Kotlin.AbstractList = Kotlin.$createClass({
set:function (index, value) {
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
},
iterator:function () {
return Kotlin.$new(Kotlin.ArrayIterator)(this);
},
isEmpty:function () {
return (this.size() === 0);
},
add:function (element) {
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
},
addAll:function (collection) {
var it = collection.iterator();
while (it.get_hasNext()) {
this.add(it.next());
}
},
remove:function(value) {
for (var i = 0; i < this.$size; ++i) {
if (this.array[i] == value) {
this.removeByIndex(i);
return;
}
}
},
removeByIndex:function (index) {
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
},
clear:function () {
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
},
contains:function (obj) {
for (var i = 0; i < this.$size; ++i) {
if (Kotlin.equals(this.array[i], obj)) {
return true;
}
}
return false;
}
});
Kotlin.ArrayList = Kotlin.$createClass({
initialize:function () {
this.array = [];
this.$size = 0;
@@ -323,7 +90,7 @@ var Kotlin;
return this.$size;
},
iterator:function () {
return new Kotlin.ArrayIterator(this);
return Kotlin.$new(Kotlin.ArrayIterator)(this);
},
isEmpty:function () {
return (this.$size === 0);
@@ -333,7 +100,7 @@ var Kotlin;
},
addAll:function (collection) {
var it = collection.iterator();
while (it.hasNext()) {
while (it.get_hasNext()) {
this.add(it.next());
}
},
@@ -366,50 +133,6 @@ var Kotlin;
});
Kotlin.AbstractList = Class.create({
set:function (index, value) {
throw new Kotlin.Exceptions.UnsupportedOperationException();
},
iterator:function () {
return new Kotlin.ArrayIterator(this);
},
isEmpty:function () {
return (this.size() === 0);
},
add:function (element) {
throw new Kotlin.Exceptions.UnsupportedOperationException();
},
addAll:function (collection) {
var it = collection.iterator();
while (it.hasNext()) {
this.add(it.next());
}
},
remove:function(value) {
for (var i = 0; i < this.$size; ++i) {
if (this.array[i] == value) {
this.removeByIndex(i);
return;
}
}
},
removeByIndex:function (index) {
throw new Kotlin.Exceptions.UnsupportedOperationException();
},
clear:function () {
throw new Kotlin.Exceptions.UnsupportedOperationException();
},
contains:function (obj) {
for (var i = 0; i < this.$size; ++i) {
if (Kotlin.equals(this.array[i], obj)) {
return true;
}
}
return false;
}
});
Kotlin.parseInt = function (str) {
return parseInt(str, 10);
}
@@ -467,37 +190,33 @@ var Kotlin;
Kotlin.System.out().print(s);
};
Kotlin.AbstractFunctionInvocationError = Class.create();
Kotlin.AbstractFunctionInvocationError = Kotlin.$createClass();
Kotlin.Iterator = Class.create({
Kotlin.Iterator = Kotlin.$createClass({
initialize:function () {
},
next:function () {
throw new Kotlin.AbstractFunctionInvocationError();
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
},
hasNext:function () {
throw new Kotlin.AbstractFunctionInvocationError();
get_hasNext:function () {
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
}
});
Kotlin.ArrayIterator = Class.create(Kotlin.Iterator, {
initialize:function (array) {
Kotlin.ArrayIterator = Kotlin.$createClass(Kotlin.Iterator, {
initialize: function (array) {
this.array = array;
this.index = 0;
},
next:function () {
next: function () {
return this.array.get(this.index++);
},
hasNext:function () {
return (this.array.size() > this.index);
},
get_hasNext:function () {
return this.hasNext();
get_hasNext: function () {
return this.array.size() > this.index;
}
});
Kotlin.RangeIterator = Kotlin.Class.create(Kotlin.Iterator, {
Kotlin.RangeIterator = Kotlin.$createClass(Kotlin.Iterator, {
initialize:function (start, count, reversed) {
this.$start = start;
this.$count = count;
@@ -525,14 +244,13 @@ var Kotlin;
this.set_i(this.get_i() + 1);
return this.get_i() - 1;
}
}, hasNext:function () {
},
get_hasNext: function () {
return this.get_count() > 0;
}, get_hasNext:function () {
return this.hasNext();
}
});
Kotlin.NumberRange = Kotlin.Class.create({initialize:function (start, size, reversed) {
Kotlin.NumberRange = Kotlin.$createClass({initialize:function (start, size, reversed) {
this.$start = start;
this.$size = size;
this.$reversed = reversed;
@@ -552,25 +270,23 @@ var Kotlin;
return number >= this.get_start() && number < this.get_start() + this.get_size();
}
}, iterator:function () {
return new Kotlin.RangeIterator(this.get_start(), this.get_size(), this.get_reversed());
return Kotlin.$new(Kotlin.RangeIterator)(this.get_start(), this.get_size(), this.get_reversed());
}
});
Kotlin.Comparator = Kotlin.Class.create(
{
initialize:function () {
},
compare:function (el1, el2) {
throw new Kotlin.AbstractFunctionInvocationError();
}
Kotlin.Comparator = Kotlin.$createClass(
{
initialize: function () {
},
compare: function (el1, el2) {
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
}
}
);
Kotlin.comparator = function (f) {
var result = new Kotlin.Comparator();
result.compare = function (el1, el2) {
return f(el1, el2);
};
var result = Kotlin.$new(Kotlin.Comparator)();
result.compare = f;
return result;
};
@@ -581,7 +297,7 @@ var Kotlin;
throw Kotlin.Exception();
}
var max = it.next();
while (it.hasNext()) {
while (it.get_hasNext()) {
var el = it.next();
if (comp.compare(max, el) < 0) {
max = el;
@@ -590,7 +306,7 @@ var Kotlin;
return max;
};
Kotlin.StringBuilder = Kotlin.Class.create(
Kotlin.StringBuilder = Kotlin.$createClass(
{
initialize:function () {
this.string = "";
@@ -627,31 +343,28 @@ var Kotlin;
};
Kotlin.arrayIndices = function (arr) {
return new Kotlin.NumberRange(0, arr.length);
return Kotlin.$new(Kotlin.NumberRange)(0, arr.length);
};
var intrinsicArrayIterator = Kotlin.Class.create(
Kotlin.Iterator,
{
initialize:function (arr) {
this.arr = arr;
this.len = arr.length;
this.i = 0;
},
hasNext:function () {
return (this.i < this.len);
},
next:function () {
return this.arr[this.i++];
},
get_hasNext:function () {
return this.hasNext();
}
var intrinsicArrayIterator = Kotlin.$createClass(
Kotlin.Iterator,
{
initialize: function (arr) {
this.arr = arr;
this.len = arr.length;
this.i = 0;
},
next: function () {
return this.arr[this.i++];
},
get_hasNext: function () {
return this.i < this.len;
}
}
);
Kotlin.arrayIterator = function (arr) {
return new intrinsicArrayIterator(arr);
return Kotlin.$new(intrinsicArrayIterator)(arr);
};
Kotlin.toString = function (obj) {
@@ -975,7 +688,7 @@ var Kotlin;
this.values = function() {
var values = this._values();
var i = values.length
var result = new Kotlin.ArrayList();
var result = Kotlin.$new(Kotlin.ArrayList)();
while (--i) {
result.add(values[i]);
}
@@ -1047,7 +760,7 @@ var Kotlin;
};
this.keySet = function () {
var res = new Kotlin.HashSet();
var res = Kotlin.$new(Kotlin.HashSet)();
var keys = this._keys();
var i = keys.length;
while (i--) {
@@ -1060,7 +773,7 @@ var Kotlin;
Kotlin.HashTable = Hashtable;
})();
Kotlin.HashMap = Kotlin.Class.create(
Kotlin.HashMap = Kotlin.$createClass(
{
initialize:function () {
Kotlin.HashTable.call(this);
@@ -1089,13 +802,7 @@ var Kotlin;
};
this.iterator = function () {
var list = new Kotlin.ArrayList();
var values = this.values();
var i = values.length;
while (i--) {
list.add(values[i]);
}
return list.iterator();
return Kotlin.arrayIterator(this.values());
};
this.remove = function (o) {
@@ -1159,13 +866,8 @@ var Kotlin;
};
}
Kotlin.HashSet = Kotlin.Class.create(
{
initialize:function () {
HashSet.call(this);
}
}
);
Kotlin.HashSet = Kotlin.$createClass({initialize: function () {
HashSet.call(this);
}});
}());
})();
@@ -0,0 +1,262 @@
/**
* Copyright 2010 Tim Down.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Prototype JavaScript framework, version 1.6.1
* (c) 2005-2009 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://www.prototypejs.org/
*
*--------------------------------------------------------------------------*/
var Kotlin = {};
(function () {
"use strict";
var emptyFunction = function () {
};
function $A(iterable) {
if (!iterable) return [];
if ('toArray' in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
(function () {
function extend(destination, source) {
for (var property in source) {
destination[property] = source[property];
}
return destination;
}
function keys(object) {
var results = [];
for (var property in object) {
if (object.hasOwnProperty(property)) {
results.push(property);
}
}
return results;
}
function values(object) {
var results = [];
for (var property in object) {
results.push(object[property]);
}
return results;
}
extend(Object, {
extend: extend,
keys: Object.keys || keys,
values: values
});
})();
Object.extend(Function.prototype, (function () {
var slice = Array.prototype.slice;
function update(array, args) {
var arrayLength = array.length, length = args.length;
while (length--) array[arrayLength + length] = args[length];
return array;
}
function merge(array, args) {
array = slice.call(array, 0);
return update(array, args);
}
function argumentNames() {
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
}
function bind(context) {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
var __method = this, args = slice.call(arguments, 1);
return function () {
var a = merge(args, arguments);
return __method.apply(context, a);
};
}
function bindAsEventListener(context) {
var __method = this, args = slice.call(arguments, 1);
return function (event) {
var a = update([event || window.event], args);
return __method.apply(context, a);
};
}
function wrap(wrapper) {
var __method = this;
return function () {
var a = update([__method.bind(this)], arguments);
return wrapper.apply(this, a);
};
}
return {
argumentNames: argumentNames,
bind: bind,
bindAsEventListener: bindAsEventListener,
wrap: wrap
};
})());
Kotlin.isType = function (object, klass) {
if (object === null) {
return false;
}
var current = object.get_class();
while (current !== klass) {
if (current === null) {
return false;
}
current = current.superclass;
}
return true;
};
Kotlin.createTrait = (function () {
function add(object, source) {
var properties = Object.keys(source);
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i];
object[property] = source[property];
}
return this;
}
return function () {
var result = {};
for (var i = 0, length = arguments.length; i < length; i++) {
add(result, arguments[i]);
}
return result;
}
})();
Kotlin.createNamespace = function () {
return Kotlin.createTrait.apply(null, arguments);
};
Kotlin.createClass = (function () {
var METHODS = {addMethods: addMethods};
function subclass() {
}
function create() {
var parent = null, properties = $A(arguments);
if (typeof (properties[0]) == "function") {
parent = properties.shift();
}
function klass() {
this.initializing = klass;
if (this.initialize) {
this.initialize.apply(this, arguments);
}
}
Object.extend(klass, METHODS);
klass.superclass = parent;
klass.subclasses = [];
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass();
parent.subclasses.push(klass);
}
klass.addMethods(
{
get_class: function () {
return klass;
}
});
if (parent !== null) {
klass.addMethods(
{
super_init: function () {
this.initializing = this.initializing.superclass;
this.initializing.prototype.initialize.apply(this, arguments);
}
});
}
for (var i = 0, length = properties.length; i < length; i++) {
klass.addMethods(properties[i]);
}
if (!klass.prototype.initialize) {
klass.prototype.initialize = emptyFunction;
}
klass.prototype.constructor = klass;
return klass;
}
function addMethods(source) {
var ancestor = this.superclass && this.superclass.prototype,
properties = Object.keys(source);
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i], value = source[property];
if (ancestor && (typeof (value) == "function") &&
value.argumentNames()[0] == "$super") {
var method = value;
value = (function (m) {
return function () {
return ancestor[m].apply(this, arguments);
};
})(property).wrap(method);
}
this.prototype[property] = value;
}
return this;
}
return create;
})();
Kotlin.$createClass = Kotlin.createClass;
Kotlin.$new = function (f) {
var o = {'__proto__': f.prototype};
return function () {
f.apply(o, arguments);
return o;
};
};
Kotlin.createObject = function () {
var singletonClass = Kotlin.createClass.apply(null, arguments);
return new singletonClass();
};
})();
@@ -0,0 +1,171 @@
// Be aware — Google Chrome has serious issue — you can rewrite READ-ONLY property (if it is defined in prototype). Firefox and Safari work correct.
// Always test property access issues in Firefox, but not in Chrome.
var Kotlin = {};
(function () {
"use strict";
Kotlin.isType = function (object, klass) {
if (object === null) {
return false;
}
var proto = Object.getPrototypeOf(object);
// todo test nested class
//noinspection RedundantIfStatementJS
if (proto == klass.proto) {
return true;
}
return false;
};
// todo compatibility for opera https://raw.github.com/gist/1000718/es5compat-gs.js
// proto must be created for class even if it is not needed (requires for is operator)
Kotlin.createClass = (function () {
function create(bases, initializer, properties) {
var proto;
var baseInitializer = null;
var isTrait = initializer == null;
if (!bases) {
proto = !properties && isTrait ? null : Object.create(null, properties || undefined);
}
else if (!Array.isArray(bases)) {
baseInitializer = bases.initializer;
proto = !properties && isTrait ? bases.proto : Object.create(bases.proto, properties || undefined);
}
else {
proto = computeProto(bases, properties);
// first is superclass, other are traits
baseInitializer = bases[0].initializer;
// all bases are traits without properties
if (proto == null && !isTrait) {
proto = Object.create(null, properties || undefined);
}
}
var constructor = createConstructor(proto, initializer);
Object.defineProperty(constructor, "proto", {value: proto});
Object.defineProperty(constructor, "properties", {value: properties || null});
// null for trait
if (!isTrait) {
Object.defineProperty(constructor, "initializer", {value: initializer});
Object.defineProperty(initializer, "baseInitializer", {value: baseInitializer});
Object.seal(initializer);
}
Object.seal(constructor);
return constructor;
}
// as separate function to reduce scope
function createConstructor(proto, initializer) {
return function () {
var o = Object.create(proto);
if (initializer != null) {
initializer.apply(o, arguments);
}
if (initializer == null || !initializer.hasOwnProperty("skipSeal")) {
Object.seal(o);
}
return o;
};
}
function computeProto(bases, properties) {
var proto = null;
for (var i = 0, n = bases.length; i < n; i++) {
var base = bases[i];
var baseProto = base.proto;
if (baseProto == null || base.properties == null) {
continue;
}
if (!proto) {
proto = Object.create(baseProto, properties || undefined);
continue;
}
// chrome bug related to getOwnPropertyDescriptor (sometimes returns undefined), so, we keep properties
//var names = Object.getOwnPropertyNames(baseProto);
//for (var j = 0, k = names.length; j < k; j++) {
// var descriptor = Object.getOwnPropertyDescriptor(baseProto, names[i]);
// Object.defineProperty(proto, names[i], descriptor);
//}
Object.defineProperties(proto, base.properties);
// todo test A -> B, C(->D) *properties from D is not yet added to proto*
}
return proto;
}
return create;
})();
Kotlin.createObject = function (initializer, properties) {
var o = Object.create(null, properties || undefined);
initializer.call(o);
return o;
};
Kotlin.createNamespace = function (initializer, properties, classesAndNestedNamespaces) {
var o = Object.create(null, properties || undefined);
Object.defineProperty(o, "initialize", {value: initializer});
var keys = Object.keys(classesAndNestedNamespaces);
for (var i = 0, n = keys.length; i < n; i++) {
var name = keys[i];
Object.defineProperty(o, name, {value: classesAndNestedNamespaces[name]});
}
return o;
};
Kotlin.$new = function (f) {
return f;
};
Kotlin.$createClass = function (parent, properties) {
if (typeof (parent) != "function") {
properties = parent;
parent = null;
}
var initializer = null;
var descriptors = properties ? {} : null;
if (descriptors != null) {
var ownPropertyNames = Object.getOwnPropertyNames(properties);
for (var i = 0, n = ownPropertyNames.length; i < n; i++) {
var name = ownPropertyNames[i];
var value = properties[name];
if (name == "initialize") {
initializer = value;
}
else if (name.indexOf("get_") === 0) {
// our std lib contains collision: hasNext property vs hasNext as function, we prefer function (actually, it does work)
var getterName = name.substring(4);
if (!descriptors.hasOwnProperty(getterName)) {
descriptors[getterName] = {get: value};
descriptors[name] = {value: value};
}
}
else if (name.indexOf("set_") === 0) {
descriptors[name.substring(4)] = {set: value};
// std lib code can refers to
descriptors[name] = {value: value};
}
else {
// we assume all our std lib functions are open
descriptors[name] = {value: value, writable: true};
}
}
}
if (initializer) {
Object.defineProperty(initializer, "skipSeal", {value: true});
}
return Kotlin.createClass(parent || null, initializer, descriptors);
};
})();
@@ -0,0 +1,12 @@
package foo
class Test() {
val a : Int = 100
var b : Int = a
val c : Int = a + b
}
fun box() : Boolean {
val test = Test()
return (100 == test.a && 100 == test.b && 200 == test.c)
}
+13
View File
@@ -0,0 +1,13 @@
<!-- Only for developers -->
<html>
<head>
<script src="kotlin_lib_ecma5.js"></script>
<script src="kotlin_lib.js"></script>
<script src="webDemoExamples2/out/life_v5.js"></script>
<script>
//console.assert(Kotlin.defs.foo.box());
</script>
</head>
<body>
</body>
</html>