JS: support enums in flat JS structure
This commit is contained in:
@@ -28,6 +28,10 @@ class Enum<T : Enum<T>> : Comparable<Enum<T>> {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
+54
-15
@@ -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.jsAstUtils.toInvocationWith
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -55,7 +56,9 @@ import org.jetbrains.kotlin.utils.identity
|
||||
*/
|
||||
class ClassTranslator private constructor(
|
||||
private val classDeclaration: KtClassOrObject,
|
||||
context: TranslationContext
|
||||
context: TranslationContext,
|
||||
private val enumInitializerName: JsName?,
|
||||
private val ordinal: Int?
|
||||
) : AbstractTranslator(context) {
|
||||
|
||||
private val descriptor = getClassDescriptor(context.bindingContext(), classDeclaration)
|
||||
@@ -73,12 +76,13 @@ class ClassTranslator private constructor(
|
||||
val context = context().newDeclaration(descriptor)
|
||||
|
||||
val constructorFunction = context.defineTopLevelFunction(descriptor)
|
||||
val enumInitFunction = if (descriptor.kind == ClassKind.ENUM_CLASS) createEnumInitFunction() else null
|
||||
|
||||
val nonConstructorContext = context.innerWithUsageTracker(scope, descriptor)
|
||||
nonConstructorContext.startDeclaration()
|
||||
val delegationTranslator = DelegationTranslator(classDeclaration, nonConstructorContext)
|
||||
translatePropertiesAsConstructorParameters(nonConstructorContext)
|
||||
val bodyVisitor = DeclarationBodyVisitor(descriptor, nonConstructorContext)
|
||||
val bodyVisitor = DeclarationBodyVisitor(descriptor, nonConstructorContext, enumInitFunction)
|
||||
bodyVisitor.traverseContainer(classDeclaration, nonConstructorContext)
|
||||
constructorFunction.body.statements += bodyVisitor.initializerStatements
|
||||
delegationTranslator.generateDelegated()
|
||||
@@ -104,6 +108,10 @@ class ClassTranslator private constructor(
|
||||
if (isObjectLike()) {
|
||||
addObjectMethods()
|
||||
}
|
||||
|
||||
if (descriptor.kind == ClassKind.ENUM_CLASS) {
|
||||
generateEnumStandardMethods(bodyVisitor.enumEntries)
|
||||
}
|
||||
}
|
||||
|
||||
private fun translatePrimaryConstructor(
|
||||
@@ -116,8 +124,13 @@ class ClassTranslator private constructor(
|
||||
if (isObjectLike()) {
|
||||
addObjectCache(constructorFunction.body.statements)
|
||||
}
|
||||
ClassInitializerTranslator(classDeclaration, constructorContext, constructorFunction)
|
||||
.generateInitializeMethod(delegationTranslator)
|
||||
ClassInitializerTranslator(classDeclaration, constructorContext, constructorFunction).apply {
|
||||
if (ordinal != null) {
|
||||
setOrdinal(ordinal)
|
||||
}
|
||||
generateInitializeMethod(delegationTranslator)
|
||||
}
|
||||
|
||||
primaryConstructor = ConstructorInfo(constructorFunction, constructorContext, descriptor)
|
||||
|
||||
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) {
|
||||
val nameParamName = constructorFunction.scope.declareFreshName("name")
|
||||
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_ORDINAL_FIELD, ordinalParamName.makeRef())
|
||||
@@ -200,6 +222,12 @@ class ClassTranslator private constructor(
|
||||
// Add parameter for outer instance
|
||||
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) {
|
||||
constructorInitializer.parameters.add(0, JsParameter(outerClassName))
|
||||
leadingArgs += outerClassName.makeRef()
|
||||
@@ -242,9 +270,7 @@ class ClassTranslator private constructor(
|
||||
|
||||
secondaryConstructors += ConstructorInfo(constructorInitializer, context, constructorDescriptor, compositeSuperCallGenerator)
|
||||
|
||||
if (DescriptorUtils.isTopLevelDeclaration(classDescriptor)) {
|
||||
context.export(constructorDescriptor)
|
||||
}
|
||||
context.export(constructorDescriptor)
|
||||
}
|
||||
|
||||
private val allConstructors: Sequence<ConstructorInfo>
|
||||
@@ -387,19 +413,28 @@ class ClassTranslator private constructor(
|
||||
val instanceFun = JsFunction(context().rootFunction.scope, JsBlock(), "Instance function: " + descriptor)
|
||||
instanceFun.name = context().getNameForObjectInstance(descriptor)
|
||||
|
||||
val instanceCreatedCondition = JsAstUtils.equality(cachedInstanceName.makeRef(), JsLiteral.NULL)
|
||||
val instanceCreationBlock = JsBlock()
|
||||
val instanceCreatedGuard = JsIf(instanceCreatedCondition, instanceCreationBlock)
|
||||
instanceFun.body.statements += instanceCreatedGuard
|
||||
if (enumInitializerName == null) {
|
||||
val instanceCreatedCondition = JsAstUtils.equality(cachedInstanceName.makeRef(), JsLiteral.NULL)
|
||||
val instanceCreationBlock = JsBlock()
|
||||
val instanceCreatedGuard = JsIf(instanceCreatedCondition, instanceCreationBlock)
|
||||
instanceFun.body.statements += instanceCreatedGuard
|
||||
|
||||
val objectRef = context().getInnerReference(descriptor)
|
||||
instanceCreationBlock.statements += JsAstUtils.assignment(cachedInstanceName.makeRef(), JsNew(objectRef)).makeStmt()
|
||||
val objectRef = context().getInnerReference(descriptor)
|
||||
instanceCreationBlock.statements += JsAstUtils.assignment(cachedInstanceName.makeRef(), JsNew(objectRef)).makeStmt()
|
||||
}
|
||||
else {
|
||||
instanceFun.body.statements += JsInvocation(pureFqn(enumInitializerName, null)).makeStmt()
|
||||
}
|
||||
|
||||
instanceFun.body.statements += JsReturn(cachedInstanceName.makeRef())
|
||||
|
||||
context().addDeclarationStatement(instanceFun.makeStmt())
|
||||
}
|
||||
|
||||
private fun generateEnumStandardMethods(entries: List<ClassDescriptor>) {
|
||||
EnumTranslator(context(), descriptor, entries).generateStandardMethods()
|
||||
}
|
||||
|
||||
private fun generatedBridgeMethods() {
|
||||
if (isAnnotation()) return
|
||||
|
||||
@@ -450,7 +485,11 @@ class ClassTranslator private constructor(
|
||||
|
||||
companion object {
|
||||
@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) {
|
||||
|
||||
+13
-8
@@ -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.utils.*
|
||||
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.psi.*
|
||||
import java.util.*
|
||||
|
||||
class DeclarationBodyVisitor(
|
||||
private val containingClass: ClassDescriptor,
|
||||
private val context: TranslationContext
|
||||
private val context: TranslationContext,
|
||||
private val enumInitializer: JsFunction?
|
||||
) : AbstractDeclarationVisitor() {
|
||||
private var enumEntryOrdinal: Int = 0
|
||||
val initializerStatements = ArrayList<JsStatement>()
|
||||
val initializerStatements = mutableListOf<JsStatement>()
|
||||
val enumEntries = mutableListOf<ClassDescriptor>()
|
||||
|
||||
override fun visitClassOrObject(classOrObject: KtClassOrObject, context: TranslationContext) {
|
||||
super.visitClassOrObject(classOrObject, context)
|
||||
@@ -48,29 +51,31 @@ class DeclarationBodyVisitor(
|
||||
}
|
||||
|
||||
override fun visitEnumEntry(enumEntry: KtEnumEntry, context: TranslationContext) {
|
||||
val enumInitializer = this.enumInitializer!!
|
||||
val descriptor = getClassDescriptor(context.bindingContext(), enumEntry)
|
||||
val supertypes = getSupertypesWithoutFakes(descriptor)
|
||||
enumEntries += descriptor
|
||||
|
||||
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 {
|
||||
// Simplify by omitting _getInstance() function
|
||||
val enumName = context.getInnerNameForDescriptor(descriptor)
|
||||
val enumInstanceName = context.createGlobalName(enumName.ident + "_instance")
|
||||
|
||||
assert(supertypes.size == 1) { "Simple Enum entry must have one supertype" }
|
||||
val jsEnumEntryCreation = ClassInitializerTranslator
|
||||
.generateEnumEntryInstanceCreation(context, supertypes[0], enumEntry, enumEntryOrdinal)
|
||||
context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, jsEnumEntryCreation))
|
||||
val jsEnumEntryFunction = context.createTopLevelAnonymousFunction(descriptor)
|
||||
jsEnumEntryFunction.body.statements.add(JsReturn(jsEnumEntryCreation))
|
||||
context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, null))
|
||||
enumInitializer.body.statements += JsAstUtils.assignment(pureFqn(enumInstanceName, null), jsEnumEntryCreation).makeStmt()
|
||||
|
||||
val enumInstanceFunction = context.createTopLevelAnonymousFunction(descriptor)
|
||||
enumInstanceFunction.name = context.getNameForObjectInstance(descriptor)
|
||||
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++
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
+34
-7
@@ -64,6 +64,8 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
private final ClassDescriptor classDescriptor;
|
||||
|
||||
private int ordinal;
|
||||
|
||||
public ClassInitializerTranslator(
|
||||
@NotNull KtClassOrObject classDeclaration,
|
||||
@NotNull TranslationContext context,
|
||||
@@ -78,6 +80,10 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
||||
fillInitFunction(classDeclaration, context);
|
||||
}
|
||||
|
||||
public void setOrdinal(int ordinal) {
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected TranslationContext context() {
|
||||
@@ -153,15 +159,27 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
||||
) {
|
||||
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) {
|
||||
ClassDescriptor classDescriptor = getClassDescriptorForType(enumClassType);
|
||||
JsNameRef reference = context.getInnerReference(classDescriptor);
|
||||
JsExpression nameArg = context.program().getStringLiteral(classDeclaration.getName());
|
||||
JsExpression ordinalArg = context.program().getNumberLiteral(ordinal);
|
||||
return new JsNew(reference, Arrays.asList(nameArg, ordinalArg));
|
||||
return new JsNew(reference, additionalArgs);
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -172,15 +190,16 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
||||
ResolvedCall<FunctionDescriptor> superCall = getSuperCall(bindingContext(), classDeclaration);
|
||||
if (superCall == null) {
|
||||
if (DescriptorUtils.isEnumEntry(classDescriptor)) {
|
||||
addCallToSuperMethod(Collections.<JsExpression>emptyList(), initializer);
|
||||
addCallToSuperMethod(getAdditionalArgumentsForEnumConstructor(), initializer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (classDeclaration instanceof KtEnumEntry) {
|
||||
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());
|
||||
}
|
||||
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) {
|
||||
if (initializer.getName() == null) {
|
||||
JsName ref = context().scope().declareName(Namer.CALLEE_NAME);
|
||||
|
||||
@@ -56,7 +56,11 @@ fun JsNode.any(predicate: (JsNode) -> Boolean): Boolean {
|
||||
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
|
||||
fun padArguments(arguments: List<JsExpression>) = arguments + (1..(parameterCount - arguments.size))
|
||||
.map { Namer.getUndefinedExpression() }
|
||||
|
||||
+4
-2
@@ -143,11 +143,11 @@
|
||||
return type === "string" ||
|
||||
type === "boolean" ||
|
||||
Kotlin.isNumber(value) ||
|
||||
Kotlin.isType(value, Kotlin.Comparable);
|
||||
Kotlin.isType(value, Kotlin.kotlin.Comparable);
|
||||
};
|
||||
|
||||
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) {
|
||||
@@ -497,5 +497,7 @@
|
||||
}
|
||||
return obj1;
|
||||
};
|
||||
|
||||
Kotlin.identityHashCode = getObjectHashCode;
|
||||
})(Kotlin);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user