JS: support enums in flat JS structure

This commit is contained in:
Alexey Andreev
2016-10-19 13:15:59 +03:00
parent 54925e7f83
commit 06476402a2
7 changed files with 198 additions and 33 deletions
+4
View File
@@ -28,6 +28,10 @@ class Enum<T : Enum<T>> : Comparable<Enum<T>> {
override fun compareTo(other: Enum<T>) = ordinal.compareTo(other.ordinal) override fun compareTo(other: Enum<T>) = ordinal.compareTo(other.ordinal)
override fun equals(other: Any?) = this === other
override fun hashCode(): Int = js("Kotlin.identityHashCode(this)")
override fun toString() = name override fun toString() = name
} }
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getSupertypesWi
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getPrimaryConstructorParameters import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getPrimaryConstructorParameters
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.toInvocationWith import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.toInvocationWith
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtSecondaryConstructor import org.jetbrains.kotlin.psi.KtSecondaryConstructor
import org.jetbrains.kotlin.resolve.BindingContextUtils import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -55,7 +56,9 @@ import org.jetbrains.kotlin.utils.identity
*/ */
class ClassTranslator private constructor( class ClassTranslator private constructor(
private val classDeclaration: KtClassOrObject, private val classDeclaration: KtClassOrObject,
context: TranslationContext context: TranslationContext,
private val enumInitializerName: JsName?,
private val ordinal: Int?
) : AbstractTranslator(context) { ) : AbstractTranslator(context) {
private val descriptor = getClassDescriptor(context.bindingContext(), classDeclaration) private val descriptor = getClassDescriptor(context.bindingContext(), classDeclaration)
@@ -73,12 +76,13 @@ class ClassTranslator private constructor(
val context = context().newDeclaration(descriptor) val context = context().newDeclaration(descriptor)
val constructorFunction = context.defineTopLevelFunction(descriptor) val constructorFunction = context.defineTopLevelFunction(descriptor)
val enumInitFunction = if (descriptor.kind == ClassKind.ENUM_CLASS) createEnumInitFunction() else null
val nonConstructorContext = context.innerWithUsageTracker(scope, descriptor) val nonConstructorContext = context.innerWithUsageTracker(scope, descriptor)
nonConstructorContext.startDeclaration() nonConstructorContext.startDeclaration()
val delegationTranslator = DelegationTranslator(classDeclaration, nonConstructorContext) val delegationTranslator = DelegationTranslator(classDeclaration, nonConstructorContext)
translatePropertiesAsConstructorParameters(nonConstructorContext) translatePropertiesAsConstructorParameters(nonConstructorContext)
val bodyVisitor = DeclarationBodyVisitor(descriptor, nonConstructorContext) val bodyVisitor = DeclarationBodyVisitor(descriptor, nonConstructorContext, enumInitFunction)
bodyVisitor.traverseContainer(classDeclaration, nonConstructorContext) bodyVisitor.traverseContainer(classDeclaration, nonConstructorContext)
constructorFunction.body.statements += bodyVisitor.initializerStatements constructorFunction.body.statements += bodyVisitor.initializerStatements
delegationTranslator.generateDelegated() delegationTranslator.generateDelegated()
@@ -104,6 +108,10 @@ class ClassTranslator private constructor(
if (isObjectLike()) { if (isObjectLike()) {
addObjectMethods() addObjectMethods()
} }
if (descriptor.kind == ClassKind.ENUM_CLASS) {
generateEnumStandardMethods(bodyVisitor.enumEntries)
}
} }
private fun translatePrimaryConstructor( private fun translatePrimaryConstructor(
@@ -116,8 +124,13 @@ class ClassTranslator private constructor(
if (isObjectLike()) { if (isObjectLike()) {
addObjectCache(constructorFunction.body.statements) addObjectCache(constructorFunction.body.statements)
} }
ClassInitializerTranslator(classDeclaration, constructorContext, constructorFunction) ClassInitializerTranslator(classDeclaration, constructorContext, constructorFunction).apply {
.generateInitializeMethod(delegationTranslator) if (ordinal != null) {
setOrdinal(ordinal)
}
generateInitializeMethod(delegationTranslator)
}
primaryConstructor = ConstructorInfo(constructorFunction, constructorContext, descriptor) primaryConstructor = ConstructorInfo(constructorFunction, constructorContext, descriptor)
if (descriptor.kind == ClassKind.ENUM_CLASS) { if (descriptor.kind == ClassKind.ENUM_CLASS) {
@@ -126,10 +139,19 @@ class ClassTranslator private constructor(
} }
} }
private fun createEnumInitFunction(): JsFunction {
val function = context().createTopLevelAnonymousFunction(descriptor)
function.name = context().createGlobalName(StaticContext.getSuggestedName(descriptor) + "_initFields")
val emptyFunction = context().createTopLevelAnonymousFunction(descriptor)
function.body.statements += JsAstUtils.assignment(JsAstUtils.pureFqn(function.name, null), emptyFunction).makeStmt()
context().addDeclarationStatement(function.makeStmt())
return function
}
private fun addEnumClassParameters(constructorFunction: JsFunction) { private fun addEnumClassParameters(constructorFunction: JsFunction) {
val nameParamName = constructorFunction.scope.declareFreshName("name") val nameParamName = constructorFunction.scope.declareFreshName("name")
val ordinalParamName = constructorFunction.scope.declareFreshName("ordinal") val ordinalParamName = constructorFunction.scope.declareFreshName("ordinal")
constructorFunction.parameters += listOf(JsParameter(nameParamName), JsParameter(ordinalParamName)) constructorFunction.parameters.addAll(0, listOf(JsParameter(nameParamName), JsParameter(ordinalParamName)))
constructorFunction.body.statements += JsAstUtils.assignmentToThisField(Namer.ENUM_NAME_FIELD, nameParamName.makeRef()) constructorFunction.body.statements += JsAstUtils.assignmentToThisField(Namer.ENUM_NAME_FIELD, nameParamName.makeRef())
constructorFunction.body.statements += JsAstUtils.assignmentToThisField(Namer.ENUM_ORDINAL_FIELD, ordinalParamName.makeRef()) constructorFunction.body.statements += JsAstUtils.assignmentToThisField(Namer.ENUM_ORDINAL_FIELD, ordinalParamName.makeRef())
@@ -200,6 +222,12 @@ class ClassTranslator private constructor(
// Add parameter for outer instance // Add parameter for outer instance
val leadingArgs = mutableListOf<JsExpression>() val leadingArgs = mutableListOf<JsExpression>()
if (descriptor.kind == ClassKind.ENUM_CLASS) {
val nameParamName = constructorInitializer.scope.declareFreshName("name")
val ordinalParamName = constructorInitializer.scope.declareFreshName("ordinal")
constructorInitializer.parameters.addAll(0, listOf(JsParameter(nameParamName), JsParameter(ordinalParamName)))
leadingArgs += listOf(nameParamName.makeRef(), ordinalParamName.makeRef())
}
if (outerClassName != null) { if (outerClassName != null) {
constructorInitializer.parameters.add(0, JsParameter(outerClassName)) constructorInitializer.parameters.add(0, JsParameter(outerClassName))
leadingArgs += outerClassName.makeRef() leadingArgs += outerClassName.makeRef()
@@ -242,9 +270,7 @@ class ClassTranslator private constructor(
secondaryConstructors += ConstructorInfo(constructorInitializer, context, constructorDescriptor, compositeSuperCallGenerator) secondaryConstructors += ConstructorInfo(constructorInitializer, context, constructorDescriptor, compositeSuperCallGenerator)
if (DescriptorUtils.isTopLevelDeclaration(classDescriptor)) { context.export(constructorDescriptor)
context.export(constructorDescriptor)
}
} }
private val allConstructors: Sequence<ConstructorInfo> private val allConstructors: Sequence<ConstructorInfo>
@@ -387,19 +413,28 @@ class ClassTranslator private constructor(
val instanceFun = JsFunction(context().rootFunction.scope, JsBlock(), "Instance function: " + descriptor) val instanceFun = JsFunction(context().rootFunction.scope, JsBlock(), "Instance function: " + descriptor)
instanceFun.name = context().getNameForObjectInstance(descriptor) instanceFun.name = context().getNameForObjectInstance(descriptor)
val instanceCreatedCondition = JsAstUtils.equality(cachedInstanceName.makeRef(), JsLiteral.NULL) if (enumInitializerName == null) {
val instanceCreationBlock = JsBlock() val instanceCreatedCondition = JsAstUtils.equality(cachedInstanceName.makeRef(), JsLiteral.NULL)
val instanceCreatedGuard = JsIf(instanceCreatedCondition, instanceCreationBlock) val instanceCreationBlock = JsBlock()
instanceFun.body.statements += instanceCreatedGuard val instanceCreatedGuard = JsIf(instanceCreatedCondition, instanceCreationBlock)
instanceFun.body.statements += instanceCreatedGuard
val objectRef = context().getInnerReference(descriptor) val objectRef = context().getInnerReference(descriptor)
instanceCreationBlock.statements += JsAstUtils.assignment(cachedInstanceName.makeRef(), JsNew(objectRef)).makeStmt() instanceCreationBlock.statements += JsAstUtils.assignment(cachedInstanceName.makeRef(), JsNew(objectRef)).makeStmt()
}
else {
instanceFun.body.statements += JsInvocation(pureFqn(enumInitializerName, null)).makeStmt()
}
instanceFun.body.statements += JsReturn(cachedInstanceName.makeRef()) instanceFun.body.statements += JsReturn(cachedInstanceName.makeRef())
context().addDeclarationStatement(instanceFun.makeStmt()) context().addDeclarationStatement(instanceFun.makeStmt())
} }
private fun generateEnumStandardMethods(entries: List<ClassDescriptor>) {
EnumTranslator(context(), descriptor, entries).generateStandardMethods()
}
private fun generatedBridgeMethods() { private fun generatedBridgeMethods() {
if (isAnnotation()) return if (isAnnotation()) return
@@ -450,7 +485,11 @@ class ClassTranslator private constructor(
companion object { companion object {
@JvmStatic fun translate(classDeclaration: KtClassOrObject, context: TranslationContext) { @JvmStatic fun translate(classDeclaration: KtClassOrObject, context: TranslationContext) {
return ClassTranslator(classDeclaration, context).translate() return ClassTranslator(classDeclaration, context, null, null).translate()
}
@JvmStatic fun translate(classDeclaration: KtEnumEntry, context: TranslationContext, enumInitializerName: JsName, ordinal: Int) {
return ClassTranslator(classDeclaration, context, enumInitializerName, ordinal).translate()
} }
@JvmStatic fun addInterfaceDefaultMembers(descriptor: ClassDescriptor, context: StaticContext) { @JvmStatic fun addInterfaceDefaultMembers(descriptor: ClassDescriptor, context: StaticContext) {
@@ -25,16 +25,19 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.initializer.ClassInitializerTranslator import org.jetbrains.kotlin.js.translate.initializer.ClassInitializerTranslator
import org.jetbrains.kotlin.js.translate.utils.* import org.jetbrains.kotlin.js.translate.utils.*
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor
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.JsDescriptorUtils.getSupertypesWithoutFakes
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import java.util.* import java.util.*
class DeclarationBodyVisitor( class DeclarationBodyVisitor(
private val containingClass: ClassDescriptor, private val containingClass: ClassDescriptor,
private val context: TranslationContext private val context: TranslationContext,
private val enumInitializer: JsFunction?
) : AbstractDeclarationVisitor() { ) : AbstractDeclarationVisitor() {
private var enumEntryOrdinal: Int = 0 private var enumEntryOrdinal: Int = 0
val initializerStatements = ArrayList<JsStatement>() val initializerStatements = mutableListOf<JsStatement>()
val enumEntries = mutableListOf<ClassDescriptor>()
override fun visitClassOrObject(classOrObject: KtClassOrObject, context: TranslationContext) { override fun visitClassOrObject(classOrObject: KtClassOrObject, context: TranslationContext) {
super.visitClassOrObject(classOrObject, context) super.visitClassOrObject(classOrObject, context)
@@ -48,29 +51,31 @@ class DeclarationBodyVisitor(
} }
override fun visitEnumEntry(enumEntry: KtEnumEntry, context: TranslationContext) { override fun visitEnumEntry(enumEntry: KtEnumEntry, context: TranslationContext) {
val enumInitializer = this.enumInitializer!!
val descriptor = getClassDescriptor(context.bindingContext(), enumEntry) val descriptor = getClassDescriptor(context.bindingContext(), enumEntry)
val supertypes = getSupertypesWithoutFakes(descriptor) val supertypes = getSupertypesWithoutFakes(descriptor)
enumEntries += descriptor
if (enumEntry.getBody() != null || supertypes.size > 1) { if (enumEntry.getBody() != null || supertypes.size > 1) {
ClassTranslator.translate(enumEntry, context) ClassTranslator.translate(enumEntry, context, enumInitializer.name, enumEntryOrdinal)
enumInitializer.body.statements += JsNew(context.getInnerReference(descriptor)).makeStmt()
} }
else { else {
// Simplify by omitting _getInstance() function
val enumName = context.getInnerNameForDescriptor(descriptor) val enumName = context.getInnerNameForDescriptor(descriptor)
val enumInstanceName = context.createGlobalName(enumName.ident + "_instance") val enumInstanceName = context.createGlobalName(enumName.ident + "_instance")
assert(supertypes.size == 1) { "Simple Enum entry must have one supertype" } assert(supertypes.size == 1) { "Simple Enum entry must have one supertype" }
val jsEnumEntryCreation = ClassInitializerTranslator val jsEnumEntryCreation = ClassInitializerTranslator
.generateEnumEntryInstanceCreation(context, supertypes[0], enumEntry, enumEntryOrdinal) .generateEnumEntryInstanceCreation(context, supertypes[0], enumEntry, enumEntryOrdinal)
context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, jsEnumEntryCreation)) context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, null))
val jsEnumEntryFunction = context.createTopLevelAnonymousFunction(descriptor) enumInitializer.body.statements += JsAstUtils.assignment(pureFqn(enumInstanceName, null), jsEnumEntryCreation).makeStmt()
jsEnumEntryFunction.body.statements.add(JsReturn(jsEnumEntryCreation))
val enumInstanceFunction = context.createTopLevelAnonymousFunction(descriptor) val enumInstanceFunction = context.createTopLevelAnonymousFunction(descriptor)
enumInstanceFunction.name = context.getNameForObjectInstance(descriptor) enumInstanceFunction.name = context.getNameForObjectInstance(descriptor)
context.addDeclarationStatement(enumInstanceFunction.makeStmt()) context.addDeclarationStatement(enumInstanceFunction.makeStmt())
enumInstanceFunction.body.statements.add(JsReturn(enumInstanceName.makeRef())) enumInstanceFunction.body.statements += JsInvocation(pureFqn(enumInitializer.name, null)).makeStmt()
enumInstanceFunction.body.statements += JsReturn(enumInstanceName.makeRef())
} }
enumEntryOrdinal++ enumEntryOrdinal++
@@ -0,0 +1,84 @@
/*
* 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.declaration
import com.google.dart.compiler.backend.js.ast.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
class EnumTranslator(
context: TranslationContext,
val descriptor: ClassDescriptor,
val entries: List<ClassDescriptor>
) : AbstractTranslator(context) {
fun generateStandardMethods() {
generateValuesFunction()
generateValueOfFunction()
}
private fun generateValuesFunction() {
val function = createFunction(getEnumFunction(DescriptorUtils.ENUM_VALUES))
val values = entries.map { JsInvocation(JsAstUtils.pureFqn(context().getNameForObjectInstance(it), null)) }
function.body.statements += JsReturn(JsArrayLiteral(values))
}
private fun generateValueOfFunction() {
val function = createFunction(getEnumFunction(DescriptorUtils.ENUM_VALUE_OF))
val nameParam = function.scope.declareFreshName("name")
function.parameters += JsParameter(nameParam)
val clauses = entries.map { entry ->
JsCase().apply {
caseExpression = context().program().getStringLiteral(entry.name.asString())
statements += JsReturn(JsInvocation(JsAstUtils.pureFqn(context().getNameForObjectInstance(entry), null)))
}
}
if (clauses.isNotEmpty()) {
function.body.statements += JsSwitch(nameParam.makeRef(), clauses)
}
}
private fun createFunction(functionDescriptor: FunctionDescriptor): JsFunction {
val function = context().getFunctionObject(functionDescriptor)
function.name = context().getInnerNameForDescriptor(functionDescriptor)
context().addDeclarationStatement(function.makeStmt())
val classRef = context().getInnerReference(descriptor)
val functionRef = function.name.makeRef()
val assignment = JsAstUtils.assignment(JsNameRef(context().getNameForDescriptor(functionDescriptor), classRef), functionRef)
context().addDeclarationStatement(assignment.makeStmt())
return function
}
private fun getEnumFunction(name: Name): FunctionDescriptor {
val functions = descriptor.staticScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
return functions
.mapNotNull { (it as? FunctionDescriptor)?.original }
.first { it.name == name }
}
}
@@ -64,6 +64,8 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
@NotNull @NotNull
private final ClassDescriptor classDescriptor; private final ClassDescriptor classDescriptor;
private int ordinal;
public ClassInitializerTranslator( public ClassInitializerTranslator(
@NotNull KtClassOrObject classDeclaration, @NotNull KtClassOrObject classDeclaration,
@NotNull TranslationContext context, @NotNull TranslationContext context,
@@ -78,6 +80,10 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
fillInitFunction(classDeclaration, context); fillInitFunction(classDeclaration, context);
} }
public void setOrdinal(int ordinal) {
this.ordinal = ordinal;
}
@NotNull @NotNull
@Override @Override
protected TranslationContext context() { protected TranslationContext context() {
@@ -153,15 +159,27 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
) { ) {
ResolvedCall<FunctionDescriptor> superCall = getSuperCall(context.bindingContext(), classDeclaration); ResolvedCall<FunctionDescriptor> superCall = getSuperCall(context.bindingContext(), classDeclaration);
JsExpression nameArg = context.program().getStringLiteral(classDeclaration.getName());
JsExpression ordinalArg = context.program().getNumberLiteral(ordinal);
List<JsExpression> additionalArgs = Arrays.asList(nameArg, ordinalArg);
if (superCall == null) { if (superCall == null) {
ClassDescriptor classDescriptor = getClassDescriptorForType(enumClassType); ClassDescriptor classDescriptor = getClassDescriptorForType(enumClassType);
JsNameRef reference = context.getInnerReference(classDescriptor); JsNameRef reference = context.getInnerReference(classDescriptor);
JsExpression nameArg = context.program().getStringLiteral(classDeclaration.getName()); return new JsNew(reference, additionalArgs);
JsExpression ordinalArg = context.program().getNumberLiteral(ordinal);
return new JsNew(reference, Arrays.asList(nameArg, ordinalArg));
} }
return CallTranslator.translate(context, superCall); JsExpression call = CallTranslator.translate(context, superCall);
if (call instanceof JsInvocation) {
JsInvocation invocation = (JsInvocation) call;
invocation.getArguments().addAll(0, additionalArgs);
}
else if (call instanceof JsNew) {
JsNew invocation = (JsNew) call;
invocation.getArguments().addAll(0, additionalArgs);
}
return call;
} }
private void mayBeAddCallToSuperMethod(JsFunction initializer) { private void mayBeAddCallToSuperMethod(JsFunction initializer) {
@@ -172,15 +190,16 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
ResolvedCall<FunctionDescriptor> superCall = getSuperCall(bindingContext(), classDeclaration); ResolvedCall<FunctionDescriptor> superCall = getSuperCall(bindingContext(), classDeclaration);
if (superCall == null) { if (superCall == null) {
if (DescriptorUtils.isEnumEntry(classDescriptor)) { if (DescriptorUtils.isEnumEntry(classDescriptor)) {
addCallToSuperMethod(Collections.<JsExpression>emptyList(), initializer); addCallToSuperMethod(getAdditionalArgumentsForEnumConstructor(), initializer);
} }
return; return;
} }
if (classDeclaration instanceof KtEnumEntry) { if (classDeclaration instanceof KtEnumEntry) {
JsExpression expression = CallTranslator.translate(context(), superCall, null); JsExpression expression = CallTranslator.translate(context(), superCall, null);
JsExpression fixedInvocation = AstUtilsKt.toInvocationWith(expression, Collections.<JsExpression>emptyList(), 0,
JsLiteral.THIS); JsExpression fixedInvocation = AstUtilsKt.toInvocationWith(
expression, getAdditionalArgumentsForEnumConstructor(), 0, JsLiteral.THIS);
initFunction.getBody().getStatements().add(fixedInvocation.makeStmt()); initFunction.getBody().getStatements().add(fixedInvocation.makeStmt());
} }
else { else {
@@ -235,6 +254,14 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
} }
} }
@NotNull
private List<JsExpression> getAdditionalArgumentsForEnumConstructor() {
List<JsExpression> additionalArguments = new ArrayList<JsExpression>();
additionalArguments.add(program().getStringLiteral(classDescriptor.getName().asString()));
additionalArguments.add(program().getNumberLiteral(ordinal));
return additionalArguments;
}
private void addCallToSuperMethod(@NotNull List<JsExpression> arguments, @NotNull JsFunction initializer) { private void addCallToSuperMethod(@NotNull List<JsExpression> arguments, @NotNull JsFunction initializer) {
if (initializer.getName() == null) { if (initializer.getName() == null) {
JsName ref = context().scope().declareName(Namer.CALLEE_NAME); JsName ref = context().scope().declareName(Namer.CALLEE_NAME);
@@ -56,7 +56,11 @@ fun JsNode.any(predicate: (JsNode) -> Boolean): Boolean {
return visitor.matched return visitor.matched
} }
fun JsExpression.toInvocationWith(leadingExtraArgs: List<JsExpression>, parameterCount: Int, thisExpr: JsExpression): JsExpression { fun JsExpression.toInvocationWith(
leadingExtraArgs: List<JsExpression>,
parameterCount: Int,
thisExpr: JsExpression
): JsExpression {
val qualifier: JsExpression val qualifier: JsExpression
fun padArguments(arguments: List<JsExpression>) = arguments + (1..(parameterCount - arguments.size)) fun padArguments(arguments: List<JsExpression>) = arguments + (1..(parameterCount - arguments.size))
.map { Namer.getUndefinedExpression() } .map { Namer.getUndefinedExpression() }
+4 -2
View File
@@ -143,11 +143,11 @@
return type === "string" || return type === "string" ||
type === "boolean" || type === "boolean" ||
Kotlin.isNumber(value) || Kotlin.isNumber(value) ||
Kotlin.isType(value, Kotlin.Comparable); Kotlin.isType(value, Kotlin.kotlin.Comparable);
}; };
Kotlin.isCharSequence = function (value) { Kotlin.isCharSequence = function (value) {
return typeof value === "string" || Kotlin.isType(value, CharSequence); return typeof value === "string" || Kotlin.isType(value, Kotlin.kotlin.CharSequence);
}; };
Kotlin.charInc = function (value) { Kotlin.charInc = function (value) {
@@ -497,5 +497,7 @@
} }
return obj1; return obj1;
}; };
Kotlin.identityHashCode = getObjectHashCode;
})(Kotlin); })(Kotlin);