JS: rewrite stdlib to compile with new flat structure

This commit is contained in:
Alexey Andreev
2016-10-14 15:34:16 +03:00
parent f9a392fdec
commit e13d34e08d
38 changed files with 588 additions and 1016 deletions
+16
View File
@@ -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
+34
View File
@@ -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
@@ -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'
+33
View File
@@ -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)
}
}
}
+13 -26
View File
@@ -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() {}
+44 -19
View File
@@ -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
}
+3 -4
View File
@@ -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>();
@@ -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;
}
}
@@ -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(
@@ -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()))
}
@@ -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;
}
};
}
}
@@ -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
@@ -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(
@@ -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);
@@ -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())
}
}
}
@@ -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
}
@@ -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),
@@ -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() {
@@ -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")
}
@@ -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"));
}
}
@@ -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
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -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
View File
@@ -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;
}
})();
+13 -3
View File
@@ -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);
})();
+15
View File
@@ -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>