JS: rewrite stdlib to compile with new flat structure
This commit is contained in:
@@ -366,6 +366,14 @@
|
||||
<file name="long.js"/>
|
||||
</sources>
|
||||
|
||||
<sources dir="${js.stdlib.output.dir}">
|
||||
<file name="builtins.js"/>
|
||||
</sources>
|
||||
|
||||
<sources dir="${stdlib.js.dir}">
|
||||
<file name="merge-builtins.js"/>
|
||||
</sources>
|
||||
|
||||
<sources dir="${js.stdlib.output.dir}">
|
||||
<file name="${compiled.stdlib.js}"/>
|
||||
</sources>
|
||||
@@ -384,6 +392,13 @@
|
||||
<property environment="env"/>
|
||||
<kotlin-pp src="libraries/stdlib/src" output="${intermediate-sources}/stdlib/js" profile="JS" />
|
||||
|
||||
<new-kotlin2js output="${js.stdlib.output.dir}/tmp-builtins/kotlin.js">
|
||||
<src>
|
||||
<union>
|
||||
<resources refid="kotlin.builtin.native.files"/>
|
||||
</union>
|
||||
</src>
|
||||
</new-kotlin2js>
|
||||
<new-kotlin2js output="${js.stdlib.output.dir}/tmp/kotlin.js">
|
||||
<src>
|
||||
<union>
|
||||
@@ -392,6 +407,7 @@
|
||||
</union>
|
||||
</src>
|
||||
</new-kotlin2js>
|
||||
<move file="${js.stdlib.output.dir}/tmp-builtins/kotlin.js" tofile="${js.stdlib.output.dir}/builtins.js" />
|
||||
<move file="${js.stdlib.output.dir}/tmp/kotlin.js" tofile="${js.stdlib.output.dir}/${compiled.stdlib.js}" />
|
||||
<move file="${js.stdlib.output.dir}/tmp/kotlin" todir="${js.stdlib.output.dir}" />
|
||||
<move file="${js.stdlib.output.dir}/tmp/${compiled.stdlib.meta.js}" tofile="${js.stdlib.output.dir}/${compiled.stdlib.meta.js}" />
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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<T : Enum<T>> : Comparable<Enum<T>> {
|
||||
@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<T>) = ordinal.compareTo(other.ordinal)
|
||||
|
||||
override fun toString() = name
|
||||
}
|
||||
|
||||
interface Annotation
|
||||
+8
-8
@@ -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'
|
||||
@@ -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<dynamic> {
|
||||
return object : MutableIterator<dynamic> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
package java.util
|
||||
|
||||
@library
|
||||
public interface Comparator<T> {
|
||||
public fun compare(a: T, b: T): Int
|
||||
interface Comparator<T> {
|
||||
@JsName("compare") fun compare(a: T, b: T): Int
|
||||
}
|
||||
|
||||
public inline fun <T> Comparator(crossinline comparison: (T, T) -> Int): Comparator<T> = object : Comparator<T> {
|
||||
inline fun <T> Comparator(crossinline comparison: (T, T) -> Int): Comparator<T> = object : Comparator<T> {
|
||||
override fun compare(a: T, b: T): Int = comparison(a, b)
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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, "<init>", 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<FqNameUnsafe, JsName> standardObjects = Maps.newHashMap();
|
||||
|
||||
@NotNull
|
||||
private final Map<FqNameUnsafe, JsObjectScope> scopeMap = Maps.newHashMap();
|
||||
|
||||
private StandardClasses(@NotNull JsObjectScope kotlinScope) {
|
||||
this.kotlinScope = kotlinScope;
|
||||
}
|
||||
|
||||
private void declareTopLevelObjectInScope(@NotNull JsObjectScope scope, @NotNull Map<FqNameUnsafe, JsName> 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();
|
||||
}
|
||||
}
|
||||
@@ -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<JsStatement> declarationStatements = new ArrayList<JsStatement>();
|
||||
|
||||
@NotNull
|
||||
private final List<JsStatement> topLevelStatements = new ArrayList<JsStatement>();
|
||||
|
||||
@NotNull
|
||||
private final List<JsStatement> importStatements = new ArrayList<JsStatement>();
|
||||
|
||||
@@ -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<JsName> partNames;
|
||||
if (standardClasses.isStandardObject(suggested.getDescriptor())) {
|
||||
List<JsName> 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<JsName> {
|
||||
public InnerNameGenerator() {
|
||||
addRule(new Rule<JsName>() {
|
||||
@@ -643,12 +646,13 @@ public final class StaticContext {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JsStatement> getDeclarationStatements() {
|
||||
return declarationStatements;
|
||||
public List<JsStatement> getTopLevelStatements() {
|
||||
return topLevelStatements;
|
||||
}
|
||||
|
||||
public void addRootStatement(@NotNull JsStatement statement) {
|
||||
declarationStatements.add(statement);
|
||||
@NotNull
|
||||
public List<JsStatement> 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<String, ExportedPackage> subpackages = new HashMap<String, ExportedPackage>();
|
||||
|
||||
+30
-11
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+64
-57
@@ -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<ConstructorInfo>
|
||||
@@ -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<JsStatement>) {
|
||||
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(
|
||||
|
||||
+3
-3
@@ -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()))
|
||||
}
|
||||
|
||||
|
||||
-99
@@ -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<JsPropertyInitializer> getMembers() {
|
||||
return membersObjectLiteral.getPropertyInitializers();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JsExpression> asList() {
|
||||
return new AbstractList<JsExpression>() { // 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+6
-3
@@ -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
|
||||
|
||||
+2
-2
@@ -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 }
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+49
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -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<TranslationContext, JsName>()
|
||||
|
||||
override fun apply(receiver: JsExpression?, arguments: MutableList<JsExpression>, 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
|
||||
}
|
||||
-1
@@ -60,7 +60,6 @@ object LongOperationFIF : FunctionIntrinsicFactory {
|
||||
private val floatBinaryIntrinsics: Map<String, BaseBinaryIntrinsic> =
|
||||
mapOf(
|
||||
"compareTo" to BaseBinaryIntrinsic(::primitiveCompareTo),
|
||||
"rangeTo" to BaseBinaryIntrinsic(::numberRangeTo),
|
||||
"plus" to BaseBinaryIntrinsic(::sum),
|
||||
"minus" to BaseBinaryIntrinsic(::subtract),
|
||||
"times" to BaseBinaryIntrinsic(::mul),
|
||||
|
||||
+4
-16
@@ -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() {
|
||||
|
||||
+10
-11
@@ -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<JsExpression>, 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")
|
||||
}
|
||||
-33
@@ -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", "<get-length>").checkOverridden(), LENGTH_PROPERTY_INTRINSIC);
|
||||
add(pattern("kotlin", "CharSequence", "subSequence").checkOverridden(), new BuiltInFunctionIntrinsic("substring"));
|
||||
}
|
||||
}
|
||||
+15
-7
@@ -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<ClassDescriptor, ObjectIntrinsic>()
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
+17
-458
@@ -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.<T>}
|
||||
*
|
||||
* @constructor
|
||||
* @param {Array.<T>} 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);
|
||||
|
||||
|
||||
+34
-7
@@ -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;
|
||||
|
||||
Vendored
+1
-1
@@ -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));
|
||||
+12
@@ -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;
|
||||
}
|
||||
})();
|
||||
Vendored
+13
-3
@@ -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);
|
||||
})();
|
||||
|
||||
@@ -2,18 +2,24 @@
|
||||
<fileset id="kotlin.builtin.files" dir="${basedir}/core/builtins">
|
||||
<include name="native/kotlin/Iterator.kt"/>
|
||||
<include name="native/kotlin/Collections.kt"/>
|
||||
<include name="native/kotlin/CharSequence.kt"/>
|
||||
<include name="src/kotlin/annotation/Annotations.kt"/>
|
||||
<include name="src/kotlin/Function.kt"/>
|
||||
<include name="src/kotlin/Iterators.kt"/>
|
||||
<include name="src/kotlin/Range.kt"/>
|
||||
<include name="src/kotlin/Progressions.kt"/>
|
||||
<include name="src/kotlin/ProgressionIterators.kt"/>
|
||||
<include name="src/kotlin/Ranges.kt"/>
|
||||
<include name="src/kotlin/FloatingPointConstants.kt"/>
|
||||
<include name="src/kotlin/IntegerConstants.kt"/>
|
||||
<include name="src/kotlin/internal/InternalAnnotations.kt"/>
|
||||
<include name="src/kotlin/internal/progressionUtil.kt"/>
|
||||
</fileset>
|
||||
|
||||
<union id="js.lib.files">
|
||||
<fileset dir="${basedir}/js/js.libraries/src">
|
||||
<include name="**/*.kt" />
|
||||
<exclude name="builtins/**/*.kt"/>
|
||||
</fileset>
|
||||
|
||||
<fileset dir="${basedir}/core/builtins/src">
|
||||
@@ -30,4 +36,13 @@
|
||||
<include name="**/*.kt" />
|
||||
</fileset>
|
||||
</union>
|
||||
|
||||
<union id="kotlin.builtin.native.files">
|
||||
<fileset dir="${basedir}/core/builtins">
|
||||
<include name="native/kotlin/Comparable.kt"/>
|
||||
</fileset>
|
||||
<fileset dir="${basedir}/js/js.libraries/src/builtins">
|
||||
<include name="**/*.kt" />
|
||||
</fileset>
|
||||
</union>
|
||||
</project>
|
||||
|
||||
Reference in New Issue
Block a user