diff --git a/build.xml b/build.xml
index 6022cd4f56b..75607fd8f67 100644
--- a/build.xml
+++ b/build.xml
@@ -366,6 +366,14 @@
+
+
+
+
+
+
+
+
@@ -384,6 +392,13 @@
+
+
+
+
+
+
+
@@ -392,6 +407,7 @@
+
diff --git a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt
index 210bc0369cb..f037125dd8e 100644
--- a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt
+++ b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt
@@ -100,7 +100,11 @@ open class JsFunctionScope(parent: JsScope, description: String) : JsScope(paren
"NaN", "Infinity", "undefined",
// the special Kotlin object
- "Kotlin"
+ "Kotlin",
+
+ "Error", "Object", "Math", "String", "Number", "Boolean", "Date", "Array", "RegExp", "JSON",
+
+ "require", "define", "module", "window", "self"
)
}
}
diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt
index dcbc259f565..e8e91afa812 100644
--- a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt
+++ b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt
@@ -19,7 +19,8 @@ package org.jetbrains.kotlin.js.naming
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
-import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.*
+import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.getNameForAnnotatedObject
+import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isNativeObject
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
@@ -198,6 +199,13 @@ class NameSuggestion {
val nativeName = getNameForAnnotatedObject(overriddenDescriptor)
if (nativeName != null) return NameAndStability(nativeName, true)
+ if (overriddenDescriptor is FunctionDescriptor) {
+ when (overriddenDescriptor.fqNameUnsafe.asString()) {
+ "kotlin.CharSequence.subSequence" -> return NameAndStability("substring", true)
+ "kotlin.CharSequence.get" -> return NameAndStability("charAt", true)
+ }
+ }
+
return mangleRegularNameIfNecessary(baseName, overriddenDescriptor)
}
diff --git a/js/js.libraries/src/builtins/annotations.kt b/js/js.libraries/src/builtins/annotations.kt
new file mode 100644
index 00000000000..109a3f391e0
--- /dev/null
+++ b/js/js.libraries/src/builtins/annotations.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010-2016 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 kotlin.js
+
+import kotlin.annotation.AnnotationTarget.*
+
+@Retention(AnnotationRetention.BINARY)
+@Target(CLASS, FUNCTION, PROPERTY, CONSTRUCTOR, PROPERTY_GETTER, PROPERTY_SETTER)
+@native annotation class JsName(val name: String)
+
+@native annotation class native
+
+@native fun js(code: String): dynamic
\ No newline at end of file
diff --git a/js/js.libraries/src/builtins/kotlin.kt b/js/js.libraries/src/builtins/kotlin.kt
new file mode 100644
index 00000000000..93d9ca34825
--- /dev/null
+++ b/js/js.libraries/src/builtins/kotlin.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010-2016 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 kotlin
+
+class Enum> : Comparable> {
+ @JsName("name$") private var _name: String = ""
+ @JsName("ordinal$") private var _ordinal: Int = 0
+
+ val name: String
+ get() = _name
+
+ val ordinal: Int
+ get() = _ordinal
+
+ override fun compareTo(other: Enum) = ordinal.compareTo(other.ordinal)
+
+ override fun toString() = name
+}
+
+interface Annotation
\ No newline at end of file
diff --git a/js/js.libraries/src/internal/primitiveCompanionObjects.kt b/js/js.libraries/src/builtins/primitiveCompanionObjects.kt
similarity index 82%
rename from js/js.libraries/src/internal/primitiveCompanionObjects.kt
rename to js/js.libraries/src/builtins/primitiveCompanionObjects.kt
index 4ad6e8855b3..e15933124df 100644
--- a/js/js.libraries/src/internal/primitiveCompanionObjects.kt
+++ b/js/js.libraries/src/builtins/primitiveCompanionObjects.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2015 JetBrains s.r.o.
+ * Copyright 2010-2016 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.
@@ -16,7 +16,7 @@
package kotlin.js.internal
-private object DoubleCompanionObject {
+@JsName("DoubleCompanionObject") private object DoubleCompanionObject {
@JsName("MIN_VALUE") val MIN_VALUE: Double = js("Number.MIN_VALUE")
@JsName("MAX_VALUE") val MAX_VALUE: Double = js("Number.MAX_VALUE")
@JsName("POSITIVE_INFINITY") val POSITIVE_INFINITY: Double = js("Number.POSITIVE_INFINITY")
@@ -24,7 +24,7 @@ private object DoubleCompanionObject {
@JsName("NaN") val NaN: Double = js("Number.NaN")
}
-private object FloatCompanionObject {
+@JsName("FloatCompanionObject") private object FloatCompanionObject {
@JsName("MIN_VALUE") val MIN_VALUE: Float = js("Number.MIN_VALUE")
@JsName("MAX_VALUE") val MAX_VALUE: Float = js("Number.MAX_VALUE")
@JsName("POSITIVE_INFINITY") val POSITIVE_INFINITY: Float = js("Number.POSITIVE_INFINITY")
@@ -32,27 +32,27 @@ private object FloatCompanionObject {
@JsName("NaN") val NaN: Float = js("Number.NaN")
}
-private object IntCompanionObject {
+@JsName("IntCompanionObject") private object IntCompanionObject {
@JsName("MIN_VALUE") val MIN_VALUE: Int = -2147483647 - 1
@JsName("MAX_VALUE") val MAX_VALUE: Int = 2147483647
}
-private object LongCompanionObject {
+@JsName("LongCompanionObject") private object LongCompanionObject {
@JsName("MIN_VALUE") val MIN_VALUE: Long = js("Kotlin.Long.MIN_VALUE")
@JsName("MAX_VALUE") val MAX_VALUE: Long = js("Kotlin.Long.MAX_VALUE")
}
-private object ShortCompanionObject {
+@JsName("ShortCompanionObject") private object ShortCompanionObject {
@JsName("MIN_VALUE") val MIN_VALUE: Short = -32768
@JsName("MAX_VALUE") val MAX_VALUE: Short = 32767
}
-private object ByteCompanionObject {
+@JsName("ByteCompanionObject") private object ByteCompanionObject {
@JsName("MIN_VALUE") val MIN_VALUE: Byte = -128
@JsName("MAX_VALUE") val MAX_VALUE: Byte = 127
}
-private object CharCompanionObject {
+@JsName("CharCompanionObject") private object CharCompanionObject {
@JsName("MIN_HIGH_SURROGATE") public const val MIN_HIGH_SURROGATE: Char = '\uD800'
@JsName("MAX_HIGH_SURROGATE") public const val MAX_HIGH_SURROGATE: Char = '\uDBFF'
@JsName("MIN_LOW_SURROGATE") public const val MIN_LOW_SURROGATE: Char = '\uDC00'
diff --git a/js/js.libraries/src/core/builtins.kt b/js/js.libraries/src/core/builtins.kt
new file mode 100644
index 00000000000..9d1ebc3d2d3
--- /dev/null
+++ b/js/js.libraries/src/core/builtins.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2016 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.
+ */
+
+@JsName("arrayIterator")
+internal fun arrayIterator(array: dynamic): MutableIterator {
+ return object : MutableIterator {
+ var index = 0;
+
+ override fun hasNext(): Boolean {
+ val length: Int = array.length
+ return index < length
+ }
+
+ override fun next() = array[index++]
+
+ override fun remove() {
+ array.splice(--index, 1)
+ }
+ }
+}
diff --git a/js/js.libraries/src/core/exceptions.kt b/js/js.libraries/src/core/exceptions.kt
index 9a522357cc5..57dbb7289f4 100644
--- a/js/js.libraries/src/core/exceptions.kt
+++ b/js/js.libraries/src/core/exceptions.kt
@@ -16,41 +16,28 @@
package kotlin
-@library
-public open class Error(message: String? = null) : Throwable(message) {}
+open class Error(message: String? = null) : Throwable(message, null) {}
-@library
-public open class Exception(message: String? = null) : Throwable(message) {}
+open class Exception(message: String? = null) : Throwable(message, null) {}
-@library
-public open class RuntimeException(message: String? = null) : Exception(message) {}
+open class RuntimeException(message: String? = null) : Exception(message) {}
-@library
-public open class IllegalArgumentException(message: String? = null) : RuntimeException(message) {}
+open class IllegalArgumentException(message: String? = null) : RuntimeException(message) {}
-@library
-public open class IllegalStateException(message: String? = null) : RuntimeException(message) {}
+open class IllegalStateException(message: String? = null) : RuntimeException(message) {}
-@library
-public open class IndexOutOfBoundsException(message: String? = null) : RuntimeException(message) {}
+open class IndexOutOfBoundsException(message: String? = null) : RuntimeException(message) {}
-@library
-public open class ConcurrentModificationException(message: String? = null) : RuntimeException(message) {}
+open class ConcurrentModificationException(message: String? = null) : RuntimeException(message) {}
-@library
-public open class UnsupportedOperationException(message: String? = null) : RuntimeException(message) {}
+open class UnsupportedOperationException(message: String? = null) : RuntimeException(message) {}
-@library
-public open class NumberFormatException(message: String? = null) : RuntimeException(message) {}
+open class NumberFormatException(message: String? = null) : RuntimeException(message) {}
-@library
-public open class NullPointerException(message: String? = null) : RuntimeException(message) {}
+open class NullPointerException(message: String? = null) : RuntimeException(message) {}
-@library
-public open class ClassCastException(message: String? = null) : RuntimeException(message) {}
+open class ClassCastException(message: String? = null) : RuntimeException(message) {}
-@library
-public open class AssertionError(message: String? = null) : Error(message) {}
+open class AssertionError(message: String? = null) : Error(message) {}
-@library
-public open class NoSuchElementException(message: String? = null) : Exception() {}
+open class NoSuchElementException(message: String? = null) : Exception() {}
diff --git a/js/js.libraries/src/core/javalang.kt b/js/js.libraries/src/core/javalang.kt
index 7445d8df3ef..be57e90250f 100644
--- a/js/js.libraries/src/core/javalang.kt
+++ b/js/js.libraries/src/core/javalang.kt
@@ -17,25 +17,50 @@
package java.lang
-@library
-public interface Appendable {
- public fun append(csq: CharSequence?): Appendable
- public fun append(csq: CharSequence?, start: Int, end: Int): Appendable
- public fun append(c: Char): Appendable
+interface Appendable {
+ fun append(csq: CharSequence?): Appendable
+ fun append(csq: CharSequence?, start: Int, end: Int): Appendable
+ fun append(c: Char): Appendable
}
-@library
-public class StringBuilder(content: String = "") : Appendable, CharSequence {
- override val length: Int = noImpl
- override fun get(index: Int): Char = noImpl
- override fun subSequence(start: Int, end: Int): CharSequence = noImpl
- override fun append(c: Char): StringBuilder = noImpl
- override fun append(csq: CharSequence?): StringBuilder = noImpl
- override fun append(csq: CharSequence?, start: Int, end: Int): StringBuilder = noImpl
- public fun append(obj: Any?): StringBuilder = noImpl
- public fun reverse(): StringBuilder = noImpl
- override fun toString(): String = noImpl
-}
+class StringBuilder(content: String = "") : Appendable, CharSequence {
+ constructor(capacity: Int) : this() {}
-public inline fun StringBuilder(capacity: Int): StringBuilder = StringBuilder()
-public inline fun StringBuilder(content: CharSequence): StringBuilder = StringBuilder(content.toString())
+ constructor(content: CharSequence) : this(content.toString()) {}
+
+ private var string: String = content
+
+ override val length: Int = string.length
+
+ override fun get(index: Int): Char = string[index]
+
+ override fun subSequence(start: Int, end: Int): CharSequence = string.substring(start, end)
+
+ override fun append(c: Char): StringBuilder {
+ string += c
+ return this
+ }
+
+ override fun append(csq: CharSequence?): StringBuilder {
+ string += csq.toString()
+ return this
+ }
+
+ override fun append(csq: CharSequence?, start: Int, end: Int): StringBuilder {
+ string += csq.toString().substring(start, end)
+ return this
+ }
+
+ fun append(obj: Any?): StringBuilder {
+ string += obj.toString()
+ return this
+ }
+
+ fun reverse(): StringBuilder {
+ val nativeString: dynamic = string
+ string = nativeString.split("").reverse().join("")
+ return this
+ }
+
+ override fun toString(): String = string
+}
diff --git a/js/js.libraries/src/core/javautil.kt b/js/js.libraries/src/core/javautil.kt
index 2fa0fd8d849..d891d72dab4 100644
--- a/js/js.libraries/src/core/javautil.kt
+++ b/js/js.libraries/src/core/javautil.kt
@@ -16,12 +16,11 @@
package java.util
-@library
-public interface Comparator {
- public fun compare(a: T, b: T): Int
+interface Comparator {
+ @JsName("compare") fun compare(a: T, b: T): Int
}
-public inline fun Comparator(crossinline comparison: (T, T) -> Int): Comparator = object : Comparator {
+inline fun Comparator(crossinline comparison: (T, T) -> Int): Comparator = object : Comparator {
override fun compare(a: T, b: T): Int = comparison(a, b)
}
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java
index 951c323c1fe..6d56a2efc65 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java
@@ -56,8 +56,8 @@ public final class Namer {
public static final String EQUALS_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatform.INSTANCE.getBuiltIns().getAny(), "equals");
public static final String COMPARE_TO_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatform.INSTANCE.getBuiltIns().getComparable(), "compareTo");
- public static final String NUMBER_RANGE = "NumberRange";
- public static final String CHAR_RANGE = "CharRange";
+ public static final String INT_RANGE = "kotlin.ranges.IntRange";
+ public static final String CHAR_RANGE = "kotlin.ranges.CharRange";
public static final String LONG_FROM_NUMBER = "fromNumber";
public static final String LONG_TO_NUMBER = "toNumber";
public static final String LONG_FROM_INT = "fromInt";
@@ -380,11 +380,6 @@ public final class Namer {
return result;
}
- @NotNull
- /*package*/ JsObjectScope getKotlinScope() {
- return kotlinScope;
- }
-
@NotNull
static String generatePackageName(@NotNull FqName packageFqName) {
return packageFqName.isRoot() ? getRootPackageName() : packageFqName.shortName().asString();
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StandardClasses.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StandardClasses.java
deleted file mode 100644
index e6c16efbf7d..00000000000
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StandardClasses.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright 2010-2015 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.kotlin.js.translate.context;
-
-import com.google.common.collect.Maps;
-import com.google.dart.compiler.backend.js.ast.JsName;
-import com.google.dart.compiler.backend.js.ast.JsObjectScope;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.builtins.PrimitiveType;
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
-import org.jetbrains.kotlin.name.FqNameUnsafe;
-import org.jetbrains.kotlin.name.Name;
-
-import java.util.Map;
-
-import static com.google.dart.compiler.backend.js.ast.JsScopesKt.JsObjectScope;
-import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
-
-/**
- * Provides a mechanism to bind some of the Kotlin/Java declarations with library implementations.
- * Makes sense only for those declaration that cannot be annotated. (Use library annotation in this case)
- */
-public final class StandardClasses {
-
- private final class Builder {
-
- @Nullable
- private /*var*/ FqNameUnsafe currentFQName = null;
- @Nullable
- private /*var*/ String currentObjectName = null;
-
- @NotNull
- public Builder forFQ(@NotNull String classFQName) {
- currentFQName = new FqNameUnsafe(classFQName);
- return this;
- }
-
- @NotNull
- public Builder kotlinClass(@NotNull String kotlinName) {
- kotlinTopLevelObject(kotlinName);
- constructor();
- return this;
- }
-
- private void kotlinTopLevelObject(@NotNull String kotlinName) {
- assert currentFQName != null;
- currentObjectName = kotlinName;
- declareKotlinObject(currentFQName, kotlinName);
- }
-
- @NotNull
- private Builder constructor() {
- assert currentFQName != null;
- assert currentObjectName != null;
- declareInner(currentFQName, "", currentObjectName);
- return this;
- }
-
- @NotNull
- public Builder methods(@NotNull String... methodNames) {
- assert currentFQName != null;
- declareMethods(currentFQName, methodNames);
- return this;
- }
-
- @NotNull
- public Builder properties(@NotNull String... propertyNames) {
- assert currentFQName != null;
- declareReadonlyProperties(currentFQName, propertyNames);
- return this;
- }
- }
-
- @NotNull
- public static StandardClasses bindImplementations(@NotNull JsObjectScope kotlinObjectScope) {
- StandardClasses standardClasses = new StandardClasses(kotlinObjectScope);
- declareKotlinStandardClasses(standardClasses);
- return standardClasses;
- }
-
- private static void declareKotlinStandardClasses(@NotNull StandardClasses standardClasses) {
- for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) {
- if (type == PrimitiveType.CHAR || type == PrimitiveType.LONG) continue;
-
- String typeName = type.getTypeName().asString();
- standardClasses.declare().forFQ("kotlin.ranges." + typeName + "Range").kotlinClass("NumberRange");
- standardClasses.declare().forFQ("kotlin.ranges." + typeName + "Progression").kotlinClass("NumberProgression");
- }
-
- standardClasses.declare().forFQ("kotlin.ranges.LongRange").kotlinClass("LongRange");
- standardClasses.declare().forFQ("kotlin.ranges.CharRange").kotlinClass("CharRange");
-
- standardClasses.declare().forFQ("kotlin.ranges.LongProgression").kotlinClass("LongProgression");
- standardClasses.declare().forFQ("kotlin.ranges.CharProgression").kotlinClass("CharProgression");
-
- standardClasses.declare().forFQ("kotlin.Enum").kotlinClass("Enum");
-
- standardClasses.declare().forFQ("kotlin.Comparable").kotlinClass("Comparable");
-
- standardClasses.declare().forFQ("kotlin.Throwable").kotlinClass("Throwable");
- standardClasses.declare().forFQ("kotlin.Annotation").kotlinClass("Annotation");
- }
-
-
- @NotNull
- private final JsObjectScope kotlinScope;
-
-
- @NotNull
- private final Map standardObjects = Maps.newHashMap();
-
- @NotNull
- private final Map scopeMap = Maps.newHashMap();
-
- private StandardClasses(@NotNull JsObjectScope kotlinScope) {
- this.kotlinScope = kotlinScope;
- }
-
- private void declareTopLevelObjectInScope(@NotNull JsObjectScope scope, @NotNull Map map,
- @NotNull FqNameUnsafe fullQualifiedName, @NotNull String name) {
- JsName declaredName = scope.declareName(name);
- map.put(fullQualifiedName, declaredName);
- scopeMap.put(fullQualifiedName, JsObjectScope(scope, "scope for " + name));
- }
-
- private void declareKotlinObject(@NotNull FqNameUnsafe fullQualifiedName, @NotNull String kotlinLibName) {
- declareTopLevelObjectInScope(kotlinScope, standardObjects, fullQualifiedName, kotlinLibName);
- }
-
- private void declareInner(@NotNull FqNameUnsafe fullQualifiedClassName,
- @NotNull String shortMethodName,
- @NotNull String javascriptName) {
- JsObjectScope classScope = scopeMap.get(fullQualifiedClassName);
- assert classScope != null;
- FqNameUnsafe fullQualifiedMethodName = fullQualifiedClassName.child(Name.guessByFirstCharacter(shortMethodName));
- standardObjects.put(fullQualifiedMethodName, classScope.declareName(javascriptName));
- }
-
- private void declareMethods(@NotNull FqNameUnsafe classFQName,
- @NotNull String... methodNames) {
- for (String methodName : methodNames) {
- declareInner(classFQName, methodName, methodName);
- }
- }
-
- private void declareReadonlyProperties(@NotNull FqNameUnsafe classFQName,
- @NotNull String... propertyNames) {
- for (String propertyName : propertyNames) {
- declareInner(classFQName, propertyName, propertyName);
- }
- }
-
- public boolean isStandardObject(@NotNull DeclarationDescriptor descriptor) {
- return standardObjects.containsKey(getFqName(descriptor));
- }
-
- @NotNull
- public JsName getStandardObjectName(@NotNull DeclarationDescriptor descriptor) {
- return standardObjects.get(getFqName(descriptor));
- }
-
- @NotNull
- private Builder declare() {
- return new Builder();
- }
-}
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java
index b6bf6731e94..95e41e59b02 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java
@@ -35,9 +35,11 @@ import org.jetbrains.kotlin.js.naming.NameSuggestion;
import org.jetbrains.kotlin.js.naming.SuggestedName;
import org.jetbrains.kotlin.js.translate.context.generator.Generator;
import org.jetbrains.kotlin.js.translate.context.generator.Rule;
+import org.jetbrains.kotlin.js.translate.declaration.ClassTranslator;
import org.jetbrains.kotlin.js.translate.intrinsic.Intrinsics;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.name.FqName;
+import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingTrace;
@@ -65,11 +67,8 @@ public final class StaticContext {
@NotNull ModuleDescriptor moduleDescriptor) {
JsProgram program = new JsProgram("main");
Namer namer = Namer.newInstance(program.getRootScope());
- Intrinsics intrinsics = new Intrinsics();
- StandardClasses standardClasses = StandardClasses.bindImplementations(namer.getKotlinScope());
JsFunction rootFunction = JsAstUtils.createFunctionWithEmptyBody(program.getScope());
- return new StaticContext(program, rootFunction, bindingTrace, namer, intrinsics, standardClasses, program.getRootScope(), config,
- moduleDescriptor);
+ return new StaticContext(program, rootFunction, bindingTrace, namer, program.getRootScope(), config, moduleDescriptor);
}
@NotNull
@@ -83,9 +82,6 @@ public final class StaticContext {
@NotNull
private final Intrinsics intrinsics;
- @NotNull
- private final StandardClasses standardClasses;
-
@NotNull
private final JsScope rootScope;
@@ -139,6 +135,9 @@ public final class StaticContext {
@NotNull
private final List declarationStatements = new ArrayList();
+ @NotNull
+ private final List topLevelStatements = new ArrayList();
+
@NotNull
private final List importStatements = new ArrayList();
@@ -160,8 +159,6 @@ public final class StaticContext {
@NotNull JsFunction rootFunction,
@NotNull BindingTrace bindingTrace,
@NotNull Namer namer,
- @NotNull Intrinsics intrinsics,
- @NotNull StandardClasses standardClasses,
@NotNull JsScope rootScope,
@NotNull JsConfig config,
@NotNull ModuleDescriptor moduleDescriptor
@@ -170,9 +167,8 @@ public final class StaticContext {
this.rootFunction = rootFunction;
this.bindingTrace = bindingTrace;
this.namer = namer;
- this.intrinsics = intrinsics;
+ this.intrinsics = new Intrinsics(this);
this.rootScope = rootScope;
- this.standardClasses = standardClasses;
this.config = config;
this.currentModule = moduleDescriptor;
this.rootFunction = rootFunction;
@@ -247,8 +243,14 @@ public final class StaticContext {
@NotNull
private JsExpression buildQualifiedExpression(@NotNull DeclarationDescriptor descriptor) {
- if (descriptor instanceof ClassDescriptor && KotlinBuiltIns.isAny((ClassDescriptor) descriptor)) {
- return new JsNameRef("Object");
+ if (descriptor instanceof ClassDescriptor) {
+ ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
+ if (KotlinBuiltIns.isAny(classDescriptor)) {
+ return pureFqn("Object", null);
+ }
+ if (DescriptorUtils.getFqName(classDescriptor).asString().equals("kotlin.Throwable")) {
+ return pureFqn("Error", null);
+ }
}
SuggestedName suggested = nameSuggestion.suggest(descriptor);
@@ -259,26 +261,20 @@ public final class StaticContext {
}
JsExpression expression;
- List partNames;
- if (standardClasses.isStandardObject(suggested.getDescriptor())) {
+ List partNames = getActualNameFromSuggested(suggested);
+ if (isLibraryObject(suggested.getDescriptor())) {
expression = Namer.kotlinObject();
- partNames = Collections.singletonList(standardClasses.getStandardObjectName(suggested.getDescriptor()));
+ }
+ // Don't generate qualifier for top-level native declarations
+ // Don't generate qualifier for local declarations
+ else if (isNativeObject(suggested.getDescriptor()) && !isNativeObject(suggested.getScope()) ||
+ suggested.getDescriptor() instanceof CallableDescriptor && suggested.getScope() instanceof FunctionDescriptor) {
+ expression = null;
}
else {
- partNames = getActualNameFromSuggested(suggested);
- if (isLibraryObject(suggested.getDescriptor())) {
- expression = Namer.kotlinObject();
- }
- // Don't generate qualifier for top-level native declarations
- // Don't generate qualifier for local declarations
- else if (isNativeObject(suggested.getDescriptor()) && !isNativeObject(suggested.getScope()) ||
- suggested.getDescriptor() instanceof CallableDescriptor && suggested.getScope() instanceof FunctionDescriptor) {
- expression = null;
- }
- else {
- expression = getQualifiedExpression(suggested.getScope());
- }
+ expression = getQualifiedExpression(suggested.getScope());
}
+
for (JsName partName : partNames) {
expression = new JsNameRef(partName, expression);
applySideEffects(expression, suggested.getDescriptor());
@@ -408,6 +404,13 @@ public final class StaticContext {
return config;
}
+ @NotNull
+ public JsName importDeclaration(@NotNull String suggestedName, @NotNull JsExpression declaration) {
+ JsName result = rootFunction.getScope().declareFreshName(suggestedName);
+ importStatements.add(JsAstUtils.newVar(result, declaration));
+ return result;
+ }
+
private final class InnerNameGenerator extends Generator {
public InnerNameGenerator() {
addRule(new Rule() {
@@ -643,12 +646,13 @@ public final class StaticContext {
}
@NotNull
- public List getDeclarationStatements() {
- return declarationStatements;
+ public List getTopLevelStatements() {
+ return topLevelStatements;
}
- public void addRootStatement(@NotNull JsStatement statement) {
- declarationStatements.add(statement);
+ @NotNull
+ public List getDeclarationStatements() {
+ return declarationStatements;
}
public void addClass(@NotNull ClassDescriptor classDescriptor) {
@@ -690,9 +694,11 @@ public final class StaticContext {
}
public void postProcess() {
+ addInterfaceDefaultMethods();
rootFunction.getBody().getStatements().addAll(importStatements);
addClassPrototypes();
rootFunction.getBody().getStatements().addAll(declarationStatements);
+ rootFunction.getBody().getStatements().addAll(topLevelStatements);
JsName rootPackageName = rootFunction.getScope().declareName(Namer.getRootPackageName());
rootFunction.getBody().getStatements().add(JsAstUtils.newVar(rootPackageName, exportObject));
@@ -727,6 +733,24 @@ public final class StaticContext {
}
}
+ private void addInterfaceDefaultMethods() {
+ for (ClassDescriptor classDescriptor : classes) {
+ if (classDescriptor.getKind() != ClassKind.INTERFACE) {
+ ClassTranslator.addInterfaceDefaultMembers(classDescriptor, this);
+ }
+ }
+ }
+
+ public boolean isBuiltinModule() {
+ for (ClassDescriptor cls : classes) {
+ FqNameUnsafe fqn = DescriptorUtils.getFqName(cls);
+ if ("kotlin.Enum".equals(fqn.asString())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private static class ExportedPackage {
@NotNull final String name;
@NotNull final Map subpackages = new HashMap();
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java
index c7c5427efe0..202d21393f3 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java
@@ -63,7 +63,7 @@ public class TranslationContext {
@NotNull StaticContext staticContext,
@NotNull JsFunction rootFunction
) {
- JsBlock block = new JsBlock(staticContext.getDeclarationStatements());
+ JsBlock block = new JsBlock(staticContext.getTopLevelStatements());
DynamicContext rootDynamicContext = DynamicContext.rootContext(rootFunction.getScope(), block);
AliasingContext rootAliasingContext = AliasingContext.getCleanContext();
return new TranslationContext(null, staticContext, rootDynamicContext, rootAliasingContext, null, null);
@@ -178,6 +178,11 @@ public class TranslationContext {
return this.innerWithAliasingContext(aliasingContext.withDescriptorsAliased(aliases));
}
+ @NotNull
+ public JsName importDeclaration(@NotNull String suggestedName, @NotNull JsExpression declaration) {
+ return staticContext.importDeclaration(suggestedName, declaration);
+ }
+
@Nullable
private JsBlock getBlockForDescriptor(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof CallableDescriptor) {
@@ -225,8 +230,8 @@ public class TranslationContext {
}
@NotNull
- public JsName declarePropertyOrPropertyAccessorName(@NotNull DeclarationDescriptor descriptor, @NotNull String name, boolean fresh) {
- return staticContext.declarePropertyOrPropertyAccessorName(descriptor, name, fresh);
+ public JsName declarePropertyOrPropertyAccessorName(@NotNull DeclarationDescriptor descriptor, @NotNull String name) {
+ return staticContext.declarePropertyOrPropertyAccessorName(descriptor, name, false);
}
@NotNull
@@ -235,13 +240,13 @@ public class TranslationContext {
}
@NotNull
- public JsNameRef getInnerReference(@NotNull DeclarationDescriptor descriptor) {
- return JsAstUtils.pureFqn(getInnerNameForDescriptor(descriptor), null);
+ public JsNameRef getQualifiedReference(@NotNull FqName fqName) {
+ return staticContext.getQualifiedReference(fqName);
}
@NotNull
- public JsNameRef getQualifiedReference(@NotNull FqName packageFqName) {
- return staticContext.getQualifiedReference(packageFqName);
+ public JsNameRef getInnerReference(@NotNull DeclarationDescriptor descriptor) {
+ return JsAstUtils.pureFqn(getInnerNameForDescriptor(descriptor), null);
}
@NotNull
@@ -567,14 +572,18 @@ public class TranslationContext {
return staticContext.getRootFunction();
}
- public void addRootStatement(@NotNull JsStatement statement) {
- staticContext.addRootStatement(statement);
+ public void addDeclarationStatement(@NotNull JsStatement statement) {
+ staticContext.getDeclarationStatements().add(statement);
+ }
+
+ public void addTopLevelStatement(@NotNull JsStatement statement) {
+ staticContext.getTopLevelStatements().add(statement);
}
@NotNull
public JsFunction defineTopLevelFunction(@NotNull DeclarationDescriptor descriptor) {
JsFunction function = createTopLevelFunction(descriptor);
- addRootStatement(function.makeStmt());
+ addDeclarationStatement(function.makeStmt());
return function;
}
@@ -584,7 +593,7 @@ public class TranslationContext {
}
@NotNull
- public JsFunction createTopLevelFunction(@NotNull DeclarationDescriptor descriptor) {
+ private JsFunction createTopLevelFunction(@NotNull DeclarationDescriptor descriptor) {
JsFunction function = createTopLevelAnonymousFunction(descriptor);
function.setName(staticContext.getInnerNameForDescriptor(descriptor));
return function;
@@ -606,4 +615,14 @@ public class TranslationContext {
public boolean isFromCurrentModule(@NotNull DeclarationDescriptor descriptor) {
return staticContext.getCurrentModule() == DescriptorUtilsKt.getModule(descriptor);
}
+
+ @NotNull
+ public ModuleDescriptor getCurrentModule() {
+ return staticContext.getCurrentModule();
+ }
+
+ @Nullable
+ public TranslationContext getParent() {
+ return parent;
+ }
}
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt
index d518498b463..c87cf9e8325 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.js.translate.initializer.ClassInitializerTranslator
import org.jetbrains.kotlin.js.translate.utils.*
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter
+import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getSupertypesWithoutFakes
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getPrimaryConstructorParameters
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.toInvocationWith
@@ -62,15 +63,11 @@ class ClassTranslator private constructor(
private lateinit var cachedInstanceName: JsName
private val metadataLiteral = JsObjectLiteral(true)
- private fun translate() {
- generateClassCreateInvocationArguments()
- }
-
private fun isTrait(): Boolean = descriptor.kind == ClassKind.INTERFACE
private fun isAnnotation(): Boolean = descriptor.kind == ClassKind.ANNOTATION_CLASS
- private fun generateClassCreateInvocationArguments() {
+ private fun translate() {
val scope = context().getScopeForDescriptor(descriptor)
val context = context().newDeclaration(descriptor)
@@ -92,10 +89,6 @@ class ClassTranslator private constructor(
addSuperclassReferences()
classDeclaration.getSecondaryConstructors().forEach { generateSecondaryConstructor(context, it) }
- if (descriptor.kind != ClassKind.INTERFACE) {
- addInterfaceDefaultMembers()
- }
-
generatedBridgeMethods()
if (descriptor.isData) {
@@ -148,7 +141,7 @@ class ClassTranslator private constructor(
}
private fun addMetadataObject() {
- context().addRootStatement(JsAstUtils.assignment(createMetadataRef(), metadataLiteral).makeStmt())
+ context().addDeclarationStatement(JsAstUtils.assignment(createMetadataRef(), metadataLiteral).makeStmt())
}
private fun createMetadataRef() = JsNameRef(Namer.METADATA, context().getInnerReference(descriptor))
@@ -247,6 +240,10 @@ class ClassTranslator private constructor(
}
secondaryConstructors += ConstructorInfo(constructorInitializer, context, constructorDescriptor, compositeSuperCallGenerator)
+
+ if (DescriptorUtils.isTopLevelDeclaration(classDescriptor)) {
+ context.export(constructorDescriptor)
+ }
}
private val allConstructors: Sequence
@@ -378,58 +375,13 @@ class ClassTranslator private constructor(
}
}
- private fun addInterfaceDefaultMembers() {
- val members = descriptor.unsubstitutedMemberScope
- .getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
- .mapNotNull { it as? CallableMemberDescriptor }
- for (member in members) {
- if (member.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue
- if (member.modality == Modality.ABSTRACT || member.overriddenDescriptors.size != 1) continue
-
- val overriddenFunction = generateSequence(member) { it.overriddenDescriptors.firstOrNull() }
- .drop(1)
- .dropWhile { it.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
- DescriptorUtils.isInterface(it.containingDeclaration) }
- .firstOrNull() ?: continue
-
- val interfaceDescriptor = overriddenFunction.containingDeclaration as ClassDescriptor
- if (interfaceDescriptor.kind != ClassKind.INTERFACE) continue
-
- when (member) {
- is FunctionDescriptor -> addDefaultMethodFromInterface(member, interfaceDescriptor)
- is PropertyDescriptor -> addDefaultPropertyFromInterface(member, interfaceDescriptor)
- }
- }
- }
-
- private fun addDefaultMethodFromInterface(function: FunctionDescriptor, interfaceDescriptor: ClassDescriptor) {
- val classPrototype = JsAstUtils.prototypeOf(context().getInnerReference(descriptor))
- val interfacePrototype = JsAstUtils.prototypeOf(context().getInnerReference(interfaceDescriptor))
- val functionName = context().getNameForDescriptor(function)
- val classFunction = JsNameRef(functionName, classPrototype)
- val interfaceFunction = JsNameRef(functionName, interfacePrototype)
- context().addRootStatement(JsAstUtils.assignment(classFunction, interfaceFunction).makeStmt())
- }
-
- private fun addDefaultPropertyFromInterface(property: PropertyDescriptor, interfaceDescriptor: ClassDescriptor) {
- val classPrototype = JsAstUtils.prototypeOf(context().getInnerReference(descriptor))
- val interfacePrototype = JsAstUtils.prototypeOf(context().getInnerReference(interfaceDescriptor))
- val functionName = context().getNameForDescriptor(property)
- val nameLiteral = context().program().getStringLiteral(functionName.ident)
-
- val getPropertyDescriptor = JsInvocation(JsNameRef("getOwnPropertyDescriptor", "Object"), interfacePrototype, nameLiteral)
- val defineProperty = JsAstUtils.defineProperty(classPrototype, functionName.ident, getPropertyDescriptor, context().program())
-
- context().addRootStatement(defineProperty.makeStmt())
- }
-
private fun addObjectCache(statements: MutableList) {
cachedInstanceName = context().createGlobalName(StaticContext.getSuggestedName(descriptor) + Namer.OBJECT_INSTANCE_VAR_SUFFIX)
statements += JsAstUtils.assignment(cachedInstanceName.makeRef(), JsObjectLiteral.THIS).makeStmt()
}
private fun addObjectMethods() {
- context().addRootStatement(JsAstUtils.newVar(cachedInstanceName, JsLiteral.NULL))
+ context().addDeclarationStatement(JsAstUtils.newVar(cachedInstanceName, JsLiteral.NULL))
val instanceFun = JsFunction(context().rootFunction.scope, JsBlock(), "Instance function: " + descriptor)
instanceFun.name = context().getNameForObjectInstance(descriptor)
@@ -444,7 +396,7 @@ class ClassTranslator private constructor(
instanceFun.body.statements += JsReturn(cachedInstanceName.makeRef())
- context().addRootStatement(instanceFun.makeStmt())
+ context().addDeclarationStatement(instanceFun.makeStmt())
}
private fun generatedBridgeMethods() {
@@ -499,6 +451,61 @@ class ClassTranslator private constructor(
@JvmStatic fun translate(classDeclaration: KtClassOrObject, context: TranslationContext) {
return ClassTranslator(classDeclaration, context).translate()
}
+
+ @JvmStatic fun addInterfaceDefaultMembers(descriptor: ClassDescriptor, context: StaticContext) {
+ val members = descriptor.unsubstitutedMemberScope
+ .getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
+ .mapNotNull { it as? CallableMemberDescriptor }
+ for (member in members) {
+ if (member.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue
+ if (member.modality == Modality.ABSTRACT || member.overriddenDescriptors.size != 1) continue
+
+ val overriddenFunction = generateSequence(member) { it.overriddenDescriptors.firstOrNull() }
+ .drop(1)
+ .dropWhile { it.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
+ DescriptorUtils.isInterface(it.containingDeclaration) }
+ .firstOrNull() ?: continue
+
+ val interfaceDescriptor = overriddenFunction.containingDeclaration as ClassDescriptor
+ if (interfaceDescriptor.kind != ClassKind.INTERFACE) continue
+
+ when (member) {
+ is FunctionDescriptor -> addDefaultMethodFromInterface(member, interfaceDescriptor, descriptor, context)
+ is PropertyDescriptor -> addDefaultPropertyFromInterface(member, interfaceDescriptor, descriptor, context)
+ }
+ }
+ }
+
+ private fun addDefaultMethodFromInterface(
+ function: FunctionDescriptor,
+ interfaceDescriptor: ClassDescriptor,
+ descriptor: ClassDescriptor,
+ context: StaticContext
+ ) {
+ val classPrototype = JsAstUtils.prototypeOf(pureFqn(context.getInnerNameForDescriptor(descriptor), null))
+ val interfacePrototype = JsAstUtils.prototypeOf(pureFqn(context.getInnerNameForDescriptor(interfaceDescriptor), null))
+ val functionName = context.getNameForDescriptor(function)
+ val classFunction = JsNameRef(functionName, classPrototype)
+ val interfaceFunction = JsNameRef(functionName, interfacePrototype)
+ context.declarationStatements += JsAstUtils.assignment(classFunction, interfaceFunction).makeStmt()
+ }
+
+ private fun addDefaultPropertyFromInterface(
+ property: PropertyDescriptor,
+ interfaceDescriptor: ClassDescriptor,
+ descriptor: ClassDescriptor,
+ context: StaticContext
+ ) {
+ val classPrototype = JsAstUtils.prototypeOf(pureFqn(context.getInnerNameForDescriptor(descriptor), null))
+ val interfacePrototype = JsAstUtils.prototypeOf(pureFqn(context.getInnerNameForDescriptor(interfaceDescriptor), null))
+ val functionName = context.getNameForDescriptor(property)
+ val nameLiteral = context.program.getStringLiteral(functionName.ident)
+
+ val getPropertyDescriptor = JsInvocation(JsNameRef("getOwnPropertyDescriptor", "Object"), interfacePrototype, nameLiteral)
+ val defineProperty = JsAstUtils.defineProperty(classPrototype, functionName.ident, getPropertyDescriptor, context.program)
+
+ context.declarationStatements += defineProperty.makeStmt()
+ }
}
private class ConstructorInfo(
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt
index fcaee0d6450..a5850e50257 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt
@@ -67,14 +67,14 @@ class DeclarationBodyVisitor(
val enumInstanceFunction = context.createTopLevelAnonymousFunction(descriptor)
enumInstanceFunction.name = context.getNameForObjectInstance(descriptor)
- context.addRootStatement(enumInstanceFunction.makeStmt())
+ context.addDeclarationStatement(enumInstanceFunction.makeStmt())
val classRef = context.getInnerReference(descriptor.containingDeclaration)
val enumExtName = context.getNameForDescriptor(descriptor)
val enumExtFq = JsNameRef(enumExtName, classRef)
- context.addRootStatement(JsAstUtils.assignment(enumExtFq, enumInstanceFunction.name.makeRef()).makeStmt())
+ context.addDeclarationStatement(JsAstUtils.assignment(enumExtFq, enumInstanceFunction.name.makeRef()).makeStmt())
- context.addRootStatement(JsAstUtils.newVar(enumInstanceName, jsEnumEntryCreation))
+ context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, jsEnumEntryCreation))
enumInstanceFunction.body.statements.add(JsReturn(enumInstanceName.makeRef()))
}
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DefineInvocation.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DefineInvocation.java
deleted file mode 100644
index af97cde2746..00000000000
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DefineInvocation.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2010-2015 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.kotlin.js.translate.declaration;
-
-import com.google.dart.compiler.backend.js.ast.*;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.js.translate.context.TranslationContext;
-import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
-import org.jetbrains.kotlin.name.FqName;
-
-import java.util.AbstractList;
-import java.util.List;
-
-public class DefineInvocation {
-
- /* package */
- @NotNull
- static DefineInvocation create(
- @NotNull FqName packageFqName,
- @Nullable JsExpression initializer,
- @NotNull JsObjectLiteral members,
- @NotNull TranslationContext context
- ) {
- return new DefineInvocation(initializer == null ? JsLiteral.NULL : initializer,
- new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, context.getQualifiedReference(packageFqName)),
- members);
- }
-
- @NotNull
- private JsExpression initializer;
- @NotNull
- private final JsDocComment jsDocComment;
- @NotNull
- private final JsObjectLiteral membersObjectLiteral;
-
- private DefineInvocation(
- @NotNull JsExpression initializer,
- @NotNull JsDocComment jsDocComment,
- @NotNull JsObjectLiteral membersObjectLiteral
- ) {
- this.initializer = initializer;
- this.jsDocComment = jsDocComment;
- this.membersObjectLiteral = membersObjectLiteral;
- }
-
- @NotNull
- public JsExpression getInitializer() {
- return initializer;
- }
-
- public void setInitializer(@NotNull JsExpression initializer) {
- this.initializer = initializer;
- }
-
- @NotNull
- public List getMembers() {
- return membersObjectLiteral.getPropertyInitializers();
- }
-
- @NotNull
- public List asList() {
- return new AbstractList() { // because initializer is mutable
- @NotNull
- @Override
- public JsExpression get(int index) {
- switch (index) {
- case 0:
- return initializer;
- case 1:
- return jsDocComment;
- case 2:
- return membersObjectLiteral;
- }
- throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size());
- }
-
- @Override
- public int size() {
- return 3;
- }
- };
- }
-
-}
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/FileDeclarationVisitor.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/FileDeclarationVisitor.kt
index 33a80152be8..f2be3e1cbf4 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/FileDeclarationVisitor.kt
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/FileDeclarationVisitor.kt
@@ -37,7 +37,10 @@ class FileDeclarationVisitor(private val context: TranslationContext) : Abstract
val backingFieldRequired = context.bindingContext()[BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor] ?: false
if (backingFieldRequired || expression.delegateExpression != null) {
val initializer = expression.delegateExpressionOrInitializer?.let { Translation.translateAsExpression(it, context) }
- context.addRootStatement(JsAstUtils.newVar(innerName, initializer))
+ context.addDeclarationStatement(JsAstUtils.newVar(innerName, null))
+ if (initializer != null) {
+ context.addTopLevelStatement(JsAstUtils.assignment(innerName.makeRef(), initializer).makeStmt())
+ }
}
super.visitProperty(expression, context)
@@ -71,10 +74,10 @@ class FileDeclarationVisitor(private val context: TranslationContext) : Abstract
when (expression) {
is JsFunction -> {
expression.name = name
- context.addRootStatement(expression.makeStmt())
+ context.addDeclarationStatement(expression.makeStmt())
}
else -> {
- context.addRootStatement(JsAstUtils.newVar(name, expression))
+ context.addDeclarationStatement(JsAstUtils.newVar(name, expression))
}
}
return name
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt
index ddb45dff492..2926152e1d6 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt
@@ -78,7 +78,7 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
lambda.isLocal = true
- context().addRootStatement(lambda.makeStmt())
+ context().addDeclarationStatement(lambda.makeStmt())
return lambda.name.makeRef().apply { sideEffects = SideEffectKind.PURE }
}
@@ -96,7 +96,7 @@ fun JsFunction.withCapturedParameters(
context: TranslationContext,
invokingContext: TranslationContext
): JsExpression {
- context.addRootStatement(makeStmt())
+ context.addDeclarationStatement(makeStmt())
val ref = name.makeRef().apply { sideEffects = SideEffectKind.PURE }
val invocation = JsInvocation(ref).apply { sideEffects = SideEffectKind.PURE }
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java
index dbe65b8c70d..59492220816 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java
@@ -263,7 +263,9 @@ public final class Translation {
PackageDeclarationTranslator.translateFiles(files, context);
staticContext.postProcess();
statements.add(0, program.getStringLiteral("use strict").makeStmt());
- defineModule(context, statements, config.getModuleId());
+ if (!staticContext.isBuiltinModule()) {
+ defineModule(context, statements, config.getModuleId());
+ }
mayBeGenerateTests(files, config, rootBlock, context);
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.java
index e6aa3166f42..a010936b3d2 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.java
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.intrinsic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
+import org.jetbrains.kotlin.js.translate.context.StaticContext;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.intrinsic.functions.FunctionIntrinsics;
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic;
@@ -34,7 +35,11 @@ import org.jetbrains.kotlin.psi.KtBinaryExpression;
public final class Intrinsics {
private final FunctionIntrinsics functionIntrinsics = new FunctionIntrinsics();
private final BinaryOperationIntrinsics binaryOperationIntrinsics = new BinaryOperationIntrinsics();
- private final ObjectIntrinsics objectIntrinsics = new ObjectIntrinsics();
+ private final ObjectIntrinsics objectIntrinsics;
+
+ public Intrinsics(@NotNull StaticContext staticContext) {
+ objectIntrinsics = new ObjectIntrinsics(staticContext);
+ }
@NotNull
public BinaryOperationIntrinsic getBinaryOperationIntrinsic(
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.java
index c38c7095fc4..a6291b05b60 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.java
@@ -43,7 +43,7 @@ public final class FunctionIntrinsics {
register(LongOperationFIF.INSTANCE);
register(PrimitiveUnaryOperationFIF.INSTANCE);
register(PrimitiveBinaryOperationFIF.INSTANCE);
- register(StringOperationFIF.INSTANCE);
+ //register(StringOperationFIF.INSTANCE);
register(ArrayFIF.INSTANCE);
register(TopLevelFIF.INSTANCE);
register(NumberAndCharConversionFIF.INSTANCE);
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FqnCallIntrinsic.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FqnCallIntrinsic.kt
new file mode 100644
index 00000000000..884fb145605
--- /dev/null
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FqnCallIntrinsic.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010-2016 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.kotlin.js.translate.intrinsic.functions.basic
+
+import com.google.dart.compiler.backend.js.ast.JsExpression
+import org.jetbrains.kotlin.js.translate.context.Namer
+import org.jetbrains.kotlin.js.translate.context.TranslationContext
+import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
+
+class FqnCallIntrinsic(
+ simpleName: String,
+ fqn: String,
+ isConstructor: Boolean = false,
+ receiverAsArgument: Boolean = true
+) : LazyImportedCallIntrinsic(simpleName, isConstructor = isConstructor, receiverAsArgument = receiverAsArgument) {
+ val fqn = FqName(fqn)
+
+ override fun getExpression(context: TranslationContext): JsExpression {
+ val packageDescriptor = context.currentModule.getPackage(fqn.parent())
+
+ // Hack to compile stdlib
+ val descriptors = packageDescriptor.memberScope.getContributedDescriptors(DescriptorKindFilter.ALL) {
+ it.asString() == fqn.shortName().asString()
+ }
+
+ return if (descriptors.size == 1) {
+ JsAstUtils.replaceRootReference(context.getQualifiedReference(fqn), Namer.kotlinObject())
+ }
+ else {
+ context.getInnerReference(descriptors.first())
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/LazyImportedCallIntrinsic.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/LazyImportedCallIntrinsic.kt
new file mode 100644
index 00000000000..642d34937af
--- /dev/null
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/LazyImportedCallIntrinsic.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010-2016 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.kotlin.js.translate.intrinsic.functions.basic
+
+import com.google.dart.compiler.backend.js.ast.*
+import org.jetbrains.kotlin.js.translate.context.TranslationContext
+import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
+import org.jetbrains.kotlin.utils.singletonOrEmptyList
+import java.util.*
+
+abstract class LazyImportedCallIntrinsic(
+ val simpleName: String,
+ val isConstructor: Boolean = false,
+ val receiverAsArgument: Boolean = true
+) : FunctionIntrinsic() {
+ private val internalNameMap = WeakHashMap()
+
+ override fun apply(receiver: JsExpression?, arguments: MutableList, context: TranslationContext): JsExpression {
+ val rootContext = generateSequence(context) { it.parent }.last()
+ val functionName = internalNameMap.getOrPut(rootContext) {
+ val declaration = getExpression(rootContext)
+ if (declaration is JsNameRef && declaration.name != null && declaration.qualifier == null) {
+ declaration.name!!
+ }
+ else {
+ rootContext.importDeclaration(simpleName, declaration)
+ }
+ }
+ val allArguments = (if (receiverAsArgument) receiver else null).singletonOrEmptyList() + arguments
+ val function = pureFqn(functionName, null)
+ return if (isConstructor) JsNew(function, allArguments) else JsInvocation(function, allArguments)
+ }
+
+ abstract fun getExpression(context: TranslationContext): JsExpression
+}
\ No newline at end of file
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/LongOperationFIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/LongOperationFIF.kt
index 80d659073ec..f04c7a695b0 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/LongOperationFIF.kt
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/LongOperationFIF.kt
@@ -60,7 +60,6 @@ object LongOperationFIF : FunctionIntrinsicFactory {
private val floatBinaryIntrinsics: Map =
mapOf(
"compareTo" to BaseBinaryIntrinsic(::primitiveCompareTo),
- "rangeTo" to BaseBinaryIntrinsic(::numberRangeTo),
"plus" to BaseBinaryIntrinsic(::sum),
"minus" to BaseBinaryIntrinsic(::subtract),
"times" to BaseBinaryIntrinsic(::mul),
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java
index afec170115f..469edb8177a 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java
@@ -28,7 +28,9 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.js.patterns.DescriptorPredicate;
import org.jetbrains.kotlin.js.patterns.NamePredicate;
+import org.jetbrains.kotlin.js.translate.context.Namer;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
+import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FqnCallIntrinsic;
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic;
import org.jetbrains.kotlin.js.translate.operation.OperatorTable;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
@@ -61,24 +63,10 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
}
@NotNull
- private static final BinaryOperationIntrinsicBase RANGE_TO_INTRINSIC = new BinaryOperationIntrinsicBase() {
- @NotNull
- @Override
- public JsExpression doApply(@NotNull JsExpression left, @NotNull JsExpression right, @NotNull TranslationContext context) {
- //TODO: add tests and correct expression for reversed ranges.
- return JsAstUtils.numberRangeTo(left, right);
- }
- };
+ private static final FunctionIntrinsic RANGE_TO_INTRINSIC = new FqnCallIntrinsic("IntRange", Namer.INT_RANGE, true, true);
@NotNull
- private static final BinaryOperationIntrinsicBase CHAR_RANGE_TO_INTRINSIC = new BinaryOperationIntrinsicBase() {
- @NotNull
- @Override
- public JsExpression doApply(@NotNull JsExpression left, @NotNull JsExpression right, @NotNull TranslationContext context) {
- //TODO: add tests and correct expression for reversed ranges.
- return JsAstUtils.charRangeTo(left, right);
- }
- };
+ private static final FunctionIntrinsic CHAR_RANGE_TO_INTRINSIC = new FqnCallIntrinsic("CharRange", Namer.CHAR_RANGE, true, true);
@NotNull
private static final BinaryOperationIntrinsicBase INTEGER_DIVISION_INTRINSIC = new BinaryOperationIntrinsicBase() {
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ProgressionCompanionFIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ProgressionCompanionFIF.kt
index d31a7707844..4d93d06f931 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ProgressionCompanionFIF.kt
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ProgressionCompanionFIF.kt
@@ -21,24 +21,23 @@ import com.google.dart.compiler.backend.js.ast.JsNew
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern
import org.jetbrains.kotlin.js.translate.context.TranslationContext
+import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FqnCallIntrinsic
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
object ProgressionCompanionFIF : CompositeFIF() {
init {
- val numberProgressionConstructor = CallProgressionConstructorIntrinsic("NumberProgression")
- for (type in arrayOf(PrimitiveType.BYTE, PrimitiveType.SHORT, PrimitiveType.INT)) {
+ val numberProgressionConstructor = FqnCallIntrinsic("IntProgression", "kotlin.ranges.IntProgression", isConstructor = true,
+ receiverAsArgument = false)
+ for (type in arrayOf(PrimitiveType.INT)) {
add(methodPattern("${type.typeName}Progression"), numberProgressionConstructor)
}
- add(methodPattern("LongProgression"), CallProgressionConstructorIntrinsic("LongProgression"))
- add(methodPattern("CharProgression"), CallProgressionConstructorIntrinsic("CharProgression"))
- }
-
- private fun methodPattern(builtinProgressionName: String) = pattern("kotlin.ranges", builtinProgressionName, "Companion", "fromClosedRange")
-
- private class CallProgressionConstructorIntrinsic(val libraryProgressionName: String) : FunctionIntrinsic() {
- override fun apply(receiver: JsExpression?, arguments: MutableList, context: TranslationContext): JsExpression
- = JsNew(context.namer().kotlin(libraryProgressionName), arguments)
+ add(methodPattern("LongProgression"), FqnCallIntrinsic("LongProgression", "kotlin.ranges.LongProgression", isConstructor = true,
+ receiverAsArgument = false))
+ add(methodPattern("CharProgression"), FqnCallIntrinsic("CharProgression", "kotlin.ranges.CharProgression", isConstructor = true,
+ receiverAsArgument = false))
}
+ private fun methodPattern(builtinProgressionName: String) =
+ pattern("kotlin.ranges", builtinProgressionName, "Companion", "fromClosedRange")
}
\ No newline at end of file
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/StringOperationFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/StringOperationFIF.java
deleted file mode 100644
index e9710693284..00000000000
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/StringOperationFIF.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2010-2015 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.kotlin.js.translate.intrinsic.functions.factories;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.BuiltInFunctionIntrinsic;
-
-import static org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern;
-
-public final class StringOperationFIF extends CompositeFIF {
- @NotNull
- public static final FunctionIntrinsicFactory INSTANCE = new StringOperationFIF();
-
- private StringOperationFIF() {
- add(pattern("kotlin", "CharSequence", "get").checkOverridden(), new BuiltInFunctionIntrinsic("charAt"));
- add(pattern("kotlin", "CharSequence", "").checkOverridden(), LENGTH_PROPERTY_INTRINSIC);
- add(pattern("kotlin", "CharSequence", "subSequence").checkOverridden(), new BuiltInFunctionIntrinsic("substring"));
- }
-}
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/objects/objectsIntrinsics.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/objects/objectsIntrinsics.kt
index d19d74e21b7..1201edc0e5c 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/objects/objectsIntrinsics.kt
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/objects/objectsIntrinsics.kt
@@ -17,29 +17,37 @@
package org.jetbrains.kotlin.js.translate.intrinsic.objects
import com.google.dart.compiler.backend.js.ast.JsExpression
+import com.google.dart.compiler.backend.js.ast.JsName
import org.jetbrains.kotlin.builtins.CompanionObjectMapping
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.js.translate.context.Namer
+import org.jetbrains.kotlin.js.translate.context.StaticContext
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
-class DefaultClassObjectIntrinsic(val fqName: FqName): ObjectIntrinsic {
- override fun apply(context: TranslationContext): JsExpression {
- val nameRef = context.getQualifiedReference(fqName)
- return JsAstUtils.replaceRootReference(nameRef, Namer.kotlinObject())
+class DefaultClassObjectIntrinsic(val staticContext: StaticContext, val fqName: FqName): ObjectIntrinsic {
+ private val innerName: JsName by lazy {
+ val declaration = JsAstUtils.replaceRootReference(staticContext.getQualifiedReference(fqName), Namer.kotlinObject())
+ staticContext.importDeclaration(fqName.shortName().asString(), declaration)
}
+
+ override fun apply(context: TranslationContext) = JsAstUtils.pureFqn(innerName, null)
}
-class ObjectIntrinsics {
- fun getIntrinsic(classDescriptor: ClassDescriptor): ObjectIntrinsic {
+class ObjectIntrinsics(private val staticContext: StaticContext) {
+ private val cache = mutableMapOf()
+
+ fun getIntrinsic(classDescriptor: ClassDescriptor) = cache.getOrPut(classDescriptor) { createIntrinsic(classDescriptor) }
+
+ private fun createIntrinsic(classDescriptor: ClassDescriptor): ObjectIntrinsic {
if (!CompanionObjectMapping.isMappedIntrinsicCompanionObject(classDescriptor)) return NO_OBJECT_INTRINSIC
val containingDeclaration = classDescriptor.containingDeclaration
val name = Name.identifier(containingDeclaration.name.asString() + "CompanionObject")
- return DefaultClassObjectIntrinsic(FqName("kotlin.js.internal").child(name));
+ return DefaultClassObjectIntrinsic(staticContext, FqName("kotlin.js.internal").child(name))
}
}
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java
index 4b1b84f3971..da1d7e5959b 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java
@@ -172,24 +172,6 @@ public final class JsAstUtils {
return invokeKotlinFunction(Namer.PRIMITIVE_COMPARE_TO, left, right);
}
- @NotNull
- private static JsExpression rangeTo(@NotNull String rangeClassName, @NotNull JsExpression rangeStart, @NotNull JsExpression rangeEnd) {
- JsNameRef expr = pureFqn(rangeClassName, Namer.kotlinObject());
- JsNew numberRangeConstructorInvocation = new JsNew(expr);
- setArguments(numberRangeConstructorInvocation, rangeStart, rangeEnd);
- return numberRangeConstructorInvocation;
- }
-
- @NotNull
- public static JsExpression numberRangeTo(@NotNull JsExpression rangeStart, @NotNull JsExpression rangeEnd) {
- return rangeTo(Namer.NUMBER_RANGE, rangeStart, rangeEnd);
- }
-
- @NotNull
- public static JsExpression charRangeTo(@NotNull JsExpression rangeStart, @NotNull JsExpression rangeEnd) {
- return rangeTo(Namer.CHAR_RANGE, rangeStart, rangeEnd);
- }
-
public static JsExpression newLong(long value, @NotNull TranslationContext context) {
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
int low = (int) value;
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java
index c7b41f8116b..77932f35f7d 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java
@@ -154,7 +154,7 @@ public final class TranslationUtils {
if (!JsDescriptorUtils.isSimpleFinalProperty(descriptor) && !(containingDescriptor instanceof PackageFragmentDescriptor)) {
JsName backingFieldMangledName = context.getNameForBackingField(descriptor);
- backingFieldName = context.declarePropertyOrPropertyAccessorName(descriptor, backingFieldMangledName.getIdent(), false);
+ backingFieldName = context.declarePropertyOrPropertyAccessorName(descriptor, backingFieldMangledName.getIdent());
}
JsExpression receiver;
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt
index ff354ea8aa2..04aa876a077 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt
@@ -107,7 +107,7 @@ fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsName
fun TranslationContext.addFunctionToPrototype(classDescriptor: ClassDescriptor, descriptor: FunctionDescriptor, function: JsExpression) {
val prototypeRef = JsAstUtils.prototypeOf(getInnerReference(classDescriptor))
val functionRef = JsNameRef(getNameForDescriptor(descriptor), prototypeRef)
- addRootStatement(JsAstUtils.assignment(functionRef, function).makeStmt())
+ addDeclarationStatement(JsAstUtils.assignment(functionRef, function).makeStmt())
}
fun TranslationContext.addAccessorsToPrototype(
@@ -118,5 +118,5 @@ fun TranslationContext.addAccessorsToPrototype(
val prototypeRef = JsAstUtils.prototypeOf(getInnerReference(containingClass))
val propertyName = getNameForDescriptor(propertyDescriptor)
val defineProperty = JsAstUtils.defineProperty(prototypeRef, propertyName.ident, literal, program())
- addRootStatement(defineProperty.makeStmt())
+ addDeclarationStatement(defineProperty.makeStmt())
}
\ No newline at end of file
diff --git a/js/js.translator/testData/kotlin_lib.js b/js/js.translator/testData/kotlin_lib.js
index b9e8c4c5e8d..9e38aec4ca8 100644
--- a/js/js.translator/testData/kotlin_lib.js
+++ b/js/js.translator/testData/kotlin_lib.js
@@ -17,8 +17,6 @@
(function (Kotlin) {
"use strict";
- var CharSequence = Kotlin.createTraitNow(null);
-
// Shims for String
if (typeof String.prototype.startsWith === "undefined") {
String.prototype.startsWith = function(searchString, position) {
@@ -197,59 +195,23 @@
};
Kotlin.intUpto = function (from, to) {
- return new Kotlin.NumberRange(from, to);
+ return new Kotlin.kotlin.ranges.IntRange(from, to);
};
Kotlin.intDownto = function (from, to) {
- return new Kotlin.Progression(from, to, -1);
+ return new Kotlin.kotlin.ranges.IntProgression(from, to, -1);
};
Kotlin.Throwable = Error;
-
- function createClassNowWithMessage(base) {
- return Kotlin.createClassNow(base,
- /** @constructs */
- function (message) {
- this.message = (message !== void 0) ? message : null;
- }
- );
- }
-
- Kotlin.Error = createClassNowWithMessage(Kotlin.Throwable);
- Kotlin.Exception = createClassNowWithMessage(Kotlin.Throwable);
- Kotlin.RuntimeException = createClassNowWithMessage(Kotlin.Exception);
- Kotlin.NullPointerException = createClassNowWithMessage(Kotlin.RuntimeException);
- Kotlin.NoSuchElementException = createClassNowWithMessage(Kotlin.RuntimeException);
- Kotlin.IllegalArgumentException = createClassNowWithMessage(Kotlin.RuntimeException);
- Kotlin.IllegalStateException = createClassNowWithMessage(Kotlin.RuntimeException);
- Kotlin.UnsupportedOperationException = createClassNowWithMessage(Kotlin.RuntimeException);
- Kotlin.IndexOutOfBoundsException = createClassNowWithMessage(Kotlin.RuntimeException);
- Kotlin.ConcurrentModificationException = createClassNowWithMessage(Kotlin.RuntimeException);
- Kotlin.ClassCastException = createClassNowWithMessage(Kotlin.RuntimeException);
- Kotlin.AssertionError = createClassNowWithMessage(Kotlin.Error);
-
Kotlin.throwNPE = function (message) {
- throw new Kotlin.NullPointerException(message);
+ throw new Kotlin.kotlin.ranges.NullPointerException(message);
};
Kotlin.throwCCE = function () {
- throw new Kotlin.ClassCastException("Illegal cast");
+ throw new Kotlin.kotlin.ClassCastException("Illegal cast");
};
- function throwAbstractFunctionInvocationError(funName) {
- return function () {
- var message;
- if (funName !== void 0) {
- message = "Function " + funName + " is abstract";
- }
- else {
- message = "Function is abstract";
- }
- throw new TypeError(message);
- };
- }
-
/** @const */
var POW_2_32 = 4294967296;
// TODO: consider switching to Symbol type once we are on ES6.
@@ -273,88 +235,12 @@
return hash;
}
- var lazyInitClasses = {};
-
- /**
- * @class
- * @implements {Kotlin.Iterator.}
- *
- * @constructor
- * @param {Array.} array
- * @template T
- */
- lazyInitClasses.ArrayIterator = Kotlin.createClass(
- function () {
- return [Kotlin.kotlin.collections.MutableIterator];
- },
- /** @constructs */
- function (array) {
- this.array = array;
- this.index = 0;
- },
- /** @lends {ArrayIterator.prototype} */
- {
- next: function () {
- return this.array[this.index++];
- },
- hasNext: function () {
- return this.index < this.array.length;
- },
- remove: function () {
- if (this.index < 0 || this.index > this.array.length) throw new RangeError();
- this.index--;
- this.array.splice(this.index, 1);
- }
- });
-
- lazyInitClasses.Enum = Kotlin.createClass(
- function() {
- return [Kotlin.Comparable];
- },
- function () {
- this.name$ = void 0;
- this.ordinal$ = void 0;
- }, {
- name: {
- get: function () {
- return this.name$;
- }
- },
- ordinal: {
- get: function () {
- return this.ordinal$;
- }
- },
- equals_za3rmp$: function (o) {
- return this === o;
- },
- hashCode: function () {
- return getObjectHashCode(this);
- },
- compareTo_za3rmp$: function (o) {
- return this.ordinal$ < o.ordinal$ ? -1 : this.ordinal$ > o.ordinal$ ? 1 : 0;
- },
- toString: function () {
- return this.name;
- }
- }
- );
-
Kotlin.PropertyMetadata = Kotlin.createClassNow(null,
function (name) {
this.name = name;
}
);
-
- Kotlin.Comparable = Kotlin.createTraitNow(null, null, {
- compareTo: throwAbstractFunctionInvocationError("Comparable#compareTo")
- });
-
- Kotlin.Appendable = Kotlin.createTraitNow(null, null, {
- append: throwAbstractFunctionInvocationError("Appendable#append")
- });
-
Kotlin.safeParseInt = function (str) {
var r = parseInt(str, 10);
return isNaN(r) ? null : r;
@@ -502,306 +388,21 @@
Kotlin.out.print(s);
};
- lazyInitClasses.RangeIterator = Kotlin.createClass(
- function () {
- return [Kotlin.kotlin.collections.Iterator];
- },
- function (start, end, step) {
- this.start = start;
- this.end = end;
- this.step = step;
- this.i = start;
- }, {
- next: function () {
- var value = this.i;
- this.i = this.i + this.step;
- return value;
- },
- hasNext: function () {
- if (this.step > 0)
- return this.i <= this.end;
- else
- return this.i >= this.end;
+ Kotlin.collectionsMax = function (c, comp) {
+ if (c.isEmpty()) {
+ //TODO: which exception?
+ throw new Error();
+ }
+ var it = c.iterator();
+ var max = it.next();
+ while (it.hasNext()) {
+ var el = it.next();
+ if (comp.compare(max, el) < 0) {
+ max = el;
}
- });
-
- function isSameNotNullRanges(other) {
- var classObject = this.constructor;
- if (this instanceof classObject && other instanceof classObject) {
- return this.isEmpty() && other.isEmpty() ||
- (this.first === other.first && this.last === other.last && this.step === other.step);
}
- return false;
- }
-
- function isSameLongRanges(other) {
- var classObject = this.constructor;
- if (this instanceof classObject && other instanceof classObject) {
- return this.isEmpty() && other.isEmpty() ||
- (this.first.equals_za3rmp$(other.first) && this.last.equals_za3rmp$(other.last) && this.step.equals_za3rmp$(other.step));
- }
- return false;
- }
-
- // reference implementation in core/builtins/src/kotlin/internal/progressionUtil.kt
- function getProgressionFinalElement(start, end, step) {
- function mod(a, b) {
- var mod = a % b;
- return mod >= 0 ? mod : mod + b;
- }
- function differenceModulo(a, b, c) {
- return mod(mod(a, c) - mod(b, c), c);
- }
-
- if (step > 0) {
- return end - differenceModulo(end, start, step);
- }
- else if (step < 0) {
- return end + differenceModulo(start, end, -step);
- }
- else {
- throw new Kotlin.IllegalArgumentException('Step is zero.');
- }
- }
-
- // reference implementation in core/builtins/src/kotlin/internal/progressionUtil.kt
- function getProgressionFinalElementLong(start, end, step) {
- function mod(a, b) {
- var mod = a.modulo(b);
- return !mod.isNegative() ? mod : mod.add(b);
- }
- function differenceModulo(a, b, c) {
- return mod(mod(a, c).subtract(mod(b, c)), c);
- }
-
- var diff;
- if (step.compareTo_za3rmp$(Kotlin.Long.ZERO) > 0) {
- diff = differenceModulo(end, start, step);
- return diff.isZero() ? end : end.subtract(diff);
- }
- else if (step.compareTo_za3rmp$(Kotlin.Long.ZERO) < 0) {
- diff = differenceModulo(start, end, step.unaryMinus());
- return diff.isZero() ? end : end.add(diff);
- }
- else {
- throw new Kotlin.IllegalArgumentException('Step is zero.');
- }
- }
-
- lazyInitClasses.NumberProgression = Kotlin.createClass(
- function () {
- return [Kotlin.kotlin.collections.Iterable];
- },
- function (start, end, step) {
- this.first = start;
- this.last = getProgressionFinalElement(start, end, step);
- this.step = step;
- if (this.step === 0)
- throw new Kotlin.IllegalArgumentException('Step must be non-zero');
- }, {
- iterator: function () {
- return new Kotlin.RangeIterator(this.first, this.last, this.step);
- },
- isEmpty: function () {
- return this.step > 0 ? this.first > this.last : this.first < this.last;
- },
- hashCode: function () {
- return this.isEmpty() ? -1 : 31 * (31 * this.first + this.last) + this.step;
- },
- equals_za3rmp$: isSameNotNullRanges,
- toString: function () {
- return this.step > 0 ? this.first.toString() + '..' + this.last + ' step ' + this.step : this.first.toString() + ' downTo ' + this.last + ' step ' + -this.step;
- }
- });
-
- lazyInitClasses.NumberRange = Kotlin.createClass(
- function() {
- return [Kotlin.kotlin.ranges.ClosedRange, Kotlin.NumberProgression]
- },
- function $fun(start, endInclusive) {
- $fun.baseInitializer.call(this, start, endInclusive, 1);
- this.start = start;
- this.endInclusive = endInclusive;
- }, {
- contains_htax2k$: function (item) {
- return this.start <= item && item <= this.endInclusive;
- },
- isEmpty: function () {
- return this.start > this.endInclusive;
- },
- hashCode: function () {
- return this.isEmpty() ? -1 : 31 * this.start + this.endInclusive;
- },
- equals_za3rmp$: isSameNotNullRanges,
- toString: function () {
- return this.start.toString() + '..' + this.endInclusive;
- }
- }, {
- Companion: Kotlin.createObject(null, function () {
- this.EMPTY = new Kotlin.NumberRange(1, 0);
- })
- });
-
-
-
- lazyInitClasses.LongRangeIterator = Kotlin.createClass(
- function () {
- return [Kotlin.kotlin.collections.Iterator];
- },
- function (start, end, step) {
- this.start = start;
- this.end = end;
- this.step = step;
- this.i = start;
- }, {
- next: function () {
- var value = this.i;
- this.i = this.i.add(this.step);
- return value;
- },
- hasNext: function () {
- if (this.step.isNegative())
- return this.i.compare(this.end) >= 0;
- else
- return this.i.compare(this.end) <= 0;
- }
- });
-
- lazyInitClasses.LongProgression = Kotlin.createClass(
- function () {
- return [Kotlin.kotlin.collections.Iterable];
- },
- function (start, end, step) {
- this.first = start;
- this.last = getProgressionFinalElementLong(start, end, step);
- this.step = step;
- if (this.step.isZero())
- throw new Kotlin.IllegalArgumentException('Step must be non-zero');
- }, {
- iterator: function () {
- return new Kotlin.LongRangeIterator(this.first, this.last, this.step);
- },
- isEmpty: function() {
- return this.step.isNegative() ? this.first.compare(this.last) < 0 : this.first.compare(this.last) > 0;
- },
- hashCode: function() {
- return this.isEmpty() ? -1 : (31 * (31 * this.first.toInt() + this.last.toInt()) + this.step.toInt());
- },
- equals_za3rmp$: isSameLongRanges,
- toString: function () {
- return !this.step.isNegative() ? this.first.toString() + '..' + this.last + ' step ' + this.step : this.first.toString() + ' downTo ' + this.last + ' step ' + this.step.unaryMinus();
- }
- });
-
- lazyInitClasses.LongRange = Kotlin.createClass(
- function () {
- return [Kotlin.kotlin.ranges.ClosedRange, Kotlin.LongProgression];
- },
- function $fun(start, endInclusive) {
- $fun.baseInitializer.call(this, start, endInclusive, Kotlin.Long.ONE);
- this.start = start;
- this.endInclusive = endInclusive;
- }, {
- contains_htax2k$: function (item) {
- return this.start.compareTo_za3rmp$(item) <= 0 && item.compareTo_za3rmp$(this.endInclusive) <= 0;
- },
- isEmpty: function () {
- return this.start.compare(this.endInclusive) > 0;
- },
- hashCode: function() {
- return this.isEmpty() ? -1 : (31 * this.start.toInt() + this.endInclusive.toInt());
- },
- equals_za3rmp$: isSameLongRanges,
- toString: function () {
- return this.start.toString() + '..' + this.endInclusive;
- }
- }, {
- Companion: Kotlin.createObject(null, function () {
- this.EMPTY = new Kotlin.LongRange(Kotlin.Long.ONE, Kotlin.Long.ZERO);
- })
- });
-
-
-
- lazyInitClasses.CharRangeIterator = Kotlin.createClass(
- function () {
- return [Kotlin.RangeIterator];
- },
- function (start, end, step) {
- Kotlin.RangeIterator.call(this, start, end, step);
- }, {
- next: function () {
- var value = this.i;
- this.i = this.i + this.step;
- return String.fromCharCode(value);
- }
- });
-
- lazyInitClasses.CharProgression = Kotlin.createClassNow(
- function () {
- return [Kotlin.kotlin.collections.Iterable];
- },
- function (start, end, step) {
- this.first = start;
- this.startCode = start.charCodeAt(0);
- this.endCode = getProgressionFinalElement(this.startCode, end.charCodeAt(0), step);
- this.last = String.fromCharCode(this.endCode);
- this.step = step;
- if (this.step === 0)
- throw new Kotlin.IllegalArgumentException('Increment must be non-zero');
- }, {
- iterator: function () {
- return new Kotlin.CharRangeIterator(this.startCode, this.endCode, this.step);
- },
- isEmpty: function() {
- return this.step > 0 ? this.startCode > this.endCode : this.startCode < this.endCode;
- },
- hashCode: function() {
- return this.isEmpty() ? -1 : (31 * (31 * this.startCode|0 + this.endCode|0) + this.step|0);
- },
- equals_za3rmp$: isSameNotNullRanges,
- toString: function () {
- return this.step > 0 ? this.first.toString() + '..' + this.last + ' step ' + this.step : this.first.toString() + ' downTo ' + this.last + ' step ' + -this.step;
- }
- });
-
-
- lazyInitClasses.CharRange = Kotlin.createClass(
- function() {
- return [Kotlin.kotlin.ranges.ClosedRange, Kotlin.CharProgression]
- },
- function $fun(start, endInclusive) {
- $fun.baseInitializer.call(this, start, endInclusive, 1);
- this.start = start;
- this.endInclusive = endInclusive;
- }, {
- contains_htax2k$: function (item) {
- return this.start <= item && item <= this.endInclusive;
- },
- isEmpty: function () {
- return this.start > this.endInclusive;
- },
- hashCode: function() {
- return this.isEmpty() ? -1 : (31 * this.startCode|0 + this.endCode|0);
- },
- equals_za3rmp$: isSameNotNullRanges,
- toString: function () {
- return this.start.toString() + '..' + this.endInclusive;
- }
- }, {
- Companion: Kotlin.createObject(null, function () {
- this.EMPTY = new Kotlin.CharRange(Kotlin.toChar(1), Kotlin.toChar(0));
- })
- });
-
-
- /**
- * @interface
- * @template T
- */
- Kotlin.Comparator = Kotlin.createClassNow(null, null, {
- compare: throwAbstractFunctionInvocationError("Comparator#compare")
- });
+ return max;
+ };
Kotlin.collectionsSort = function (mutableList, comparator) {
var boundComparator = void 0;
@@ -839,42 +440,6 @@
return array;
};
-
- Kotlin.StringBuilder = Kotlin.createClassNow([CharSequence],
- function (content) {
- this.string = typeof(content) == "string" ? content : "";
- }, {
- length: {
- get: function() {
- return this.string.length;
- }
- },
- substring: function(start, end) {
- return this.string.substring(start, end);
- },
- charAt: function(index) {
- return this.string.charAt(index);
- },
- append: function (obj, from, to) {
- if (from == void 0 && to == void 0) {
- this.string = this.string + obj.toString();
- } else if (to == void 0) {
- this.string = this.string + obj.toString().substring(from);
- } else {
- this.string = this.string + obj.toString().substring(from, to);
- }
-
- return this;
- },
- reverse: function () {
- this.string = this.string.split("").reverse().join("");
- return this;
- },
- toString: function () {
- return this.string;
- }
- });
-
Kotlin.splitString = function (str, regex, limit) {
return str.split(new RegExp(regex), limit);
};
@@ -920,10 +485,6 @@
return result;
};
- Kotlin.arrayIterator = function (array) {
- return new Kotlin.ArrayIterator(array);
- };
-
Kotlin.deleteProperty = function (object, property) {
delete object[property];
};
@@ -936,7 +497,5 @@
}
return obj1;
};
-
- Kotlin.createDefinition(lazyInitClasses, Kotlin);
})(Kotlin);
diff --git a/js/js.translator/testData/kotlin_lib_ecma5.js b/js/js.translator/testData/kotlin_lib_ecma5.js
index 843a27e2276..f7ba2ef3318 100644
--- a/js/js.translator/testData/kotlin_lib_ecma5.js
+++ b/js/js.translator/testData/kotlin_lib_ecma5.js
@@ -343,17 +343,41 @@
};
Kotlin.callGetter = function (thisObject, klass, propertyName) {
- return klass.$metadata$.properties[propertyName].get.call(thisObject);
+ var propertyDescriptor = Object.getOwnPropertyDescriptor(klass, propertyName);
+ if (propertyDescriptor != null) {
+ if (propertyDescriptor.get != null) {
+ return propertyDescriptor.get.call(thisObject);
+ }
+ else if ("value" in propertyDescriptor) {
+ return propertyDescriptor.value;
+ }
+ }
+ else {
+ return Kotlin.callGetter(thisObject, Object.getPrototypeOf(klass), propertyName);
+ }
+ return null;
};
Kotlin.callSetter = function (thisObject, klass, propertyName, value) {
- klass.$metadata$.properties[propertyName].set.call(thisObject, value);
+ var propertyDescriptor = Object.getOwnPropertyDescriptor(klass, propertyName);
+ if (propertyDescriptor != null) {
+ if (propertyDescriptor.set != null) {
+ propertyDescriptor.set.call(thisObject, value);
+ }
+ else if ("value" in propertyDescriptor) {
+ propertyDescriptor.value = value;
+ }
+ }
+ else {
+ return Kotlin.callSetter(thisObject, Object.getPrototypeOf(klass), propertyName, value);
+ }
};
function isInheritanceFromTrait(metadata, trait) {
- if (metadata == null || metadata.classIndex < trait.$metadata$.classIndex) {
+ // TODO: return this optimization
+ /*if (metadata == null || metadata.classIndex < trait.$metadata$.classIndex) {
return false;
- }
+ }*/
var baseClasses = metadata.baseClasses;
var i;
for (i = 0; i < baseClasses.length; i++) {
@@ -380,8 +404,8 @@
return false;
}
- if (typeof klass === "function") {
- return object instanceof klass;
+ if (typeof klass === "function" && object instanceof klass) {
+ return true;
}
var proto = Object.getPrototypeOf(klass);
@@ -399,7 +423,10 @@
}
if (object.constructor != null) {
- return isInheritanceFromTrait(object.constructor.$metadata$, klass);
+ metadata = object.constructor.$metadata$;
+ if (metadata != null) {
+ return isInheritanceFromTrait(metadata, klass);
+ }
}
return false;
diff --git a/js/js.translator/testData/long.js b/js/js.translator/testData/long.js
index d38adbd3d4f..5baaacbac5f 100644
--- a/js/js.translator/testData/long.js
+++ b/js/js.translator/testData/long.js
@@ -839,6 +839,6 @@
Kotlin.Long.prototype.inv = Kotlin.Long.prototype.not;
Kotlin.Long.prototype.rangeTo = function (other) {
- return new Kotlin.LongRange(this, other);
+ return new Kotlin.kotlin.ranges.LongRange(this, other);
};
}(Kotlin));
\ No newline at end of file
diff --git a/js/js.translator/testData/merge-builtins.js b/js/js.translator/testData/merge-builtins.js
new file mode 100644
index 00000000000..5e1428d8a65
--- /dev/null
+++ b/js/js.translator/testData/merge-builtins.js
@@ -0,0 +1,12 @@
+var require = (function () {
+ var builtins = module.exports.kotlin;
+ var propertyNames = Object.getOwnPropertyNames(builtins);
+ Kotlin.kotlin = Kotlin.kotlin || {};
+ for (var i = 0; i < propertyNames.length; ++i) {
+ var propertyName = propertyNames[i];
+ Kotlin.kotlin[propertyName] = builtins[propertyName];
+ }
+ return function() {
+ return Kotlin;
+ }
+})();
\ No newline at end of file
diff --git a/js/js.translator/testData/merge.js b/js/js.translator/testData/merge.js
index 91039d5ac8d..d41e5821a92 100644
--- a/js/js.translator/testData/merge.js
+++ b/js/js.translator/testData/merge.js
@@ -1,6 +1,16 @@
(function () {
var stdlib = module.exports;
- Object.getOwnPropertyNames(stdlib).forEach(function(propertyName) {
- Kotlin[propertyName] = stdlib[propertyName];
- });
+ function copyProperties(from, to) {
+ var propertyNames = Object.getOwnPropertyNames(from);
+ for (var i = 0; i < propertyNames.length; ++i) {
+ var propertyName = propertyNames[i];
+ if (propertyName in to) {
+ copyProperties(from[propertyName], to[propertyName]);
+ }
+ else {
+ to[propertyName] = from[propertyName];
+ }
+ }
+ }
+ copyProperties(stdlib, Kotlin);
})();
diff --git a/jslib_files.xml b/jslib_files.xml
index 744a26fa76e..761cd607b8c 100644
--- a/jslib_files.xml
+++ b/jslib_files.xml
@@ -2,18 +2,24 @@
+
+
+
+
+
+
@@ -30,4 +36,13 @@
+
+
+
+
+
+
+
+
+