diff --git a/js/js.libraries/src/js/arrayUtils.js b/js/js.libraries/src/js/arrayUtils.js new file mode 100644 index 00000000000..e1563877040 --- /dev/null +++ b/js/js.libraries/src/js/arrayUtils.js @@ -0,0 +1,91 @@ +/* + * 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. + */ + +Kotlin.arrayToString = function (a) { + return "[" + a.map(Kotlin.toString).join(", ") + "]"; +}; + +Kotlin.arrayDeepToString = function (a, visited) { + visited = visited || [a]; + return "[" + a.map(function(e) { + if (Array.isArray(e) && visited.indexOf(e) < 0) { + visited.push(e); + var result = Kotlin.arrayDeepToString(e, visited); + visited.pop(); + return result; + } + else { + return Kotlin.toString(e); + } + }).join(", ") + "]"; +}; + +Kotlin.arrayEquals = function (a, b) { + if (a === b) { + return true; + } + if (!Array.isArray(b) || a.length !== b.length) { + return false; + } + + for (var i = 0, n = a.length; i < n; i++) { + if (!Kotlin.equals(a[i], b[i])) { + return false; + } + } + return true; +}; + +Kotlin.arrayDeepEquals = function (a, b) { + if (a === b) { + return true; + } + if (!Array.isArray(b) || a.length !== b.length) { + return false; + } + + for (var i = 0, n = a.length; i < n; i++) { + if (Array.isArray(a[i])) { + if (!Kotlin.arrayDeepEquals(a[i], b[i])) { + return false; + } + } else if (!Kotlin.equals(a[i], b[i])) { + return false; + } + } + return true; +}; + +Kotlin.arrayHashCode = function (arr) { + var result = 1; + for (var i = 0, n = arr.length; i < n; i++) { + result = ((31 * result | 0) + Kotlin.hashCode(arr[i])) | 0; + } + return result; +}; + +Kotlin.arrayDeepHashCode = function (arr) { + var result = 1; + for (var i = 0, n = arr.length; i < n; i++) { + var e = arr[i]; + result = ((31 * result | 0) + (Array.isArray(e) ? Kotlin.arrayDeepHashCode(e) : Kotlin.hashCode(e))) | 0; + } + return result; +}; + +Kotlin.primitiveArraySort = function(array) { + array.sort(Kotlin.primitiveCompareTo) +}; diff --git a/js/js.libraries/src/js/callableReferenceUtils.js b/js/js.libraries/src/js/callableReferenceUtils.js new file mode 100644 index 00000000000..0c9ffe3137c --- /dev/null +++ b/js/js.libraries/src/js/callableReferenceUtils.js @@ -0,0 +1,144 @@ +/* + * Copyright 2010-2014 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. + */ + +// TODO Store callable references for members in class +Kotlin.getCallableRefForMemberFunction = function (memberName) { + return function () { + var args = [].slice.call(arguments); + var instance = args.shift(); + return instance[memberName].apply(instance, args); + }; +}; + +Kotlin.getBoundCallableRefForMemberFunction = function (receiver, memberName) { + return function () { + return receiver[memberName].apply(receiver, arguments); + }; +}; + +// TODO Store callable references for extension functions in class +// extFun expected receiver as the first argument +Kotlin.getCallableRefForExtensionFunction = function (extFun) { + return function () { + return extFun.apply(null, arguments); + }; +}; + +Kotlin.getBoundCallableRefForExtensionFunction = function (receiver, extFun) { + return function () { + var args = [].slice.call(arguments); + args.unshift(receiver); + return extFun.apply(null, args); + }; +}; + +Kotlin.getCallableRefForLocalExtensionFunction = function (extFun) { + return function () { + var args = [].slice.call(arguments); + var instance = args.shift(); + return extFun.apply(instance, args); + }; +}; + +Kotlin.getBoundCallableRefForLocalExtensionFunction = function (receiver, extFun) { + return function () { + return extFun.apply(receiver, arguments); + }; +}; + +Kotlin.getCallableRefForConstructor = function (klass) { + return function () { + var obj = Object.create(klass.prototype); + klass.apply(obj, arguments); + return obj; + }; +}; + +Kotlin.getCallableRefForTopLevelProperty = function(getter, setter, name) { + var getFun = Function("getter", "return function " + name + "() { return getter(); }")(getter, setter); + return getPropertyRefClass(getFun, "get", setter, "set_za3rmp$", propertyRefClassMetadataCache.zeroArg); +}; + +Kotlin.getCallableRefForMemberProperty = function(name, isVar) { + var getFun = Function("return function " + name + "(receiver) { return receiver['" + name + "']; }")(); + var setFun = isVar ? function(receiver, value) { receiver[name] = value; } : null; + return getPropertyRefClass(getFun, "get_za3rmp$", setFun, "set_wn2jw4$", propertyRefClassMetadataCache.oneArg); +}; + +Kotlin.getBoundCallableRefForMemberProperty = function(receiver, name, isVar) { + var getFun = Function("receiver", "return function " + name + "() { return receiver['" + name + "']; }")(receiver); + var setFun = isVar ? function(value) { receiver[name] = value; } : null; + return getPropertyRefClass(getFun, "get", setFun, "set_za3rmp$", propertyRefClassMetadataCache.oneArg); +}; + +Kotlin.getCallableRefForExtensionProperty = function(name, getFun, setFun) { + var getFunWrapper = Function("getFun", "return function " + name + "(receiver, extensionReceiver) { return getFun(receiver, extensionReceiver) }")(getFun); + return getPropertyRefClass(getFunWrapper, "get_za3rmp$", setFun, "set_wn2jw4$", propertyRefClassMetadataCache.oneArg); +}; + +Kotlin.getBoundCallableRefForExtensionProperty = function(receiver, name, getFun, setFun) { + var getFunWrapper = Function("receiver", "getFun", "return function " + name + "(extensionReceiver) { return getFun(receiver, extensionReceiver) }")(receiver, getFun); + if (setFun) { + setFun = setFun.bind(null, receiver); + } + return getPropertyRefClass(getFunWrapper, "get", setFun, "set_za3rmp$", propertyRefClassMetadataCache.oneArg); +}; + +function getPropertyRefClass(getFun, getName, setFun, setName, cache) { + var obj = getFun; + var isMutable = typeof setFun === "function"; + obj.$metadata$ = getPropertyRefMetadata(isMutable ? cache.mutable : cache.immutable); + obj[getName] = getFun; + if (isMutable) { + obj[setName] = setFun; + } + obj.constructor = obj; + return obj; +} + +var propertyRefClassMetadataCache = { + zeroArg: { + mutable: { value: null, implementedInterface: function () { + return Kotlin.kotlin.reflect.KMutableProperty0 } + }, + immutable: { value: null, implementedInterface: function () { + return Kotlin.kotlin.reflect.KProperty0 } + } + }, + oneArg: { + mutable: { value: null, implementedInterface: function () { + return Kotlin.kotlin.reflect.KMutableProperty1 } + }, + immutable: { value: null, implementedInterface: function () { + return Kotlin.kotlin.reflect.KProperty1 } + } + } +}; + +function getPropertyRefMetadata(cache) { + if (cache.value === null) { + cache.value = { + baseClasses: [cache.implementedInterface()], + baseClass: null, + classIndex: Kotlin.newClassIndex(), + functions: {}, + properties: {}, + types: {}, + staticMembers: {} + }; + } + return cache.value; +} diff --git a/js/js.libraries/src/js/conversions.js b/js/js.libraries/src/js/conversions.js new file mode 100644 index 00000000000..1c5e0a6627a --- /dev/null +++ b/js/js.libraries/src/js/conversions.js @@ -0,0 +1,51 @@ +/* + * 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. + */ + +Kotlin.toShort = function (a) { + return (a & 0xFFFF) << 16 >> 16; +}; + +Kotlin.toByte = function (a) { + return (a & 0xFF) << 24 >> 24; +}; + +Kotlin.toChar = function (a) { + return String.fromCharCode((((a | 0) % 65536) & 0xFFFF) << 16 >>> 16); +}; + +Kotlin.numberToLong = function (a) { + return a instanceof Kotlin.Long ? a : Kotlin.Long.fromNumber(a); +}; + +Kotlin.numberToInt = function (a) { + return a instanceof Kotlin.Long ? a.toInt() : (a | 0); +}; + +Kotlin.numberToShort = function (a) { + return Kotlin.toShort(Kotlin.numberToInt(a)); +}; + +Kotlin.numberToByte = function (a) { + return Kotlin.toByte(Kotlin.numberToInt(a)); +}; + +Kotlin.numberToDouble = function (a) { + return +a; +}; + +Kotlin.numberToChar = function (a) { + return Kotlin.toChar(Kotlin.numberToInt(a)); +}; \ No newline at end of file diff --git a/js/js.libraries/src/js/core.js b/js/js.libraries/src/js/core.js new file mode 100644 index 00000000000..f52bf610c3e --- /dev/null +++ b/js/js.libraries/src/js/core.js @@ -0,0 +1,89 @@ +/* + * 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. + */ + +Kotlin.equals = function (obj1, obj2) { + if (obj1 == null) { + return obj2 == null; + } + + if (obj2 == null) { + return false; + } + + if (typeof obj1 == "object" && typeof obj1.equals === "function") { + return obj1.equals(obj2); + } + + return obj1 === obj2; +}; + +Kotlin.hashCode = function (obj) { + if (obj == null) { + return 0; + } + if ("function" == typeof obj.hashCode) { + return obj.hashCode(); + } + var objType = typeof obj; + if ("object" == objType || "function" == objType) { + return getObjectHashCode(obj); + } else if ("number" == objType) { + // TODO: a more elaborate code is needed for floating point values. + return obj | 0; + } if ("boolean" == objType) { + return Number(obj) + } + + var str = String(obj); + return getStringHashCode(str); +}; + +Kotlin.toString = function (o) { + if (o == null) { + return "null"; + } + else if (Array.isArray(o)) { + return "[...]"; + } + else { + return o.toString(); + } +}; + +/** @const */ +var POW_2_32 = 4294967296; +// TODO: consider switching to Symbol type once we are on ES6. +/** @const */ +var OBJECT_HASH_CODE_PROPERTY_NAME = "kotlinHashCodeValue$"; + +function getObjectHashCode(obj) { + if (!(OBJECT_HASH_CODE_PROPERTY_NAME in obj)) { + var hash = (Math.random() * POW_2_32) | 0; // Make 32-bit singed integer. + Object.defineProperty(obj, OBJECT_HASH_CODE_PROPERTY_NAME, { value: hash, enumerable: false }); + } + return obj[OBJECT_HASH_CODE_PROPERTY_NAME]; +} + +function getStringHashCode(str) { + var hash = 0; + for (var i = 0; i < str.length; i++) { + var code = str.charCodeAt(i); + hash = (hash * 31 + code) | 0; // Keep it 32-bit. + } + return hash; +} + +Kotlin.identityHashCode = getObjectHashCode; diff --git a/js/js.libraries/src/js/externs.js b/js/js.libraries/src/js/externs.js index 6374e17e882..38d607bc7ab 100644 --- a/js/js.libraries/src/js/externs.js +++ b/js/js.libraries/src/js/externs.js @@ -1,5 +1,5 @@ /* - * Copyright 2010-2014 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. diff --git a/js/js.libraries/src/js/kotlin_lib.js b/js/js.libraries/src/js/kotlin_lib.js deleted file mode 100644 index 1a6c8515a18..00000000000 --- a/js/js.libraries/src/js/kotlin_lib.js +++ /dev/null @@ -1,252 +0,0 @@ -/** - * Copyright 2010 Tim Down. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Kotlin stdlib - -Kotlin.equals = function (obj1, obj2) { - if (obj1 == null) { - return obj2 == null; - } - - if (obj2 == null) { - return false; - } - - if (typeof obj1 == "object" && typeof obj1.equals === "function") { - return obj1.equals(obj2); - } - - return obj1 === obj2; -}; - -Kotlin.hashCode = function (obj) { - if (obj == null) { - return 0; - } - if ("function" == typeof obj.hashCode) { - return obj.hashCode(); - } - var objType = typeof obj; - if ("object" == objType || "function" == objType) { - return getObjectHashCode(obj); - } else if ("number" == objType) { - // TODO: a more elaborate code is needed for floating point values. - return obj | 0; - } if ("boolean" == objType) { - return Number(obj) - } - - var str = String(obj); - return getStringHashCode(str); -}; - -Kotlin.toString = function (o) { - if (o == null) { - return "null"; - } - else if (Array.isArray(o)) { - return "[...]"; - } - else { - return o.toString(); - } -}; - -Kotlin.arrayToString = function (a) { - return "[" + a.map(Kotlin.toString).join(", ") + "]"; -}; - -Kotlin.arrayDeepToString = function (a, visited) { - visited = visited || [a]; - return "[" + a.map(function(e) { - if (Array.isArray(e) && visited.indexOf(e) < 0) { - visited.push(e); - var result = Kotlin.arrayDeepToString(e, visited); - visited.pop(); - return result; - } - else { - return Kotlin.toString(e); - } - }).join(", ") + "]"; -}; - -Kotlin.compareTo = function (a, b) { - var typeA = typeof a; - var typeB = typeof a; - if (Kotlin.isChar(a) && typeB == "number") { - return Kotlin.primitiveCompareTo(a.charCodeAt(0), b); - } - if (typeA == "number" && Kotlin.isChar(b)) { - return Kotlin.primitiveCompareTo(a, b.charCodeAt(0)); - } - if (typeA == "number" || typeA == "string") { - return a < b ? -1 : a > b ? 1 : 0; - } - return a.compareTo_za3rmp$(b); -}; - -Kotlin.primitiveCompareTo = function (a, b) { - return a < b ? -1 : a > b ? 1 : 0; -}; - -Kotlin.isNumber = function (a) { - return typeof a == "number" || a instanceof Kotlin.Long; -}; - -Kotlin.isChar = function (value) { - return (typeof value) == "string" && value.length == 1; -}; - -Kotlin.isComparable = function (value) { - var type = typeof value; - - return type === "string" || - type === "boolean" || - Kotlin.isNumber(value) || - Kotlin.isType(value, Kotlin.kotlin.Comparable); -}; - -Kotlin.isCharSequence = function (value) { - return typeof value === "string" || Kotlin.isType(value, Kotlin.kotlin.CharSequence); -}; - -Kotlin.charInc = function (value) { - return String.fromCharCode(value.charCodeAt(0)+1); -}; - -Kotlin.charDec = function (value) { - return String.fromCharCode(value.charCodeAt(0)-1); -}; - -Kotlin.toShort = function (a) { - return (a & 0xFFFF) << 16 >> 16; -}; - -Kotlin.toByte = function (a) { - return (a & 0xFF) << 24 >> 24; -}; - -Kotlin.toChar = function (a) { - return String.fromCharCode((((a | 0) % 65536) & 0xFFFF) << 16 >>> 16); -}; - -Kotlin.numberToLong = function (a) { - return a instanceof Kotlin.Long ? a : Kotlin.Long.fromNumber(a); -}; - -Kotlin.numberToInt = function (a) { - return a instanceof Kotlin.Long ? a.toInt() : (a | 0); -}; - -Kotlin.numberToShort = function (a) { - return Kotlin.toShort(Kotlin.numberToInt(a)); -}; - -Kotlin.numberToByte = function (a) { - return Kotlin.toByte(Kotlin.numberToInt(a)); -}; - -Kotlin.numberToDouble = function (a) { - return +a; -}; - -Kotlin.numberToChar = function (a) { - return Kotlin.toChar(Kotlin.numberToInt(a)); -}; - -/** @const */ -var POW_2_32 = 4294967296; -// TODO: consider switching to Symbol type once we are on ES6. -/** @const */ -var OBJECT_HASH_CODE_PROPERTY_NAME = "kotlinHashCodeValue$"; - -function getObjectHashCode(obj) { - if (!(OBJECT_HASH_CODE_PROPERTY_NAME in obj)) { - var hash = (Math.random() * POW_2_32) | 0; // Make 32-bit singed integer. - Object.defineProperty(obj, OBJECT_HASH_CODE_PROPERTY_NAME, { value: hash, enumerable: false }); - } - return obj[OBJECT_HASH_CODE_PROPERTY_NAME]; -} - -function getStringHashCode(str) { - var hash = 0; - for (var i = 0; i < str.length; i++) { - var code = str.charCodeAt(i); - hash = (hash * 31 + code) | 0; // Keep it 32-bit. - } - return hash; -} - -Kotlin.arrayEquals = function (a, b) { - if (a === b) { - return true; - } - if (!Array.isArray(b) || a.length !== b.length) { - return false; - } - - for (var i = 0, n = a.length; i < n; i++) { - if (!Kotlin.equals(a[i], b[i])) { - return false; - } - } - return true; -}; - -Kotlin.arrayDeepEquals = function (a, b) { - if (a === b) { - return true; - } - if (!Array.isArray(b) || a.length !== b.length) { - return false; - } - - for (var i = 0, n = a.length; i < n; i++) { - if (Array.isArray(a[i])) { - if (!Kotlin.arrayDeepEquals(a[i], b[i])) { - return false; - } - } else if (!Kotlin.equals(a[i], b[i])) { - return false; - } - } - return true; -}; - -Kotlin.arrayHashCode = function (arr) { - var result = 1; - for (var i = 0, n = arr.length; i < n; i++) { - result = ((31 * result | 0) + Kotlin.hashCode(arr[i])) | 0; - } - return result; -}; - -Kotlin.arrayDeepHashCode = function (arr) { - var result = 1; - for (var i = 0, n = arr.length; i < n; i++) { - var e = arr[i]; - result = ((31 * result | 0) + (Array.isArray(e) ? Kotlin.arrayDeepHashCode(e) : Kotlin.hashCode(e))) | 0; - } - return result; -}; - -Kotlin.primitiveArraySort = function(array) { - array.sort(Kotlin.primitiveCompareTo) -}; - -Kotlin.identityHashCode = getObjectHashCode; - diff --git a/js/js.libraries/src/js/kotlin_lib_ecma5.js b/js/js.libraries/src/js/kotlin_lib_ecma5.js deleted file mode 100644 index f2ed04bec1f..00000000000 --- a/js/js.libraries/src/js/kotlin_lib_ecma5.js +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright 2010-2014 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. - */ - -(function () { - Kotlin.TYPE = { - CLASS: "class", - TRAIT: "trait", - OBJECT: "object", - INIT_FUN: "init fun" - }; - - Kotlin.classCount = 0; - Kotlin.newClassIndex = function () { - var tmp = Kotlin.classCount; - Kotlin.classCount++; - return tmp; - }; - - function isNativeClass(obj) { - return !(obj == null) && obj.$metadata$ == null; - } - - Kotlin.callGetter = function (thisObject, klass, propertyName) { - 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) { - var propertyDescriptor = Object.getOwnPropertyDescriptor(klass, propertyName); - if (propertyDescriptor != null) { - if (propertyDescriptor.set != null) { - propertyDescriptor.set.call(thisObject, value); - } - else if ("value" in propertyDescriptor) { - throw new Error("Assertion failed: Kotlin compiler should not generate simple JavaScript properties for overridable " + - "Kotlin properties."); - } - } - else { - return Kotlin.callSetter(thisObject, Object.getPrototypeOf(klass), propertyName, value); - } - }; - - function isInheritanceFromTrait(metadata, trait) { - // 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++) { - if (baseClasses[i] === trait) { - return true; - } - } - for (i = 0; i < baseClasses.length; i++) { - if (isInheritanceFromTrait(baseClasses[i].$metadata$, trait)) { - return true; - } - } - return false; - } - - /** - * - * @param {*} object - * @param {Function|Object} klass - * @returns {Boolean} - */ - Kotlin.isType = function (object, klass) { - if (klass === Object) { - switch (typeof object) { - case "string": - case "number": - case "boolean": - case "function": - return true; - default: - return object instanceof Object; - } - } - - if (object == null || klass == null || (typeof object !== 'object' && typeof object !== 'function')) { - return false; - } - - if (typeof klass === "function" && object instanceof klass) { - return true; - } - - var proto = Object.getPrototypeOf(klass); - var constructor = proto != null ? proto.constructor : null; - if (constructor != null && "$metadata$" in constructor) { - var metadata = constructor.$metadata$; - if (metadata.type === Kotlin.TYPE.OBJECT) { - return object === klass; - } - } - - // In WebKit (JavaScriptCore) for some interfaces from DOM typeof returns "object", nevertheless they can be used in RHS of instanceof - if (isNativeClass(klass)) { - return object instanceof klass; - } - - if (isTrait(klass) && object.constructor != null) { - metadata = object.constructor.$metadata$; - if (metadata != null) { - return isInheritanceFromTrait(metadata, klass); - } - } - - return false; - }; - - function isTrait(klass) { - var metadata = klass.$metadata$; - return metadata != null && metadata.type === Kotlin.TYPE.TRAIT; - } - - // TODO Store callable references for members in class - Kotlin.getCallableRefForMemberFunction = function (memberName) { - return function () { - var args = [].slice.call(arguments); - var instance = args.shift(); - return instance[memberName].apply(instance, args); - }; - }; - - Kotlin.getBoundCallableRefForMemberFunction = function (receiver, memberName) { - return function () { - return receiver[memberName].apply(receiver, arguments); - }; - }; - - // TODO Store callable references for extension functions in class - // extFun expected receiver as the first argument - Kotlin.getCallableRefForExtensionFunction = function (extFun) { - return function () { - return extFun.apply(null, arguments); - }; - }; - - Kotlin.getBoundCallableRefForExtensionFunction = function (receiver, extFun) { - return function () { - var args = [].slice.call(arguments); - args.unshift(receiver); - return extFun.apply(null, args); - }; - }; - - Kotlin.getCallableRefForLocalExtensionFunction = function (extFun) { - return function () { - var args = [].slice.call(arguments); - var instance = args.shift(); - return extFun.apply(instance, args); - }; - }; - - Kotlin.getBoundCallableRefForLocalExtensionFunction = function (receiver, extFun) { - return function () { - return extFun.apply(receiver, arguments); - }; - }; - - Kotlin.getCallableRefForConstructor = function (klass) { - return function () { - var obj = Object.create(klass.prototype); - klass.apply(obj, arguments); - return obj; - }; - }; - - Kotlin.getCallableRefForTopLevelProperty = function(getter, setter, name) { - var getFun = Function("getter", "return function " + name + "() { return getter(); }")(getter, setter); - return getPropertyRefClass(getFun, "get", setter, "set_za3rmp$", propertyRefClassMetadataCache.zeroArg); - }; - - Kotlin.getCallableRefForMemberProperty = function(name, isVar) { - var getFun = Function("return function " + name + "(receiver) { return receiver['" + name + "']; }")(); - var setFun = isVar ? function(receiver, value) { receiver[name] = value; } : null; - return getPropertyRefClass(getFun, "get_za3rmp$", setFun, "set_wn2jw4$", propertyRefClassMetadataCache.oneArg); - }; - - Kotlin.getBoundCallableRefForMemberProperty = function(receiver, name, isVar) { - var getFun = Function("receiver", "return function " + name + "() { return receiver['" + name + "']; }")(receiver); - var setFun = isVar ? function(value) { receiver[name] = value; } : null; - return getPropertyRefClass(getFun, "get", setFun, "set_za3rmp$", propertyRefClassMetadataCache.oneArg); - }; - - Kotlin.getCallableRefForExtensionProperty = function(name, getFun, setFun) { - var getFunWrapper = Function("getFun", "return function " + name + "(receiver, extensionReceiver) { return getFun(receiver, extensionReceiver) }")(getFun); - return getPropertyRefClass(getFunWrapper, "get_za3rmp$", setFun, "set_wn2jw4$", propertyRefClassMetadataCache.oneArg); - }; - - Kotlin.getBoundCallableRefForExtensionProperty = function(receiver, name, getFun, setFun) { - var getFunWrapper = Function("receiver", "getFun", "return function " + name + "(extensionReceiver) { return getFun(receiver, extensionReceiver) }")(receiver, getFun); - if (setFun) { - setFun = setFun.bind(null, receiver); - } - return getPropertyRefClass(getFunWrapper, "get", setFun, "set_za3rmp$", propertyRefClassMetadataCache.oneArg); - }; - - function getPropertyRefClass(getFun, getName, setFun, setName, cache) { - var obj = getFun; - var isMutable = typeof setFun === "function"; - obj.$metadata$ = getPropertyRefMetadata(isMutable ? cache.mutable : cache.immutable); - obj[getName] = getFun; - if (isMutable) { - obj[setName] = setFun; - } - obj.constructor = obj; - return obj; - } - - var propertyRefClassMetadataCache = { - zeroArg: { - mutable: { value: null, implementedInterface: function () { - return Kotlin.kotlin.reflect.KMutableProperty0 } - }, - immutable: { value: null, implementedInterface: function () { - return Kotlin.kotlin.reflect.KProperty0 } - } - }, - oneArg: { - mutable: { value: null, implementedInterface: function () { - return Kotlin.kotlin.reflect.KMutableProperty1 } - }, - immutable: { value: null, implementedInterface: function () { - return Kotlin.kotlin.reflect.KProperty1 } - } - } - }; - - function getPropertyRefMetadata(cache) { - if (cache.value === null) { - cache.value = { - baseClasses: [cache.implementedInterface()], - baseClass: null, - classIndex: Kotlin.newClassIndex(), - functions: {}, - properties: {}, - types: {}, - staticMembers: {} - }; - } - return cache.value; - } - -////////////////////////////////// packages & modules ////////////////////////////// - - /** - * @param {string} id - * @param {Object} declaration - */ - Kotlin.defineModule = function (id, declaration) { - }; - - Kotlin.defineInlineFunction = function(tag, fun) { - return fun; - }; - - Kotlin.isTypeOf = function(type) { - return function (object) { - return typeof object === type; - } - }; - - Kotlin.isInstanceOf = function (klass) { - return function (object) { - return Kotlin.isType(object, klass); - } - }; - - Kotlin.orNull = function (fn) { - return function (object) { - return object == null || fn(object); - } - }; - - Kotlin.andPredicate = function (a, b) { - return function (object) { - return a(object) && b(object); - } - }; - - Kotlin.kotlinModuleMetadata = function (abiVersion, moduleName, data) { - }; - - Kotlin.imul = Math.imul || imul; - - Kotlin.imulEmulated = imul; - - function imul(a, b) { - return ((a & 0xffff0000) * (b & 0xffff) + (a & 0xffff) * (b | 0)) | 0; - } -})(); diff --git a/js/js.libraries/src/js/markerFunctions.js b/js/js.libraries/src/js/markerFunctions.js new file mode 100644 index 00000000000..cac14f87883 --- /dev/null +++ b/js/js.libraries/src/js/markerFunctions.js @@ -0,0 +1,53 @@ +/* + * 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. + */ + +/** + * @param {string} id + * @param {Object} declaration + */ +Kotlin.defineModule = function (id, declaration) { +}; + +Kotlin.defineInlineFunction = function(tag, fun) { + return fun; +}; + +Kotlin.isTypeOf = function(type) { + return function (object) { + return typeof object === type; + } +}; + +Kotlin.isInstanceOf = function (klass) { + return function (object) { + return Kotlin.isType(object, klass); + } +}; + +Kotlin.orNull = function (fn) { + return function (object) { + return object == null || fn(object); + } +}; + +Kotlin.andPredicate = function (a, b) { + return function (object) { + return a(object) && b(object); + } +}; + +Kotlin.kotlinModuleMetadata = function (abiVersion, moduleName, data) { +}; diff --git a/js/js.libraries/src/js/misc.js b/js/js.libraries/src/js/misc.js new file mode 100644 index 00000000000..7a7f36b840b --- /dev/null +++ b/js/js.libraries/src/js/misc.js @@ -0,0 +1,50 @@ +/* + * 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. + */ + +Kotlin.compareTo = function (a, b) { + var typeA = typeof a; + var typeB = typeof a; + if (Kotlin.isChar(a) && typeB == "number") { + return Kotlin.primitiveCompareTo(a.charCodeAt(0), b); + } + if (typeA == "number" && Kotlin.isChar(b)) { + return Kotlin.primitiveCompareTo(a, b.charCodeAt(0)); + } + if (typeA == "number" || typeA == "string") { + return a < b ? -1 : a > b ? 1 : 0; + } + return a.compareTo_za3rmp$(b); +}; + +Kotlin.primitiveCompareTo = function (a, b) { + return a < b ? -1 : a > b ? 1 : 0; +}; + +Kotlin.charInc = function (value) { + return String.fromCharCode(value.charCodeAt(0)+1); +}; + +Kotlin.charDec = function (value) { + return String.fromCharCode(value.charCodeAt(0)-1); +}; + +Kotlin.imul = Math.imul || imul; + +Kotlin.imulEmulated = imul; + +function imul(a, b) { + return ((a & 0xffff0000) * (b & 0xffff) + (a & 0xffff) * (b | 0)) | 0; +} diff --git a/js/js.libraries/src/js/kotlin_polyfills.js b/js/js.libraries/src/js/polyfills.js similarity index 98% rename from js/js.libraries/src/js/kotlin_polyfills.js rename to js/js.libraries/src/js/polyfills.js index 7e3a44423a5..dd7ace6057b 100644 --- a/js/js.libraries/src/js/kotlin_polyfills.js +++ b/js/js.libraries/src/js/polyfills.js @@ -14,7 +14,6 @@ * limitations under the License. */ -// Shims for String if (typeof String.prototype.startsWith === "undefined") { String.prototype.startsWith = function(searchString, position) { position = position || 0; diff --git a/js/js.libraries/src/js/rtti.js b/js/js.libraries/src/js/rtti.js new file mode 100644 index 00000000000..6e8a69b86eb --- /dev/null +++ b/js/js.libraries/src/js/rtti.js @@ -0,0 +1,162 @@ +/* + * 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. + */ + +Kotlin.TYPE = { + CLASS: "class", + TRAIT: "trait", + OBJECT: "object", + INIT_FUN: "init fun" +}; + +Kotlin.classCount = 0; +Kotlin.newClassIndex = function () { + var tmp = Kotlin.classCount; + Kotlin.classCount++; + return tmp; +}; + +function isNativeClass(obj) { + return !(obj == null) && obj.$metadata$ == null; +} + +Kotlin.callGetter = function (thisObject, klass, propertyName) { + 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) { + var propertyDescriptor = Object.getOwnPropertyDescriptor(klass, propertyName); + if (propertyDescriptor != null) { + if (propertyDescriptor.set != null) { + propertyDescriptor.set.call(thisObject, value); + } + else if ("value" in propertyDescriptor) { + throw new Error("Assertion failed: Kotlin compiler should not generate simple JavaScript properties for overridable " + + "Kotlin properties."); + } + } + else { + return Kotlin.callSetter(thisObject, Object.getPrototypeOf(klass), propertyName, value); + } +}; + +function isInheritanceFromTrait(metadata, trait) { + // 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++) { + if (baseClasses[i] === trait) { + return true; + } + } + for (i = 0; i < baseClasses.length; i++) { + if (isInheritanceFromTrait(baseClasses[i].$metadata$, trait)) { + return true; + } + } + return false; +} + +/** + * + * @param {*} object + * @param {Function|Object} klass + * @returns {Boolean} + */ +Kotlin.isType = function (object, klass) { + if (klass === Object) { + switch (typeof object) { + case "string": + case "number": + case "boolean": + case "function": + return true; + default: + return object instanceof Object; + } + } + + if (object == null || klass == null || (typeof object !== 'object' && typeof object !== 'function')) { + return false; + } + + if (typeof klass === "function" && object instanceof klass) { + return true; + } + + var proto = Object.getPrototypeOf(klass); + var constructor = proto != null ? proto.constructor : null; + if (constructor != null && "$metadata$" in constructor) { + var metadata = constructor.$metadata$; + if (metadata.type === Kotlin.TYPE.OBJECT) { + return object === klass; + } + } + + // In WebKit (JavaScriptCore) for some interfaces from DOM typeof returns "object", nevertheless they can be used in RHS of instanceof + if (isNativeClass(klass)) { + return object instanceof klass; + } + + if (isTrait(klass) && object.constructor != null) { + metadata = object.constructor.$metadata$; + if (metadata != null) { + return isInheritanceFromTrait(metadata, klass); + } + } + + return false; +}; + +function isTrait(klass) { + var metadata = klass.$metadata$; + return metadata != null && metadata.type === Kotlin.TYPE.TRAIT; +} + +Kotlin.isNumber = function (a) { + return typeof a == "number" || a instanceof Kotlin.Long; +}; + +Kotlin.isChar = function (value) { + return (typeof value) == "string" && value.length == 1; +}; + +Kotlin.isComparable = function (value) { + var type = typeof value; + + return type === "string" || + type === "boolean" || + Kotlin.isNumber(value) || + Kotlin.isType(value, Kotlin.kotlin.Comparable); +}; + +Kotlin.isCharSequence = function (value) { + return typeof value === "string" || Kotlin.isType(value, Kotlin.kotlin.CharSequence); +}; \ No newline at end of file