JS IR BE: migrate to IR types
(cherry picked from commit 064f47b)
This commit is contained in:
committed by
Dmitry Petrov
parent
952163b2fb
commit
bf2aa5263e
+4
-14
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
*
|
* that can be found in the license/LICENSE.txt file.
|
||||||
* 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.backend.js
|
package org.jetbrains.kotlin.backend.js
|
||||||
@@ -29,6 +18,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
|||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
import org.jetbrains.kotlin.ir.util.dump
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -64,7 +54,7 @@ class JsDescriptorsFactory : DescriptorsFactory {
|
|||||||
false
|
false
|
||||||
).apply {
|
).apply {
|
||||||
setType(
|
setType(
|
||||||
outerClass.defaultType,
|
outerClass.defaultType.toKotlinType(),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
innerClass.descriptor.thisAsReceiverParameter,
|
innerClass.descriptor.thisAsReceiverParameter,
|
||||||
null as? ReceiverParameterDescriptor
|
null as? ReceiverParameterDescriptor
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class JsIntrinsics(
|
|||||||
context: JsIrBackendContext
|
context: JsIrBackendContext
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val stubBuilder = DeclarationStubGenerator(context.module, context.symbolTable, JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB)
|
private val stubBuilder = DeclarationStubGenerator(module, context.module, context.symbolTable, JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB)
|
||||||
|
|
||||||
// Equality operations:
|
// Equality operations:
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.ModuleIndex
|
import org.jetbrains.kotlin.ir.backend.js.lower.inline.ModuleIndex
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -59,7 +61,7 @@ class JsIrBackendContext(
|
|||||||
|
|
||||||
val secondaryConstructorsMap = mutableMapOf<IrConstructorSymbol, SecondaryCtorPair>()
|
val secondaryConstructorsMap = mutableMapOf<IrConstructorSymbol, SecondaryCtorPair>()
|
||||||
|
|
||||||
fun getOperatorByName(name: Name, type: KotlinType) = operatorMap[name]?.get(type)
|
fun getOperatorByName(name: Name, type: IrType) = operatorMap[name]?.get(type.toKotlinType())
|
||||||
|
|
||||||
val originalModuleIndex = ModuleIndex(irModuleFragment)
|
val originalModuleIndex = ModuleIndex(irModuleFragment)
|
||||||
|
|
||||||
@@ -109,6 +111,7 @@ class JsIrBackendContext(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun referenceOperators() = OperatorNames.ALL.map { name ->
|
private fun referenceOperators() = OperatorNames.ALL.map { name ->
|
||||||
|
// TODO to replace KotlinType with IrType we need right equals on IrType
|
||||||
name to irBuiltIns.primitiveTypes.fold(mutableMapOf<KotlinType, IrFunctionSymbol>()) { m, t ->
|
name to irBuiltIns.primitiveTypes.fold(mutableMapOf<KotlinType, IrFunctionSymbol>()) { m, t ->
|
||||||
val function = t.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).singleOrNull()
|
val function = t.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).singleOrNull()
|
||||||
function?.let { m.put(t, symbolTable.referenceSimpleFunction(it)) }
|
function?.let { m.put(t, symbolTable.referenceSimpleFunction(it)) }
|
||||||
|
|||||||
+15
-5
@@ -40,24 +40,28 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack
|
|||||||
false, false, variableDescriptor.isLateInit, variableDescriptor.source
|
false, false, variableDescriptor.isLateInit, variableDescriptor.source
|
||||||
)
|
)
|
||||||
|
|
||||||
val valueType = originalDeclaration.descriptor.type
|
val valueType = originalDeclaration.type
|
||||||
val boxConstructor = closureBoxConstructorTypeDescriptor
|
val boxConstructor = closureBoxConstructorTypeDescriptor
|
||||||
val boxConstructorSymbol = closureBoxConstructorTypeSymbol
|
val boxConstructorSymbol = closureBoxConstructorTypeSymbol
|
||||||
val constructorTypeParam = closureBoxConstructorTypeDescriptor.typeParameters[0]
|
|
||||||
val boxConstructorTypeArgument = mapOf(constructorTypeParam to valueType)
|
|
||||||
val initializer = originalDeclaration.initializer ?: IrConstImpl.constNull(
|
val initializer = originalDeclaration.initializer ?: IrConstImpl.constNull(
|
||||||
originalDeclaration.startOffset,
|
originalDeclaration.startOffset,
|
||||||
originalDeclaration.endOffset,
|
originalDeclaration.endOffset,
|
||||||
valueType
|
valueType
|
||||||
)
|
)
|
||||||
|
// TODO use buildCall?
|
||||||
val constructorCall = IrCallImpl(
|
val constructorCall = IrCallImpl(
|
||||||
originalDeclaration.startOffset,
|
originalDeclaration.startOffset,
|
||||||
originalDeclaration.endOffset,
|
originalDeclaration.endOffset,
|
||||||
|
// TODO wrong type
|
||||||
|
originalDeclaration.type,
|
||||||
boxConstructorSymbol,
|
boxConstructorSymbol,
|
||||||
boxConstructor,
|
boxConstructor,
|
||||||
boxConstructorTypeArgument,
|
1,
|
||||||
JsLoweredDeclarationOrigin.JS_CLOSURE_BOX_CLASS
|
JsLoweredDeclarationOrigin.JS_CLOSURE_BOX_CLASS
|
||||||
).apply { putValueArgument(0, initializer) }
|
).apply {
|
||||||
|
putTypeArgument(0, valueType)
|
||||||
|
putValueArgument(0, initializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return IrVariableImpl(
|
return IrVariableImpl(
|
||||||
@@ -65,6 +69,8 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack
|
|||||||
originalDeclaration.endOffset,
|
originalDeclaration.endOffset,
|
||||||
originalDeclaration.origin,
|
originalDeclaration.origin,
|
||||||
sharedVariableDescriptor,
|
sharedVariableDescriptor,
|
||||||
|
// TODO wrong type ?
|
||||||
|
originalDeclaration.type,
|
||||||
constructorCall
|
constructorCall
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -75,9 +81,11 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack
|
|||||||
IrGetFieldImpl(
|
IrGetFieldImpl(
|
||||||
originalGet.startOffset, originalGet.endOffset,
|
originalGet.startOffset, originalGet.endOffset,
|
||||||
closureBoxFieldSymbol,
|
closureBoxFieldSymbol,
|
||||||
|
originalGet.type,
|
||||||
IrGetValueImpl(
|
IrGetValueImpl(
|
||||||
originalGet.startOffset,
|
originalGet.startOffset,
|
||||||
originalGet.endOffset,
|
originalGet.endOffset,
|
||||||
|
originalGet.type,
|
||||||
sharedVariableSymbol
|
sharedVariableSymbol
|
||||||
),
|
),
|
||||||
originalGet.origin
|
originalGet.origin
|
||||||
@@ -90,9 +98,11 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack
|
|||||||
IrGetValueImpl(
|
IrGetValueImpl(
|
||||||
originalSet.startOffset,
|
originalSet.startOffset,
|
||||||
originalSet.endOffset,
|
originalSet.endOffset,
|
||||||
|
originalSet.type,
|
||||||
sharedVariableSymbol
|
sharedVariableSymbol
|
||||||
),
|
),
|
||||||
originalSet.value,
|
originalSet.value,
|
||||||
|
originalSet.type,
|
||||||
originalSet.origin
|
originalSet.origin
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ fun compile(
|
|||||||
moduleFragment
|
moduleFragment
|
||||||
)
|
)
|
||||||
|
|
||||||
ExternalDependenciesGenerator(psi2IrContext.symbolTable, psi2IrContext.irBuiltIns).generateUnboundSymbolsAsDependencies(moduleFragment)
|
ExternalDependenciesGenerator(psi2IrContext.moduleDescriptor, psi2IrContext.symbolTable, psi2IrContext.irBuiltIns)
|
||||||
|
.generateUnboundSymbolsAsDependencies(moduleFragment)
|
||||||
|
|
||||||
context.performInlining(moduleFragment)
|
context.performInlining(moduleFragment)
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class JsIrArithBuilder(val context: JsIrBackendContext) {
|
|||||||
fun inv(v: IrExpression): IrExpression = buildUnaryOperator(OperatorNames.INV, v)
|
fun inv(v: IrExpression): IrExpression = buildUnaryOperator(OperatorNames.INV, v)
|
||||||
|
|
||||||
fun andand(l: IrExpression, r: IrExpression) = // if (l) r else false
|
fun andand(l: IrExpression, r: IrExpression) = // if (l) r else false
|
||||||
JsIrBuilder.buildIfElse(context.builtIns.booleanType, l, r, JsIrBuilder.buildBoolean(context.builtIns.booleanType, false))
|
JsIrBuilder.buildIfElse(context.irBuiltIns.booleanType, l, r, JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false))
|
||||||
fun oror(l: IrExpression, r: IrExpression) = // if (l) true else r
|
fun oror(l: IrExpression, r: IrExpression) = // if (l) true else r
|
||||||
JsIrBuilder.buildIfElse(context.builtIns.booleanType, l, JsIrBuilder.buildBoolean(context.builtIns.booleanType, true), r)
|
JsIrBuilder.buildIfElse(context.irBuiltIns.booleanType, l, JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true), r)
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.ir
|
package org.jetbrains.kotlin.ir.backend.js.ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||||
@@ -15,76 +15,103 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
|||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
|
||||||
object JsIrBuilder {
|
object JsIrBuilder {
|
||||||
|
|
||||||
object SYNTHESIZED_STATEMENT : IrStatementOriginImpl("SYNTHESIZED_STATEMENT")
|
object SYNTHESIZED_STATEMENT : IrStatementOriginImpl("SYNTHESIZED_STATEMENT")
|
||||||
object SYNTHESIZED_DECLARATION : IrDeclarationOriginImpl("SYNTHESIZED_DECLARATION")
|
object SYNTHESIZED_DECLARATION : IrDeclarationOriginImpl("SYNTHESIZED_DECLARATION")
|
||||||
|
|
||||||
fun buildCall(target: IrFunctionSymbol, type: KotlinType? = null, typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null) =
|
fun buildCall(target: IrFunctionSymbol, type: IrType? = null, typeArguments: List<IrType>? = null): IrCall =
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
type ?: target.descriptor.returnType!!,
|
type ?: target.owner.returnType,
|
||||||
target,
|
target,
|
||||||
target.descriptor,
|
target.descriptor,
|
||||||
typeArguments,
|
target.owner.typeParameters.size,
|
||||||
SYNTHESIZED_STATEMENT
|
SYNTHESIZED_STATEMENT
|
||||||
)
|
).apply {
|
||||||
|
typeArguments?.let {
|
||||||
|
assert(typeArguments.size == typeArgumentsCount)
|
||||||
|
it.withIndex().forEach { (i, t) -> putTypeArgument(i, t) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun buildReturn(targetSymbol: IrFunctionSymbol, value: IrExpression) =
|
fun buildReturn(targetSymbol: IrFunctionSymbol, value: IrExpression, context: BackendContext) =
|
||||||
IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, targetSymbol, value)
|
IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.nothingType, targetSymbol, value)
|
||||||
|
|
||||||
fun buildThrow(type: KotlinType, value: IrExpression) = IrThrowImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, value)
|
fun buildThrow(type: IrType, value: IrExpression) = IrThrowImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, value)
|
||||||
|
|
||||||
fun buildValueParameter(symbol: IrValueParameterSymbol) =
|
fun buildValueParameter(symbol: IrValueParameterSymbol, type: IrType? = null) =
|
||||||
IrValueParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol)
|
IrValueParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol, type ?: symbol.owner.type, null)
|
||||||
|
|
||||||
fun buildFunction(symbol: IrSimpleFunctionSymbol) = IrFunctionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol)
|
fun buildFunction(symbol: IrSimpleFunctionSymbol, returnType: IrType) =
|
||||||
|
IrFunctionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol).apply {
|
||||||
|
this.returnType = returnType
|
||||||
|
}
|
||||||
|
|
||||||
fun buildGetObjectValue(type: KotlinType, classSymbol: IrClassSymbol) =
|
fun buildGetObjectValue(type: IrType, classSymbol: IrClassSymbol) =
|
||||||
IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, classSymbol)
|
IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, classSymbol)
|
||||||
|
|
||||||
fun buildGetClass(expression: IrExpression, type: KotlinType) = IrGetClassImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, expression)
|
fun buildGetClass(expression: IrExpression, type: IrType) = IrGetClassImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, expression)
|
||||||
|
|
||||||
fun buildGetValue(symbol: IrValueSymbol) = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, SYNTHESIZED_STATEMENT)
|
fun buildGetValue(symbol: IrValueSymbol) = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol.owner.type, symbol, SYNTHESIZED_STATEMENT)
|
||||||
fun buildSetVariable(symbol: IrVariableSymbol, value: IrExpression) =
|
fun buildSetVariable(symbol: IrVariableSymbol, value: IrExpression, type: IrType) =
|
||||||
IrSetVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, value, SYNTHESIZED_STATEMENT)
|
IrSetVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, symbol, value, SYNTHESIZED_STATEMENT)
|
||||||
|
|
||||||
fun buildGetField(symbol: IrFieldSymbol, receiver: IrExpression?, superQualifierSymbol: IrClassSymbol? = null) =
|
fun buildGetField(symbol: IrFieldSymbol, receiver: IrExpression?, superQualifierSymbol: IrClassSymbol? = null) =
|
||||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, receiver, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, symbol.owner.type, receiver, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
||||||
|
|
||||||
fun buildSetField(symbol: IrFieldSymbol, receiver: IrExpression?, value: IrExpression, superQualifierSymbol: IrClassSymbol? = null) =
|
fun buildSetField(symbol: IrFieldSymbol, receiver: IrExpression?, value: IrExpression, type: IrType, superQualifierSymbol: IrClassSymbol? = null) =
|
||||||
IrSetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, receiver, value, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
IrSetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, receiver, value, type, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
||||||
|
|
||||||
fun buildBlockBody(statements: List<IrStatement>) = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, statements)
|
fun buildBlockBody(statements: List<IrStatement>) = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, statements)
|
||||||
|
|
||||||
fun buildBlock(type: KotlinType) = IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT)
|
fun buildBlock(type: IrType) = IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT)
|
||||||
fun buildBlock(type: KotlinType, statements: List<IrStatement>) =
|
fun buildBlock(type: IrType, statements: List<IrStatement>) =
|
||||||
IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT, statements)
|
IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT, statements)
|
||||||
|
|
||||||
fun buildFunctionReference(type: KotlinType, symbol: IrFunctionSymbol) =
|
fun buildFunctionReference(type: IrType, symbol: IrFunctionSymbol) =
|
||||||
IrFunctionReferenceImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, symbol, symbol.descriptor)
|
IrFunctionReferenceImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, symbol, symbol.descriptor, 0, null)
|
||||||
|
|
||||||
fun buildVar(symbol: IrVariableSymbol, initializer: IrExpression? = null) =
|
fun buildVar(symbol: IrVariableSymbol, initializer: IrExpression? = null, type: IrType?) =
|
||||||
IrVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol).apply { this.initializer = initializer }
|
IrVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol, type ?: symbol.owner.type).apply { this.initializer = initializer }
|
||||||
|
|
||||||
fun buildBreak(type: KotlinType, loop: IrLoop) = IrBreakImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, loop)
|
fun buildBreak(type: IrType, loop: IrLoop) = IrBreakImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, loop)
|
||||||
fun buildContinue(type: KotlinType, loop: IrLoop) = IrContinueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, loop)
|
fun buildContinue(type: IrType, loop: IrLoop) = IrContinueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, loop)
|
||||||
|
|
||||||
fun buildIfElse(type: KotlinType, cond: IrExpression, thenBranch: IrExpression, elseBranch: IrExpression? = null) = IrIfThenElseImpl(
|
fun buildIfElse(type: IrType, cond: IrExpression, thenBranch: IrExpression, elseBranch: IrExpression? = null): IrWhen = buildIfElse(
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, cond, thenBranch, elseBranch, SYNTHESIZED_STATEMENT
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, cond, thenBranch, elseBranch, SYNTHESIZED_STATEMENT
|
||||||
)
|
)
|
||||||
|
|
||||||
fun buildWhen(type: KotlinType, branches: List<IrBranch>) =
|
fun buildIfElse(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
type: IrType,
|
||||||
|
cond: IrExpression,
|
||||||
|
thenBranch: IrExpression,
|
||||||
|
elseBranch: IrExpression? = null,
|
||||||
|
origin: IrStatementOrigin? = null
|
||||||
|
): IrWhen {
|
||||||
|
val element = IrIfThenElseImpl(startOffset, endOffset, type, origin)
|
||||||
|
element.branches.add(IrBranchImpl(cond, thenBranch))
|
||||||
|
if (elseBranch != null) {
|
||||||
|
val irTrue = IrConstImpl.boolean(UNDEFINED_OFFSET, UNDEFINED_OFFSET, cond.type, true)
|
||||||
|
element.branches.add(IrElseBranchImpl(irTrue, elseBranch))
|
||||||
|
}
|
||||||
|
|
||||||
|
return element
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildWhen(type: IrType, branches: List<IrBranch>) =
|
||||||
IrWhenImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT, branches)
|
IrWhenImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT, branches)
|
||||||
|
|
||||||
fun buildTypeOperator(type: KotlinType, operator: IrTypeOperator, argument: IrExpression, toType: KotlinType, symbol: IrClassifierSymbol) =
|
fun buildTypeOperator(type: IrType, operator: IrTypeOperator, argument: IrExpression, toType: IrType, symbol: IrClassifierSymbol) =
|
||||||
IrTypeOperatorCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, operator, toType, argument, symbol)
|
IrTypeOperatorCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, operator, toType, symbol, argument)
|
||||||
|
|
||||||
fun buildNull(type: KotlinType) = IrConstImpl.constNull(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type)
|
fun buildNull(type: IrType) = IrConstImpl.constNull(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type)
|
||||||
fun buildBoolean(type: KotlinType, v: Boolean) = IrConstImpl.boolean(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
fun buildBoolean(type: IrType, v: Boolean) = IrConstImpl.boolean(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
||||||
fun buildInt(type: KotlinType, v: Int) = IrConstImpl.int(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
fun buildInt(type: IrType, v: Int) = IrConstImpl.int(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
||||||
fun buildString(type: KotlinType, s: String) = IrConstImpl.string(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, s)
|
fun buildString(type: IrType, s: String) = IrConstImpl.string(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, s)
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-32
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
@@ -17,9 +16,11 @@ import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.isUnit
|
||||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
|
||||||
private typealias VisitData = Nothing?
|
private typealias VisitData = Nothing?
|
||||||
|
|
||||||
@@ -30,15 +31,20 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
private val statementVisitor = StatementVisitor()
|
private val statementVisitor = StatementVisitor()
|
||||||
private val expressionVisitor = ExpressionVisitor()
|
private val expressionVisitor = ExpressionVisitor()
|
||||||
|
|
||||||
private val constTrue = JsIrBuilder.buildBoolean(context.builtIns.booleanType, true)
|
private val constTrue = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true)
|
||||||
private val constFalse = JsIrBuilder.buildBoolean(context.builtIns.booleanType, false)
|
private val constFalse = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false)
|
||||||
private val nothingType = context.builtIns.nullableNothingType
|
private val nothingType get() = context.irBuiltIns.nothingType
|
||||||
|
private val unitType get() = context.irBuiltIns.unitType
|
||||||
|
|
||||||
private val unitType = context.builtIns.unitType
|
|
||||||
private val unitValue = JsIrBuilder.buildGetObjectValue(unitType, context.symbolTable.referenceClass(context.builtIns.unit))
|
private val unitValue = JsIrBuilder.buildGetObjectValue(unitType, context.symbolTable.referenceClass(context.builtIns.unit))
|
||||||
|
|
||||||
private val unreachableFunction =
|
private val unreachableFunction = JsIrBuilder.buildFunction(
|
||||||
JsSymbolBuilder.buildSimpleFunction(context.module, Namer.UNREACHABLE_NAME).initialize(type = nothingType)
|
JsSymbolBuilder.buildSimpleFunction(
|
||||||
|
context.module,
|
||||||
|
Namer.UNREACHABLE_NAME
|
||||||
|
).initialize(returnType = nothingType),
|
||||||
|
nothingType
|
||||||
|
)
|
||||||
|
|
||||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||||
irDeclarationContainer.declarations.transformFlat { declaration ->
|
irDeclarationContainer.declarations.transformFlat { declaration ->
|
||||||
@@ -61,17 +67,18 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
|
|
||||||
fun lower(irField: IrField, container: IrDeclarationContainer): List<IrDeclaration> {
|
fun lower(irField: IrField, container: IrDeclarationContainer): List<IrDeclaration> {
|
||||||
irField.initializer?.apply {
|
irField.initializer?.apply {
|
||||||
|
val returnType = expression.type
|
||||||
val initFnSymbol = JsSymbolBuilder.buildSimpleFunction(
|
val initFnSymbol = JsSymbolBuilder.buildSimpleFunction(
|
||||||
(container as IrSymbolOwner).symbol.descriptor,
|
(container as IrSymbolOwner).symbol.descriptor,
|
||||||
irField.name.asString() + "\$init\$"
|
irField.name.asString() + "\$init\$"
|
||||||
).initialize(type = expression.type)
|
).initialize(returnType = returnType)
|
||||||
|
|
||||||
|
|
||||||
val newBody = IrBlockBodyImpl(expression.startOffset, expression.endOffset).apply {
|
val newBody = IrBlockBodyImpl(expression.startOffset, expression.endOffset).apply {
|
||||||
statements += JsIrBuilder.buildReturn(initFnSymbol, expression)
|
statements += JsIrBuilder.buildReturn(initFnSymbol, expression, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
val initFn = JsIrBuilder.buildFunction(initFnSymbol).apply {
|
val initFn = JsIrBuilder.buildFunction(initFnSymbol, returnType).apply {
|
||||||
body = newBody
|
body = newBody
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,15 +321,15 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
expression.type,
|
expression.type,
|
||||||
expression.operator,
|
expression.operator,
|
||||||
expression.typeOperand,
|
expression.typeOperand,
|
||||||
resultValue,
|
expression.typeOperandClassifier,
|
||||||
expression.typeOperandClassifier
|
resultValue
|
||||||
)
|
)
|
||||||
|
|
||||||
val resValue: IrExpression
|
val resValue: IrExpression
|
||||||
|
|
||||||
if (!KotlinBuiltIns.isUnit(expression.type)) {
|
if (!expression.type.isUnit()) {
|
||||||
val resVar = makeTempVar(expression.type)
|
val resVar = makeTempVar(expression.type)
|
||||||
statements += JsIrBuilder.buildVar(resVar, newOperator)
|
statements += JsIrBuilder.buildVar(resVar, newOperator, type = expression.type)
|
||||||
resValue = JsIrBuilder.buildGetValue(resVar)
|
resValue = JsIrBuilder.buildGetValue(resVar)
|
||||||
} else {
|
} else {
|
||||||
statements += newOperator
|
statements += newOperator
|
||||||
@@ -364,7 +371,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needNew) {
|
if (needNew) {
|
||||||
newStatements += JsIrBuilder.buildSetField(expression.symbol, newReceiver, newValue, expression.superQualifierSymbol)
|
newStatements += JsIrBuilder.buildSetField(expression.symbol, newReceiver, newValue, unitType, expression.superQualifierSymbol)
|
||||||
return DecomposedResult(newStatements, unitValue)
|
return DecomposedResult(newStatements, unitValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,7 +382,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
val valueResult = expression.value.accept(expressionVisitor, data)
|
val valueResult = expression.value.accept(expressionVisitor, data)
|
||||||
|
|
||||||
return valueResult.runIfChanged {
|
return valueResult.runIfChanged {
|
||||||
statements += JsIrBuilder.buildSetVariable(expression.symbol, resultValue)
|
statements += JsIrBuilder.buildSetVariable(expression.symbol, resultValue, unitType)
|
||||||
DecomposedResult(statements, unitValue)
|
DecomposedResult(statements, unitValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,7 +407,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
// val x = x_tmp
|
// val x = x_tmp
|
||||||
override fun visitContainerExpression(expression: IrContainerExpression, data: VisitData): VisitResult {
|
override fun visitContainerExpression(expression: IrContainerExpression, data: VisitData): VisitResult {
|
||||||
val variable = makeTempVar(expression.type)
|
val variable = makeTempVar(expression.type)
|
||||||
val varDeclaration = JsIrBuilder.buildVar(variable)
|
val varDeclaration = JsIrBuilder.buildVar(variable, type = expression.type)
|
||||||
|
|
||||||
val blockStatements = expression.statements
|
val blockStatements = expression.statements
|
||||||
val lastStatement: IrStatement? = blockStatements.lastOrNull()
|
val lastStatement: IrStatement? = blockStatements.lastOrNull()
|
||||||
@@ -434,7 +441,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
collectingList += statements
|
collectingList += statements
|
||||||
resultValue
|
resultValue
|
||||||
}
|
}
|
||||||
collectingList += JsIrBuilder.buildSetVariable(variable, result)
|
collectingList += JsIrBuilder.buildSetVariable(variable, result, unitType)
|
||||||
if (body is IrComposite) {
|
if (body is IrComposite) {
|
||||||
DecomposedResult(mutableListOf(varDeclaration, *collectingList.toTypedArray()) , JsIrBuilder.buildGetValue(variable))
|
DecomposedResult(mutableListOf(varDeclaration, *collectingList.toTypedArray()) , JsIrBuilder.buildGetValue(variable))
|
||||||
} else {
|
} else {
|
||||||
@@ -463,7 +470,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
private fun prepareArgument(arg: IrExpression, needWrap: Boolean, statements: MutableList<IrStatement>): IrExpression {
|
private fun prepareArgument(arg: IrExpression, needWrap: Boolean, statements: MutableList<IrStatement>): IrExpression {
|
||||||
return if (needWrap) {
|
return if (needWrap) {
|
||||||
val wrapVar = makeTempVar(arg.type)
|
val wrapVar = makeTempVar(arg.type)
|
||||||
statements += JsIrBuilder.buildVar(wrapVar, arg)
|
statements += JsIrBuilder.buildVar(wrapVar, arg, type = arg.type)
|
||||||
JsIrBuilder.buildGetValue(wrapVar)
|
JsIrBuilder.buildGetValue(wrapVar)
|
||||||
} else arg
|
} else arg
|
||||||
}
|
}
|
||||||
@@ -543,21 +550,21 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
val resultVar = makeTempVar(expression.type)
|
val resultVar = makeTempVar(expression.type)
|
||||||
|
|
||||||
// TODO: get rid of temporary variable
|
// TODO: get rid of temporary variable
|
||||||
newStatements += JsIrBuilder.buildVar(resultVar, expression)
|
newStatements += JsIrBuilder.buildVar(resultVar, expression, type = expression.type)
|
||||||
|
|
||||||
return DecomposedResult(newStatements, JsIrBuilder.buildGetValue(resultVar))
|
return DecomposedResult(newStatements, JsIrBuilder.buildGetValue(resultVar))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitWhen(expression: IrWhen, data: VisitData): VisitResult {
|
override fun visitWhen(expression: IrWhen, data: VisitData): VisitResult {
|
||||||
val collectiveVar = makeTempVar(expression.type)
|
val collectiveVar = makeTempVar(expression.type)
|
||||||
val varDeclaration = JsIrBuilder.buildVar(collectiveVar)
|
val varDeclaration = JsIrBuilder.buildVar(collectiveVar, type = expression.type)
|
||||||
val newWhen = processWhen(expression, data, this, this) { visitResult, original ->
|
val newWhen = processWhen(expression, data, this, this) { visitResult, original ->
|
||||||
val resultList = mutableListOf<IrStatement>()
|
val resultList = mutableListOf<IrStatement>()
|
||||||
val newResult = visitResult.runIfChangedOrDefault(original as IrExpression) {
|
val newResult = visitResult.runIfChangedOrDefault(original as IrExpression) {
|
||||||
resultList += statements
|
resultList += statements
|
||||||
resultValue
|
resultValue
|
||||||
}
|
}
|
||||||
resultList.apply { add(JsIrBuilder.buildSetVariable(collectiveVar, newResult)) }
|
resultList.apply { add(JsIrBuilder.buildSetVariable(collectiveVar, newResult, unitType)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newWhen != expression) {
|
if (newWhen != expression) {
|
||||||
@@ -587,7 +594,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
resultValue
|
resultValue
|
||||||
}
|
}
|
||||||
val wrapVar = makeTempVar(expression.varargElementType)
|
val wrapVar = makeTempVar(expression.varargElementType)
|
||||||
newStatements += JsIrBuilder.buildVar(wrapVar).apply { initializer = newExpression }
|
newStatements += JsIrBuilder.buildVar(wrapVar, type = expression.type).apply { initializer = newExpression }
|
||||||
val newValue = JsIrBuilder.buildGetValue(wrapVar)
|
val newValue = JsIrBuilder.buildGetValue(wrapVar)
|
||||||
if (original is IrSpreadElement) {
|
if (original is IrSpreadElement) {
|
||||||
IrSpreadElementImpl(original.startOffset, original.endOffset, newValue)
|
IrSpreadElementImpl(original.startOffset, original.endOffset, newValue)
|
||||||
@@ -641,7 +648,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
|
|
||||||
newStatements += instantiater(returnValue)
|
newStatements += instantiater(returnValue)
|
||||||
|
|
||||||
return TerminatedResult(newStatements, JsIrBuilder.buildCall(unreachableFunction))
|
return TerminatedResult(newStatements, JsIrBuilder.buildCall(unreachableFunction.symbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -658,7 +665,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun visitBreakContinue(jump: IrBreakContinue, data: VisitData): VisitResult {
|
override fun visitBreakContinue(jump: IrBreakContinue, data: VisitData): VisitResult {
|
||||||
return DecomposedResult(jump, JsIrBuilder.buildCall(unreachableFunction))
|
return DecomposedResult(jump, JsIrBuilder.buildCall(unreachableFunction.symbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTry(aTry: IrTry, data: VisitData): VisitResult {
|
override fun visitTry(aTry: IrTry, data: VisitData): VisitResult {
|
||||||
@@ -669,10 +676,10 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
finallyResult?.run { assert(status == VisitStatus.KEPT) }
|
finallyResult?.run { assert(status == VisitStatus.KEPT) }
|
||||||
|
|
||||||
val resultSymbol = makeTempVar(aTry.type)
|
val resultSymbol = makeTempVar(aTry.type)
|
||||||
val resultDeclaration = JsIrBuilder.buildVar(resultSymbol)
|
val resultDeclaration = JsIrBuilder.buildVar(resultSymbol, type = aTry.type)
|
||||||
|
|
||||||
val newTryValue = tryResult.runIfChangedOrDefault(aTry.tryResult) { resultValue }
|
val newTryValue = tryResult.runIfChangedOrDefault(aTry.tryResult) { resultValue }
|
||||||
val trySetResult = JsIrBuilder.buildSetVariable(resultSymbol, newTryValue) as IrStatement
|
val trySetResult = JsIrBuilder.buildSetVariable(resultSymbol, newTryValue, unitType) as IrStatement
|
||||||
|
|
||||||
val tryBlock = IrBlockImpl(aTry.tryResult.startOffset, aTry.tryResult.endOffset, unitType).apply {
|
val tryBlock = IrBlockImpl(aTry.tryResult.startOffset, aTry.tryResult.endOffset, unitType).apply {
|
||||||
statements += tryResult.runIfChangedOrDefault(listOf(trySetResult)) { statements + trySetResult }
|
statements += tryResult.runIfChangedOrDefault(listOf(trySetResult)) { statements + trySetResult }
|
||||||
@@ -680,7 +687,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
|
|
||||||
val catchBlocks = catchResults.map { (original, result) ->
|
val catchBlocks = catchResults.map { (original, result) ->
|
||||||
val newCatchResult = result.runIfChangedOrDefault(original.result) { resultValue }
|
val newCatchResult = result.runIfChangedOrDefault(original.result) { resultValue }
|
||||||
val catchSetResult = JsIrBuilder.buildSetVariable(resultSymbol, newCatchResult) as IrStatement
|
val catchSetResult = JsIrBuilder.buildSetVariable(resultSymbol, newCatchResult, unitType) as IrStatement
|
||||||
val catchBlock = IrBlockImpl(original.result.startOffset, original.result.endOffset, unitType)
|
val catchBlock = IrBlockImpl(original.result.startOffset, original.result.endOffset, unitType)
|
||||||
catchBlock.statements += result.runIfChangedOrDefault(listOf(catchSetResult)) { statements + catchSetResult }
|
catchBlock.statements += result.runIfChangedOrDefault(listOf(catchSetResult)) { statements + catchSetResult }
|
||||||
IrCatchImpl(original.startOffset, original.endOffset, original.catchParameter, catchBlock)
|
IrCatchImpl(original.startOffset, original.endOffset, original.catchParameter, catchBlock)
|
||||||
@@ -713,7 +720,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun makeTempVar(type: KotlinType) =
|
fun makeTempVar(type: IrType) =
|
||||||
JsSymbolBuilder.buildTempVar(function.symbol, type, "tmp\$dcms\$${tmpVarCounter++}", true)
|
JsSymbolBuilder.buildTempVar(function.symbol, type, "tmp\$dcms\$${tmpVarCounter++}", true)
|
||||||
|
|
||||||
fun makeLoopLabel() = "\$l\$${tmpVarCounter++}"
|
fun makeLoopLabel() = "\$l\$${tmpVarCounter++}"
|
||||||
@@ -782,7 +789,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
|||||||
JsIrBuilder.buildBlock(unitType).also {
|
JsIrBuilder.buildBlock(unitType).also {
|
||||||
val elseBlock = if (originalBranch is IrElseBranch) null else it
|
val elseBlock = if (originalBranch is IrElseBranch) null else it
|
||||||
|
|
||||||
val ifElseNode = IrIfThenElseImpl(
|
val ifElseNode = JsIrBuilder.buildIfElse(
|
||||||
originalBranch.startOffset,
|
originalBranch.startOffset,
|
||||||
originalBranch.endOffset,
|
originalBranch.endOffset,
|
||||||
unitType,
|
unitType,
|
||||||
|
|||||||
+49
-29
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
|
import org.jetbrains.kotlin.ir.types.toIrType
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.visitors.*
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
|
|
||||||
@@ -39,9 +41,9 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
private val callableToGetterFunction = mutableMapOf<CallableReferenceKey, IrFunction>()
|
private val callableToGetterFunction = mutableMapOf<CallableReferenceKey, IrFunction>()
|
||||||
private val collectedReferenceMap = mutableMapOf<CallableReferenceKey, IrCallableReference>()
|
private val collectedReferenceMap = mutableMapOf<CallableReferenceKey, IrCallableReference>()
|
||||||
|
|
||||||
private val callableNameConst = JsIrBuilder.buildString(context.irBuiltIns.string, Namer.KCALLABLE_NAME)
|
private val callableNameConst = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KCALLABLE_NAME)
|
||||||
private val getterConst = JsIrBuilder.buildString(context.irBuiltIns.string, Namer.KPROPERTY_GET)
|
private val getterConst = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KPROPERTY_GET)
|
||||||
private val setterConst = JsIrBuilder.buildString(context.irBuiltIns.string, Namer.KPROPERTY_SET)
|
private val setterConst = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KPROPERTY_SET)
|
||||||
|
|
||||||
private val newDeclarations = mutableListOf<IrDeclaration>()
|
private val newDeclarations = mutableListOf<IrDeclaration>()
|
||||||
|
|
||||||
@@ -97,7 +99,13 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun redirectToFunction(callable: IrCallableReference, newTarget: IrFunction) =
|
private fun redirectToFunction(callable: IrCallableReference, newTarget: IrFunction) =
|
||||||
IrCallImpl(callable.startOffset, callable.endOffset, newTarget.symbol, callable.origin).apply {
|
IrCallImpl(
|
||||||
|
callable.startOffset, callable.endOffset,
|
||||||
|
newTarget.symbol.owner.returnType,
|
||||||
|
newTarget.symbol,
|
||||||
|
newTarget.symbol.descriptor,
|
||||||
|
callable.origin
|
||||||
|
).apply {
|
||||||
copyTypeArgumentsFrom(callable)
|
copyTypeArgumentsFrom(callable)
|
||||||
var index = 0
|
var index = 0
|
||||||
callable.dispatchReceiver?.let { putValueArgument(index++, it) }
|
callable.dispatchReceiver?.let { putValueArgument(index++, it) }
|
||||||
@@ -156,13 +164,13 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
val additionalDeclarations = generateGetterBodyWithGuard(refGetFunction) {
|
val additionalDeclarations = generateGetterBodyWithGuard(refGetFunction) {
|
||||||
val irClosureReference = JsIrBuilder.buildFunctionReference(functionReference.type, refClosureFunction.symbol)
|
val irClosureReference = JsIrBuilder.buildFunctionReference(functionReference.type, refClosureFunction.symbol)
|
||||||
val irVarSymbol = JsSymbolBuilder.buildTempVar(refGetFunction.symbol, irClosureReference.type)
|
val irVarSymbol = JsSymbolBuilder.buildTempVar(refGetFunction.symbol, irClosureReference.type)
|
||||||
val irVar = JsIrBuilder.buildVar(irVarSymbol, irClosureReference)
|
val irVar = JsIrBuilder.buildVar(irVarSymbol, irClosureReference, type = irClosureReference.type)
|
||||||
|
|
||||||
// TODO: fill other fields of callable reference (returnType, parameters, isFinal, etc.)
|
// TODO: fill other fields of callable reference (returnType, parameters, isFinal, etc.)
|
||||||
val irSetName = JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
val irSetName = JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||||
putValueArgument(1, callableNameConst)
|
putValueArgument(1, callableNameConst)
|
||||||
putValueArgument(2, JsIrBuilder.buildString(context.irBuiltIns.string, getReferenceName(declaration.descriptor)))
|
putValueArgument(2, JsIrBuilder.buildString(context.irBuiltIns.stringType, getReferenceName(declaration.descriptor)))
|
||||||
}
|
}
|
||||||
Pair(listOf(irVar, irSetName), irVarSymbol)
|
Pair(listOf(irVar, irSetName), irVarSymbol)
|
||||||
}
|
}
|
||||||
@@ -203,10 +211,11 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
val statements = mutableListOf<IrStatement>()
|
val statements = mutableListOf<IrStatement>()
|
||||||
|
|
||||||
val getterFunctionType = context.builtIns.getFunction(getterFunction.valueParameters.size + 1)
|
val getterFunctionType = context.builtIns.getFunction(getterFunction.valueParameters.size + 1)
|
||||||
val irGetReference = JsIrBuilder.buildFunctionReference(getterFunctionType.defaultType, getterFunction.symbol)
|
val type = getterFunctionType.toIrType()
|
||||||
val irVarSymbol = JsSymbolBuilder.buildTempVar(refGetFunction.symbol, getterFunctionType.defaultType)
|
val irGetReference = JsIrBuilder.buildFunctionReference(type, getterFunction.symbol)
|
||||||
|
val irVarSymbol = JsSymbolBuilder.buildTempVar(refGetFunction.symbol, type)
|
||||||
|
|
||||||
statements += JsIrBuilder.buildVar(irVarSymbol, irGetReference)
|
statements += JsIrBuilder.buildVar(irVarSymbol, irGetReference, type = type)
|
||||||
|
|
||||||
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||||
@@ -216,7 +225,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
|
|
||||||
if (setterFunction != null) {
|
if (setterFunction != null) {
|
||||||
val setterFunctionType = context.builtIns.getFunction(setterFunction.valueParameters.size + 1)
|
val setterFunctionType = context.builtIns.getFunction(setterFunction.valueParameters.size + 1)
|
||||||
val irSetReference = JsIrBuilder.buildFunctionReference(setterFunctionType.defaultType, setterFunction.symbol)
|
val irSetReference = JsIrBuilder.buildFunctionReference(setterFunctionType.toIrType(), setterFunction.symbol)
|
||||||
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||||
putValueArgument(1, setterConst)
|
putValueArgument(1, setterConst)
|
||||||
@@ -228,7 +237,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||||
putValueArgument(1, callableNameConst)
|
putValueArgument(1, callableNameConst)
|
||||||
putValueArgument(2, JsIrBuilder.buildString(context.irBuiltIns.string, getReferenceName(propertyReference.descriptor)))
|
putValueArgument(2, JsIrBuilder.buildString(context.irBuiltIns.stringType, getReferenceName(propertyReference.descriptor)))
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair(statements, irVarSymbol)
|
Pair(statements, irVarSymbol)
|
||||||
@@ -255,22 +264,23 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
val cacheName = "${getterFunction.name}_${Namer.KCALLABLE_CACHE_SUFFIX}"
|
val cacheName = "${getterFunction.name}_${Namer.KCALLABLE_CACHE_SUFFIX}"
|
||||||
|
val type = getterFunction.returnType
|
||||||
val cacheVarSymbol =
|
val cacheVarSymbol =
|
||||||
JsSymbolBuilder.buildVar(getterFunction.descriptor.containingDeclaration, getterFunction.returnType, cacheName, true)
|
JsSymbolBuilder.buildVar(getterFunction.descriptor.containingDeclaration, type, cacheName, true)
|
||||||
val irNull = JsIrBuilder.buildNull(cacheVarSymbol.descriptor.type)
|
val irNull = JsIrBuilder.buildNull(context.irBuiltIns.nothingNType)
|
||||||
val irCacheDeclaration = JsIrBuilder.buildVar(cacheVarSymbol)
|
val irCacheDeclaration = JsIrBuilder.buildVar(cacheVarSymbol, irNull, type = type)
|
||||||
val irCacheValue = JsIrBuilder.buildGetValue(cacheVarSymbol)
|
val irCacheValue = JsIrBuilder.buildGetValue(cacheVarSymbol)
|
||||||
val irIfCondition = JsIrBuilder.buildCall(context.irBuiltIns.eqeqSymbol).apply {
|
val irIfCondition = JsIrBuilder.buildCall(context.irBuiltIns.eqeqSymbol).apply {
|
||||||
putValueArgument(0, irCacheValue)
|
putValueArgument(0, irCacheValue)
|
||||||
putValueArgument(1, irNull)
|
putValueArgument(1, irNull)
|
||||||
}
|
}
|
||||||
val irSetCache = JsIrBuilder.buildSetVariable(cacheVarSymbol, JsIrBuilder.buildGetValue(varSymbol))
|
val irSetCache = JsIrBuilder.buildSetVariable(cacheVarSymbol, JsIrBuilder.buildGetValue(varSymbol), context.irBuiltIns.unitType)
|
||||||
val thenStatements = mutableListOf<IrStatement>().apply {
|
val thenStatements = mutableListOf<IrStatement>().apply {
|
||||||
addAll(bodyStatements)
|
addAll(bodyStatements)
|
||||||
add(irSetCache)
|
add(irSetCache)
|
||||||
}
|
}
|
||||||
val irThenBranch = JsIrBuilder.buildBlock(context.irBuiltIns.unit, thenStatements)
|
val irThenBranch = JsIrBuilder.buildBlock(context.irBuiltIns.unitType, thenStatements)
|
||||||
val irIfNode = JsIrBuilder.buildIfElse(context.irBuiltIns.unit, irIfCondition, irThenBranch)
|
val irIfNode = JsIrBuilder.buildIfElse(context.irBuiltIns.unitType, irIfCondition, irThenBranch)
|
||||||
statements += irIfNode
|
statements += irIfNode
|
||||||
returnValue = irCacheValue
|
returnValue = irCacheValue
|
||||||
returnStatements = listOf(irCacheDeclaration)
|
returnStatements = listOf(irCacheDeclaration)
|
||||||
@@ -280,7 +290,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
returnStatements = emptyList()
|
returnStatements = emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
statements += JsIrBuilder.buildReturn(getterFunction.symbol, returnValue)
|
statements += JsIrBuilder.buildReturn(getterFunction.symbol, returnValue, context)
|
||||||
|
|
||||||
getterFunction.body = JsIrBuilder.buildBlockBody(statements)
|
getterFunction.body = JsIrBuilder.buildBlockBody(statements)
|
||||||
return returnStatements
|
return returnStatements
|
||||||
@@ -314,8 +324,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
private fun buildGetFunction(declaration: IrFunction, reference: IrCallableReference, getterName: String): IrSimpleFunction {
|
private fun buildGetFunction(declaration: IrFunction, reference: IrCallableReference, getterName: String): IrSimpleFunction {
|
||||||
|
|
||||||
val callableType = reference.type
|
val callableType = reference.type
|
||||||
val closureParams = callableType.arguments.dropLast(1) // drop return type
|
var kFunctionValueParamsCount = (callableType as? IrSimpleType)?.arguments?.size?.minus(1) ?: 0
|
||||||
var kFunctionValueParamsCount = closureParams.size
|
|
||||||
|
|
||||||
if (declaration.dispatchReceiverParameter != null && reference.dispatchReceiver == null) {
|
if (declaration.dispatchReceiverParameter != null && reference.dispatchReceiver == null) {
|
||||||
kFunctionValueParamsCount--
|
kFunctionValueParamsCount--
|
||||||
@@ -342,14 +351,22 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
val refGetSymbol = JsSymbolBuilder.buildSimpleFunction(declaration.descriptor.containingDeclaration, getterName).apply {
|
val refGetSymbol = JsSymbolBuilder.buildSimpleFunction(declaration.descriptor.containingDeclaration, getterName).apply {
|
||||||
initialize(
|
initialize(
|
||||||
valueParameters = getterValueParameters.mapIndexed { i, p -> p.descriptor.copyAsValueParameter(descriptor, i) },
|
valueParameters = getterValueParameters.mapIndexed { i, p -> p.descriptor.copyAsValueParameter(descriptor, i) },
|
||||||
type = callableType
|
returnType = callableType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return JsIrBuilder.buildFunction(refGetSymbol).apply {
|
return JsIrBuilder.buildFunction(refGetSymbol, callableType).apply {
|
||||||
for (i in 0 until getterValueParameters.size) {
|
for (i in 0 until getterValueParameters.size) {
|
||||||
val p = getterValueParameters[i]
|
val p = getterValueParameters[i]
|
||||||
valueParameters += IrValueParameterImpl(p.startOffset, p.endOffset, p.origin, refGetSymbol.descriptor.valueParameters[i])
|
valueParameters +=
|
||||||
|
IrValueParameterImpl(
|
||||||
|
p.startOffset,
|
||||||
|
p.endOffset,
|
||||||
|
p.origin,
|
||||||
|
refGetSymbol.descriptor.valueParameters[i],
|
||||||
|
p.type,
|
||||||
|
p.varargElementType
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,15 +383,18 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
val closureParamSymbols = generateSignatureForClosure(declaration, refGetFunction, refClosureSymbol, reference)
|
val closureParamSymbols = generateSignatureForClosure(declaration, refGetFunction, refClosureSymbol, reference)
|
||||||
val closureParamDescriptors = closureParamSymbols.map { it.descriptor as ValueParameterDescriptor }
|
val closureParamDescriptors = closureParamSymbols.map { it.descriptor as ValueParameterDescriptor }
|
||||||
|
|
||||||
refClosureSymbol.initialize(valueParameters = closureParamDescriptors, type = declaration.returnType)
|
val returnType = declaration.returnType
|
||||||
|
refClosureSymbol.initialize(valueParameters = closureParamDescriptors, returnType = returnType)
|
||||||
|
|
||||||
val closureFunction = JsIrBuilder.buildFunction(refClosureSymbol)
|
val closureFunction = JsIrBuilder.buildFunction(refClosureSymbol, returnType)
|
||||||
|
|
||||||
for (it in closureParamSymbols) {
|
for (param in closureParamSymbols) {
|
||||||
closureFunction.valueParameters += JsIrBuilder.buildValueParameter(it)
|
// TODO always take type from param
|
||||||
|
val type = if (param.isBound) param.owner.type else context.irBuiltIns.anyType
|
||||||
|
closureFunction.valueParameters += JsIrBuilder.buildValueParameter(param, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
val irCall = JsIrBuilder.buildCall(declaration.symbol)
|
val irCall = JsIrBuilder.buildCall(declaration.symbol, type = returnType)
|
||||||
|
|
||||||
var cp = 0
|
var cp = 0
|
||||||
var gp = 0
|
var gp = 0
|
||||||
@@ -401,7 +421,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
|||||||
irCall.putValueArgument(j++, JsIrBuilder.buildGetValue(closureParamSymbols[i]))
|
irCall.putValueArgument(j++, JsIrBuilder.buildGetValue(closureParamSymbols[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
val irClosureReturn = JsIrBuilder.buildReturn(closureFunction.symbol, irCall)
|
val irClosureReturn = JsIrBuilder.buildReturn(closureFunction.symbol, irCall, context)
|
||||||
|
|
||||||
closureFunction.body = JsIrBuilder.buildBlockBody(listOf(irClosureReturn))
|
closureFunction.body = JsIrBuilder.buildBlockBody(listOf(irClosureReturn))
|
||||||
|
|
||||||
|
|||||||
+34
-19
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOfClass
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||||
@@ -19,10 +19,10 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|||||||
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
|
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.SimpleType
|
import org.jetbrains.kotlin.types.SimpleType
|
||||||
|
|
||||||
class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileLoweringPass {
|
class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileLoweringPass {
|
||||||
@@ -33,16 +33,13 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
private val symbolToIrFunction: Map<IrFunctionSymbol, IrSimpleFunction>
|
private val symbolToIrFunction: Map<IrFunctionSymbol, IrSimpleFunction>
|
||||||
private val nameToIrTransformer: Map<Name, (IrCall) -> IrCall>
|
private val nameToIrTransformer: Map<Name, (IrCall) -> IrCall>
|
||||||
|
|
||||||
val kCallable = context.builtIns.getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.kCallable.toSafe())
|
|
||||||
val kProperty = context.builtIns.getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.kProperty.asSingleFqName())
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
memberToIrFunction = mutableMapOf()
|
memberToIrFunction = mutableMapOf()
|
||||||
symbolToIrFunction = mutableMapOf()
|
symbolToIrFunction = mutableMapOf()
|
||||||
memberToTransformer = mutableMapOf()
|
memberToTransformer = mutableMapOf()
|
||||||
nameToIrTransformer = mutableMapOf()
|
nameToIrTransformer = mutableMapOf()
|
||||||
|
|
||||||
val primitiveNumbers = context.irBuiltIns.run { listOf(int, short, byte, float, double) }
|
val primitiveNumbers = context.irBuiltIns.run { listOf(intType, shortType, byteType, floatType, doubleType) }
|
||||||
|
|
||||||
memberToIrFunction.run {
|
memberToIrFunction.run {
|
||||||
for (type in primitiveNumbers) {
|
for (type in primitiveNumbers) {
|
||||||
@@ -57,11 +54,11 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
op(type, OperatorNames.REM, context.intrinsics.jsMod)
|
op(type, OperatorNames.REM, context.intrinsics.jsMod)
|
||||||
}
|
}
|
||||||
|
|
||||||
context.irBuiltIns.string.let {
|
context.irBuiltIns.stringType.let {
|
||||||
op(it, OperatorNames.ADD, context.intrinsics.jsPlus)
|
op(it, OperatorNames.ADD, context.intrinsics.jsPlus)
|
||||||
}
|
}
|
||||||
|
|
||||||
context.irBuiltIns.int.let {
|
context.irBuiltIns.intType.let {
|
||||||
op(it, OperatorNames.SHL, context.intrinsics.jsBitShiftL)
|
op(it, OperatorNames.SHL, context.intrinsics.jsBitShiftL)
|
||||||
op(it, OperatorNames.SHR, context.intrinsics.jsBitShiftR)
|
op(it, OperatorNames.SHR, context.intrinsics.jsBitShiftR)
|
||||||
op(it, OperatorNames.SHRU, context.intrinsics.jsBitShiftRU)
|
op(it, OperatorNames.SHRU, context.intrinsics.jsBitShiftRU)
|
||||||
@@ -71,7 +68,7 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
op(it, OperatorNames.INV, context.intrinsics.jsBitNot)
|
op(it, OperatorNames.INV, context.intrinsics.jsBitNot)
|
||||||
}
|
}
|
||||||
|
|
||||||
context.irBuiltIns.bool.let {
|
context.irBuiltIns.booleanType.let {
|
||||||
op(it, OperatorNames.AND, context.intrinsics.jsBitAnd)
|
op(it, OperatorNames.AND, context.intrinsics.jsBitAnd)
|
||||||
op(it, OperatorNames.OR, context.intrinsics.jsBitOr)
|
op(it, OperatorNames.OR, context.intrinsics.jsBitOr)
|
||||||
op(it, OperatorNames.NOT, context.intrinsics.jsNot)
|
op(it, OperatorNames.NOT, context.intrinsics.jsNot)
|
||||||
@@ -99,12 +96,12 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
// TODO: use increment and decrement when it's possible
|
// TODO: use increment and decrement when it's possible
|
||||||
op(type, OperatorNames.INC) {
|
op(type, OperatorNames.INC) {
|
||||||
irCall(it, context.intrinsics.jsPlus.symbol, dispatchReceiverAsFirstArgument = true).apply {
|
irCall(it, context.intrinsics.jsPlus.symbol, dispatchReceiverAsFirstArgument = true).apply {
|
||||||
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.int, 1))
|
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
op(type, OperatorNames.DEC) {
|
op(type, OperatorNames.DEC) {
|
||||||
irCall(it, context.intrinsics.jsMinus.symbol, dispatchReceiverAsFirstArgument = true).apply {
|
irCall(it, context.intrinsics.jsMinus.symbol, dispatchReceiverAsFirstArgument = true).apply {
|
||||||
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.int, 1))
|
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,18 +110,18 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
nameToIrTransformer.run {
|
nameToIrTransformer.run {
|
||||||
addWithPredicate(
|
addWithPredicate(
|
||||||
Name.special(Namer.KCALLABLE_GET_NAME),
|
Name.special(Namer.KCALLABLE_GET_NAME),
|
||||||
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { DescriptorUtils.isSubtypeOfClass(type, kCallable) } ?: false },
|
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kCallableClass) } ?: false },
|
||||||
{ call -> irCall(call, context.intrinsics.jsName.symbol, dispatchReceiverAsFirstArgument = true) })
|
{ call -> irCall(call, context.intrinsics.jsName.symbol, dispatchReceiverAsFirstArgument = true) })
|
||||||
|
|
||||||
addWithPredicate(
|
addWithPredicate(
|
||||||
Name.identifier(Namer.KPROPERTY_GET),
|
Name.identifier(Namer.KPROPERTY_GET),
|
||||||
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { DescriptorUtils.isSubtypeOfClass(type, kProperty) } ?: false },
|
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false },
|
||||||
{ call -> irCall(call, context.intrinsics.jsPropertyGet.symbol, dispatchReceiverAsFirstArgument = true)}
|
{ call -> irCall(call, context.intrinsics.jsPropertyGet.symbol, dispatchReceiverAsFirstArgument = true)}
|
||||||
)
|
)
|
||||||
|
|
||||||
addWithPredicate(
|
addWithPredicate(
|
||||||
Name.identifier(Namer.KPROPERTY_SET),
|
Name.identifier(Namer.KPROPERTY_SET),
|
||||||
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { DescriptorUtils.isSubtypeOfClass(type, kProperty) } ?: false},
|
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false},
|
||||||
{ call -> irCall(call, context.intrinsics.jsPropertySet.symbol, dispatchReceiverAsFirstArgument = true)}
|
{ call -> irCall(call, context.intrinsics.jsPropertySet.symbol, dispatchReceiverAsFirstArgument = true)}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -207,12 +204,11 @@ private fun IrCall.copyTypeAndValueArgumentsFrom(call: IrCall, dispatchReceiverA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <V> MutableMap<SimpleMemberKey, V>.op(type: KotlinType, name: Name, v: V) {
|
private fun <V> MutableMap<SimpleMemberKey, V>.op(type: IrType, name: Name, v: V) {
|
||||||
put(SimpleMemberKey(type, name), v)
|
put(SimpleMemberKey(type, name), v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO issue: marked as unused, but used; rename works wrongly.
|
private fun <V> MutableMap<SimpleMemberKey, V>.op(type: IrType, name: String, v: V) {
|
||||||
private fun <V> MutableMap<SimpleMemberKey, V>.op(type: KotlinType, name: String, v: V) {
|
|
||||||
put(SimpleMemberKey(type, Name.identifier(name)), v)
|
put(SimpleMemberKey(type, Name.identifier(name)), v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,4 +228,23 @@ private fun <K> MutableMap<K, (IrCall) -> IrCall>.addWithPredicate(from: K, pred
|
|||||||
|
|
||||||
private inline fun <T> select(crossinline predicate: () -> Boolean, crossinline ifTrue: () -> T, crossinline ifFalse: () -> T): T = if (predicate()) ifTrue() else ifFalse()
|
private inline fun <T> select(crossinline predicate: () -> Boolean, crossinline ifTrue: () -> T, crossinline ifFalse: () -> T): T = if (predicate()) ifTrue() else ifFalse()
|
||||||
|
|
||||||
private data class SimpleMemberKey(val klass: KotlinType, val name: Name)
|
private class SimpleMemberKey(val klass: IrType, val name: Name) {
|
||||||
|
// TODO drop custom equals and hashCode when IrTypes will have right equals
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as SimpleMemberKey
|
||||||
|
|
||||||
|
if (name != other.name) return false
|
||||||
|
if (klass.originalKotlinType != other.klass.originalKotlinType) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = klass.originalKotlinType?.hashCode() ?: 0
|
||||||
|
result = 31 * result + name.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+23
-19
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.utils.commonSupertype
|
||||||
|
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
@@ -18,11 +20,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCatchImpl
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrElseBranchImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrElseBranchImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrDynamicType
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.types.CommonSupertypes
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.isDynamic
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Since JS does not support multiple catch blocks by default we should replace them with similar `when` statement, so
|
* Since JS does not support multiple catch blocks by default we should replace them with similar `when` statement, so
|
||||||
@@ -49,9 +50,9 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||||
val litTrue = JsIrBuilder.buildBoolean(context.irBuiltIns.bool, true)
|
val litTrue = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true)
|
||||||
val unitType = context.irBuiltIns.unit
|
val unitType = context.irBuiltIns.unitType
|
||||||
val nothingType = context.irBuiltIns.nothing
|
val nothingType = context.irBuiltIns.nothingType
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildren(object : IrElementTransformer<IrDeclaration?> {
|
irFile.transformChildren(object : IrElementTransformer<IrDeclaration?> {
|
||||||
@@ -67,7 +68,7 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas
|
|||||||
val commonType = mergeTypes(aTry.catches.map { it.catchParameter.type })
|
val commonType = mergeTypes(aTry.catches.map { it.catchParameter.type })
|
||||||
|
|
||||||
val pendingExceptionSymbol = JsSymbolBuilder.buildVar(data!!.descriptor, commonType, "\$pending\$", false)
|
val pendingExceptionSymbol = JsSymbolBuilder.buildVar(data!!.descriptor, commonType, "\$pending\$", false)
|
||||||
val pendingExceptionDeclaration = JsIrBuilder.buildVar(pendingExceptionSymbol)
|
val pendingExceptionDeclaration = JsIrBuilder.buildVar(pendingExceptionSymbol, type = commonType)
|
||||||
val pendingException = JsIrBuilder.buildGetValue(pendingExceptionSymbol)
|
val pendingException = JsIrBuilder.buildGetValue(pendingExceptionSymbol)
|
||||||
|
|
||||||
val branches = mutableListOf<IrBranch>()
|
val branches = mutableListOf<IrBranch>()
|
||||||
@@ -75,24 +76,27 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas
|
|||||||
for (catch in aTry.catches) {
|
for (catch in aTry.catches) {
|
||||||
assert(!catch.catchParameter.isVar) { "caught exception parameter has to immutable" }
|
assert(!catch.catchParameter.isVar) { "caught exception parameter has to immutable" }
|
||||||
val type = catch.catchParameter.type
|
val type = catch.catchParameter.type
|
||||||
val typeSymbol = context.symbolTable.referenceClassifier(type.constructor.declarationDescriptor!!)
|
val typeSymbol = type.classifierOrNull
|
||||||
val castedPendingException = buildImplicitCast(pendingException, type, typeSymbol)
|
|
||||||
val catchBody = catch.result.transform(object : IrElementTransformer<VariableDescriptor> {
|
val catchBody = catch.result.transform(object : IrElementTransformer<VariableDescriptor> {
|
||||||
override fun visitGetValue(expression: IrGetValue, data: VariableDescriptor) =
|
override fun visitGetValue(expression: IrGetValue, data: VariableDescriptor) =
|
||||||
if (expression.descriptor == data) castedPendingException else expression
|
if (typeSymbol != null && expression.descriptor == data)
|
||||||
|
// TODO how is it good to generate implicit cast for each access?
|
||||||
|
buildImplicitCast(pendingException, type, typeSymbol)
|
||||||
|
else
|
||||||
|
expression
|
||||||
}, catch.parameter)
|
}, catch.parameter)
|
||||||
|
|
||||||
if (type.isDynamic()) {
|
if (type is IrDynamicType) {
|
||||||
branches += IrElseBranchImpl(catch.startOffset, catch.endOffset, litTrue, catchBody)
|
branches += IrElseBranchImpl(catch.startOffset, catch.endOffset, litTrue, catchBody)
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
val typeCheck = buildIsCheck(pendingException, type, typeSymbol)
|
val typeCheck = buildIsCheck(pendingException, type, typeSymbol!!)
|
||||||
branches += IrBranchImpl(catch.startOffset, catch.endOffset, typeCheck, catchBody)
|
branches += IrBranchImpl(catch.startOffset, catch.endOffset, typeCheck, catchBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!commonType.isDynamic()) {
|
if (commonType !is IrDynamicType) {
|
||||||
val throwStatement = JsIrBuilder.buildThrow(nothingType, pendingException)
|
val throwStatement = JsIrBuilder.buildThrow(nothingType, pendingException)
|
||||||
branches += IrElseBranchImpl(litTrue, JsIrBuilder.buildBlock(nothingType, listOf(throwStatement)))
|
branches += IrElseBranchImpl(litTrue, JsIrBuilder.buildBlock(nothingType, listOf(throwStatement)))
|
||||||
}
|
}
|
||||||
@@ -106,14 +110,14 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas
|
|||||||
return aTry.run { IrTryImpl(startOffset, endOffset, type, tryResult, listOf(newCatch), finallyExpression) }
|
return aTry.run { IrTryImpl(startOffset, endOffset, type, tryResult, listOf(newCatch), finallyExpression) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildIsCheck(value: IrExpression, toType: KotlinType, toTypeSymbol: IrClassifierSymbol) =
|
private fun buildIsCheck(value: IrExpression, toType: IrType, toTypeSymbol: IrClassifierSymbol) =
|
||||||
JsIrBuilder.buildTypeOperator(context.irBuiltIns.bool, IrTypeOperator.INSTANCEOF, value, toType, toTypeSymbol)
|
JsIrBuilder.buildTypeOperator(context.irBuiltIns.booleanType, IrTypeOperator.INSTANCEOF, value, toType, toTypeSymbol)
|
||||||
|
|
||||||
private fun buildImplicitCast(value: IrExpression, toType: KotlinType, toTypeSymbol: IrClassifierSymbol) =
|
private fun buildImplicitCast(value: IrExpression, toType: IrType, toTypeSymbol: IrClassifierSymbol) =
|
||||||
JsIrBuilder.buildTypeOperator(toType, IrTypeOperator.IMPLICIT_CAST, value, toType, toTypeSymbol)
|
JsIrBuilder.buildTypeOperator(toType, IrTypeOperator.IMPLICIT_CAST, value, toType, toTypeSymbol)
|
||||||
|
|
||||||
private fun mergeTypes(types: List<KotlinType>) = CommonSupertypes.commonSupertype(types).also {
|
private fun mergeTypes(types: List<IrType>) = types.commonSupertype().also {
|
||||||
assert(it.isSubtypeOf(context.builtIns.throwable.defaultType) || it.isDynamic())
|
assert(it.isSubtypeOf(context.irBuiltIns.throwableType) || it is IrDynamicType)
|
||||||
}
|
}
|
||||||
|
|
||||||
}, null)
|
}, null)
|
||||||
|
|||||||
+26
-16
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
@@ -72,8 +74,9 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
|||||||
// val t = Object.create(Foo.prototype);
|
// val t = Object.create(Foo.prototype);
|
||||||
// return Foo_init_$Init$(..., t)
|
// return Foo_init_$Init$(..., t)
|
||||||
// }
|
// }
|
||||||
val newInitConstructor = createInitConstructor(declaration, constructorName)
|
|
||||||
val newCreateConstructor = createCreateConstructor(declaration, newInitConstructor, constructorName)
|
val newInitConstructor = createInitConstructor(declaration, constructorName, irClass.defaultType)
|
||||||
|
val newCreateConstructor = createCreateConstructor(declaration, newInitConstructor, constructorName, irClass.defaultType)
|
||||||
|
|
||||||
oldCtorToNewMap[declaration.symbol] =
|
oldCtorToNewMap[declaration.symbol] =
|
||||||
JsIrBackendContext.SecondaryCtorPair(newInitConstructor.symbol, newCreateConstructor.symbol)
|
JsIrBackendContext.SecondaryCtorPair(newInitConstructor.symbol, newCreateConstructor.symbol)
|
||||||
@@ -95,14 +98,16 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
|||||||
override fun visitReturn(expression: IrReturn): IrExpression = IrReturnImpl(
|
override fun visitReturn(expression: IrReturn): IrExpression = IrReturnImpl(
|
||||||
expression.startOffset,
|
expression.startOffset,
|
||||||
expression.endOffset,
|
expression.endOffset,
|
||||||
|
expression.type,
|
||||||
function,
|
function,
|
||||||
IrGetValueImpl(expression.startOffset, expression.endOffset, thisSymbol)
|
IrGetValueImpl(expression.startOffset, expression.endOffset, thisSymbol.owner.type, thisSymbol)
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression =
|
override fun visitGetValue(expression: IrGetValue): IrExpression =
|
||||||
if (expression.descriptor.name.isSpecial && expression.descriptor.name.asString() == Namer.THIS_SPECIAL_NAME) IrGetValueImpl(
|
if (expression.descriptor.name.isSpecial && expression.descriptor.name.asString() == Namer.THIS_SPECIAL_NAME) IrGetValueImpl(
|
||||||
expression.startOffset,
|
expression.startOffset,
|
||||||
expression.endOffset,
|
expression.endOffset,
|
||||||
|
expression.type,
|
||||||
thisSymbol,
|
thisSymbol,
|
||||||
expression.origin
|
expression.origin
|
||||||
) else {
|
) else {
|
||||||
@@ -110,28 +115,32 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createInitConstructor(declaration: IrConstructor, name: String): IrSimpleFunction =
|
private fun createInitConstructor(
|
||||||
|
declaration: IrConstructor,
|
||||||
|
name: String,
|
||||||
|
type: IrType
|
||||||
|
): IrSimpleFunction =
|
||||||
JsSymbolBuilder.copyFunctionSymbol(declaration.symbol, "${name}_\$Init\$").let {
|
JsSymbolBuilder.copyFunctionSymbol(declaration.symbol, "${name}_\$Init\$").let {
|
||||||
|
|
||||||
val thisSymbol =
|
val thisSymbol =
|
||||||
JsSymbolBuilder.buildValueParameter(it, declaration.valueParameters.size, declaration.returnType, "\$this")
|
JsSymbolBuilder.buildValueParameter(it, declaration.valueParameters.size, type, "\$this")
|
||||||
|
|
||||||
it.initialize(
|
it.initialize(
|
||||||
dispatchParameterDescriptor = declaration.descriptor.dispatchReceiverParameter,
|
dispatchParameterDescriptor = declaration.descriptor.dispatchReceiverParameter,
|
||||||
typeParameters = declaration.descriptor.typeParameters,
|
typeParameters = declaration.descriptor.typeParameters,
|
||||||
valueParameters = declaration.descriptor.valueParameters + thisSymbol.descriptor as ValueParameterDescriptor,
|
valueParameters = declaration.descriptor.valueParameters + thisSymbol.descriptor as ValueParameterDescriptor,
|
||||||
type = declaration.descriptor.returnType,
|
returnType = type,
|
||||||
modality = declaration.descriptor.modality,
|
modality = declaration.descriptor.modality,
|
||||||
visibility = declaration.descriptor.visibility
|
visibility = declaration.descriptor.visibility
|
||||||
)
|
)
|
||||||
|
|
||||||
val thisParam = JsIrBuilder.buildValueParameter(thisSymbol)
|
val thisParam = JsIrBuilder.buildValueParameter(thisSymbol, type)
|
||||||
|
|
||||||
return IrFunctionImpl(
|
return IrFunctionImpl(
|
||||||
declaration.startOffset, declaration.endOffset,
|
declaration.startOffset, declaration.endOffset,
|
||||||
declaration.origin, it
|
declaration.origin, it
|
||||||
).apply {
|
).apply {
|
||||||
val retStmt = JsIrBuilder.buildReturn(it, JsIrBuilder.buildGetValue(thisSymbol))
|
val retStmt = JsIrBuilder.buildReturn(it, JsIrBuilder.buildGetValue(thisSymbol), context)
|
||||||
val statements = (declaration.body as IrStatementContainer).statements
|
val statements = (declaration.body as IrStatementContainer).statements
|
||||||
|
|
||||||
valueParameters += (declaration.valueParameters + thisParam)
|
valueParameters += (declaration.valueParameters + thisParam)
|
||||||
@@ -145,13 +154,13 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun createCreateConstructor(ctorOrig: IrConstructor, ctorImpl: IrSimpleFunction, name: String): IrSimpleFunction =
|
private fun createCreateConstructor(ctorOrig: IrConstructor, ctorImpl: IrSimpleFunction, name: String, type: IrType): IrSimpleFunction =
|
||||||
JsSymbolBuilder.copyFunctionSymbol(ctorOrig.symbol, "${name}_\$Create\$").let {
|
JsSymbolBuilder.copyFunctionSymbol(ctorOrig.symbol, "${name}_\$Create\$").let {
|
||||||
it.initialize(
|
it.initialize(
|
||||||
dispatchParameterDescriptor = ctorOrig.descriptor.dispatchReceiverParameter,
|
dispatchParameterDescriptor = ctorOrig.descriptor.dispatchReceiverParameter,
|
||||||
typeParameters = ctorOrig.descriptor.typeParameters,
|
typeParameters = ctorOrig.descriptor.typeParameters,
|
||||||
valueParameters = ctorOrig.descriptor.valueParameters,
|
valueParameters = ctorOrig.descriptor.valueParameters,
|
||||||
type = ctorOrig.returnType,
|
returnType = type,
|
||||||
modality = ctorOrig.descriptor.modality,
|
modality = ctorOrig.descriptor.modality,
|
||||||
visibility = ctorOrig.visibility
|
visibility = ctorOrig.visibility
|
||||||
)
|
)
|
||||||
@@ -165,14 +174,14 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
|||||||
typeParameters += ctorOrig.typeParameters
|
typeParameters += ctorOrig.typeParameters
|
||||||
// parent = ctorOrig.parent
|
// parent = ctorOrig.parent
|
||||||
|
|
||||||
val returnType = ctorOrig.returnType
|
val returnType = type
|
||||||
val createFunctionIntrinsic = context.intrinsics.jsObjectCreate
|
val createFunctionIntrinsic = context.intrinsics.jsObjectCreate
|
||||||
val irCreateCall = JsIrBuilder.buildCall(
|
val irCreateCall = JsIrBuilder.buildCall(
|
||||||
createFunctionIntrinsic.symbol,
|
createFunctionIntrinsic.symbol,
|
||||||
returnType,
|
returnType,
|
||||||
mapOf(createFunctionIntrinsic.typeParameters[0].descriptor to returnType)
|
listOf(returnType)
|
||||||
)
|
)
|
||||||
val irDelegateCall = JsIrBuilder.buildCall(ctorImpl.symbol).also {
|
val irDelegateCall = JsIrBuilder.buildCall(ctorImpl.symbol, type).also {
|
||||||
for (i in 0 until valueParameters.size) {
|
for (i in 0 until valueParameters.size) {
|
||||||
it.putValueArgument(i, JsIrBuilder.buildGetValue(valueParameters[i].symbol))
|
it.putValueArgument(i, JsIrBuilder.buildGetValue(valueParameters[i].symbol))
|
||||||
}
|
}
|
||||||
@@ -181,7 +190,7 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
|||||||
|
|
||||||
// typeParameters.mapIndexed { i, t -> ctorImpl.typeParameters[i].descriptor -> }
|
// typeParameters.mapIndexed { i, t -> ctorImpl.typeParameters[i].descriptor -> }
|
||||||
}
|
}
|
||||||
val irReturn = JsIrBuilder.buildReturn(it, irDelegateCall)
|
val irReturn = JsIrBuilder.buildReturn(it, irDelegateCall, context)
|
||||||
|
|
||||||
|
|
||||||
body = JsIrBuilder.buildBlockBody(listOf(irReturn))
|
body = JsIrBuilder.buildBlockBody(listOf(irReturn))
|
||||||
@@ -233,10 +242,11 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
|||||||
IrGetValueImpl(
|
IrGetValueImpl(
|
||||||
expression.startOffset,
|
expression.startOffset,
|
||||||
expression.endOffset,
|
expression.endOffset,
|
||||||
|
expression.type,
|
||||||
IrValueParameterSymbolImpl(LazyClassReceiverParameterDescriptor(target.descriptor.containingDeclaration))
|
IrValueParameterSymbolImpl(LazyClassReceiverParameterDescriptor(target.descriptor.containingDeclaration))
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
IrGetValueImpl(expression.startOffset, expression.endOffset, ownerFunc.valueParameters.last().symbol)
|
IrGetValueImpl(expression.startOffset, expression.endOffset, expression.type, ownerFunc.valueParameters.last().symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
newCall.putValueArgument(expression.valueArgumentsCount, readThis)
|
newCall.putValueArgument(expression.valueArgumentsCount, readThis)
|
||||||
@@ -247,7 +257,7 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
|||||||
private fun redirectCall(
|
private fun redirectCall(
|
||||||
call: IrFunctionAccessExpression,
|
call: IrFunctionAccessExpression,
|
||||||
newTarget: IrSimpleFunctionSymbol
|
newTarget: IrSimpleFunctionSymbol
|
||||||
) = IrCallImpl(call.startOffset, call.endOffset, newTarget).apply {
|
) = IrCallImpl(call.startOffset, call.endOffset, call.type, newTarget).apply {
|
||||||
|
|
||||||
copyTypeArgumentsFrom(call)
|
copyTypeArgumentsFrom(call)
|
||||||
|
|
||||||
|
|||||||
+57
-51
@@ -6,35 +6,34 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.isFunctionOrKFunctionType
|
import org.jetbrains.kotlin.backend.common.utils.*
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrArithBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrArithBuilder
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
import org.jetbrains.kotlin.ir.backend.js.symbols.JsSymbolBuilder
|
import org.jetbrains.kotlin.ir.backend.js.symbols.JsSymbolBuilder
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.utils.isReified
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
|
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.isNullable
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.*
|
|
||||||
|
|
||||||
class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||||
private val unit = context.builtIns.unit
|
private val unit = context.irBuiltIns.unitType
|
||||||
private val unitValue = JsIrBuilder.buildGetObjectValue(unit.defaultType, context.symbolTable.referenceClass(unit))
|
private val unitValue = JsIrBuilder.buildGetObjectValue(unit, unit.classifierOrFail as IrClassSymbol)
|
||||||
|
|
||||||
private val lit24 = JsIrBuilder.buildInt(context.builtIns.intType, 24)
|
private val lit24 = JsIrBuilder.buildInt(context.irBuiltIns.intType, 24)
|
||||||
private val lit16 = JsIrBuilder.buildInt(context.builtIns.intType, 16)
|
private val lit16 = JsIrBuilder.buildInt(context.irBuiltIns.intType, 16)
|
||||||
|
|
||||||
private val byteMask = JsIrBuilder.buildInt(context.builtIns.intType, 0xFF)
|
private val byteMask = JsIrBuilder.buildInt(context.irBuiltIns.intType, 0xFF)
|
||||||
private val shortMask = JsIrBuilder.buildInt(context.builtIns.intType, 0xFFFF)
|
private val shortMask = JsIrBuilder.buildInt(context.irBuiltIns.intType, 0xFFFF)
|
||||||
|
|
||||||
private val calculator = JsIrArithBuilder(context)
|
private val calculator = JsIrArithBuilder(context)
|
||||||
|
|
||||||
@@ -53,13 +52,13 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
private val typeOfIntrinsicSymbol = context.intrinsics.jsTypeOf.symbol
|
private val typeOfIntrinsicSymbol = context.intrinsics.jsTypeOf.symbol
|
||||||
private val toJSTypeIntrinsicSymbol = context.intrinsics.jsToJsType.symbol
|
private val toJSTypeIntrinsicSymbol = context.intrinsics.jsToJsType.symbol
|
||||||
|
|
||||||
private val stringMarker = JsIrBuilder.buildString(context.irBuiltIns.string, "string")
|
private val stringMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "string")
|
||||||
private val booleanMarker = JsIrBuilder.buildString(context.irBuiltIns.string, "boolean")
|
private val booleanMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "boolean")
|
||||||
private val functionMarker = JsIrBuilder.buildString(context.irBuiltIns.string, "function")
|
private val functionMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "function")
|
||||||
private val numberMarker = JsIrBuilder.buildString(context.irBuiltIns.string, "number")
|
private val numberMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "number")
|
||||||
|
|
||||||
private val litTrue: IrExpression = JsIrBuilder.buildBoolean(context.irBuiltIns.bool, true)
|
private val litTrue: IrExpression = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true)
|
||||||
private val litNull: IrExpression = JsIrBuilder.buildNull(context.builtIns.nullableNothingType)
|
private val litNull: IrExpression = JsIrBuilder.buildNull(context.irBuiltIns.nothingNType)
|
||||||
|
|
||||||
private fun getInternalFunction(name: String) = context.symbolTable.referenceSimpleFunction(context.getInternalFunctions(name).single())
|
private fun getInternalFunction(name: String) = context.symbolTable.referenceSimpleFunction(context.getInternalFunctions(name).single())
|
||||||
|
|
||||||
@@ -126,16 +125,21 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: native `instanceOf` is not used which is important because of null-behaviour
|
// Note: native `instanceOf` is not used which is important because of null-behaviour
|
||||||
private fun advancedCheckRequired(type: KotlinType) = type.isInterface() ||
|
private fun advancedCheckRequired(type: IrType) = type.isInterface() ||
|
||||||
KotlinBuiltIns.isArray(type) ||
|
type.isArray() ||
|
||||||
KotlinBuiltIns.isPrimitiveArray(type) ||
|
type.isPrimitiveArray() ||
|
||||||
isTypeOfCheckingType(type)
|
isTypeOfCheckingType(type)
|
||||||
|
|
||||||
private fun isTypeOfCheckingType(type: KotlinType) =
|
private fun isTypeOfCheckingType(type: IrType) =
|
||||||
((type.isPrimitiveNumberType() || KotlinBuiltIns.isNumber(type)) && !type.isLong() && !type.isChar()) ||
|
type.isByte() ||
|
||||||
|
type.isShort() ||
|
||||||
|
type.isInt() ||
|
||||||
|
type.isFloat() ||
|
||||||
|
type.isDouble() ||
|
||||||
|
type.isNumber() ||
|
||||||
type.isBoolean() ||
|
type.isBoolean() ||
|
||||||
type.isFunctionOrKFunctionType ||
|
type.isFunctionOrKFunction() ||
|
||||||
KotlinBuiltIns.isString(type)
|
type.isString()
|
||||||
|
|
||||||
fun lowerInstanceOf(
|
fun lowerInstanceOf(
|
||||||
expression: IrTypeOperatorCall,
|
expression: IrTypeOperatorCall,
|
||||||
@@ -146,7 +150,7 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
assert((expression.operator == IrTypeOperator.NOT_INSTANCEOF) == inverted)
|
assert((expression.operator == IrTypeOperator.NOT_INSTANCEOF) == inverted)
|
||||||
|
|
||||||
val toType = expression.typeOperand
|
val toType = expression.typeOperand
|
||||||
val isCopyRequired = expression.argument.type.isNullable() && advancedCheckRequired(toType.makeNotNullable())
|
val isCopyRequired = expression.argument.type.isNullable() && advancedCheckRequired(toType.makeNotNull())
|
||||||
val newStatements = mutableListOf<IrStatement>()
|
val newStatements = mutableListOf<IrStatement>()
|
||||||
|
|
||||||
val argument =
|
val argument =
|
||||||
@@ -167,12 +171,12 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
|
|
||||||
private fun cacheValue(value: IrExpression, newStatements: MutableList<IrStatement>, cd: DeclarationDescriptor): IrExpression {
|
private fun cacheValue(value: IrExpression, newStatements: MutableList<IrStatement>, cd: DeclarationDescriptor): IrExpression {
|
||||||
val varSymbol = JsSymbolBuilder.buildTempVar(cd, value.type, mutable = false)
|
val varSymbol = JsSymbolBuilder.buildTempVar(cd, value.type, mutable = false)
|
||||||
newStatements += JsIrBuilder.buildVar(varSymbol, value)
|
newStatements += JsIrBuilder.buildVar(varSymbol, value, value.type)
|
||||||
return JsIrBuilder.buildGetValue(varSymbol)
|
return JsIrBuilder.buildGetValue(varSymbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateTypeCheck(argument: IrExpression, toType: KotlinType): IrExpression {
|
private fun generateTypeCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||||
val toNotNullable = toType.makeNotNullable()
|
val toNotNullable = toType.makeNotNull()
|
||||||
val instanceCheck = generateTypeCheckNonNull(argument, toNotNullable)
|
val instanceCheck = generateTypeCheckNonNull(argument, toNotNullable)
|
||||||
val isFromNullable = argument.type.isNullable()
|
val isFromNullable = argument.type.isNullable()
|
||||||
val isToNullable = toType.isNullable()
|
val isToNullable = toType.isNullable()
|
||||||
@@ -190,14 +194,14 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateTypeCheckNonNull(argument: IrExpression, toType: KotlinType): IrExpression {
|
private fun generateTypeCheckNonNull(argument: IrExpression, toType: IrType): IrExpression {
|
||||||
assert(!toType.isMarkedNullable)
|
assert(!toType.isMarkedNullable())
|
||||||
return when {
|
return when {
|
||||||
KotlinBuiltIns.isAny(toType) -> generateIsObjectCheck(argument)
|
toType.isAny() -> generateIsObjectCheck(argument)
|
||||||
isTypeOfCheckingType(toType) -> generateTypeOfCheck(argument, toType)
|
isTypeOfCheckingType(toType) -> generateTypeOfCheck(argument, toType)
|
||||||
toType.isChar() -> generateCheckForChar(argument)
|
toType.isChar() -> generateCheckForChar(argument)
|
||||||
KotlinBuiltIns.isArray(toType) -> generateGenericArrayCheck(argument)
|
toType.isArray() -> generateGenericArrayCheck(argument)
|
||||||
KotlinBuiltIns.isPrimitiveArray(toType) -> generatePrimitiveArrayTypeCheck(argument, toType)
|
toType.isPrimitiveArray() -> generatePrimitiveArrayTypeCheck(argument, toType)
|
||||||
toType.isTypeParameter() -> generateTypeCheckWithTypeParameter(argument, toType)
|
toType.isTypeParameter() -> generateTypeCheckWithTypeParameter(argument, toType)
|
||||||
toType.isInterface() -> generateInterfaceCheck(argument, toType)
|
toType.isInterface() -> generateInterfaceCheck(argument, toType)
|
||||||
else -> generateNativeInstanceOf(argument, toType)
|
else -> generateNativeInstanceOf(argument, toType)
|
||||||
@@ -208,12 +212,14 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
putValueArgument(0, argument)
|
putValueArgument(0, argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateTypeCheckWithTypeParameter(argument: IrExpression, toType: KotlinType): IrExpression {
|
private fun generateTypeCheckWithTypeParameter(argument: IrExpression, toType: IrType): IrExpression {
|
||||||
val typeParameterDescriptor = toType.constructor.declarationDescriptor as TypeParameterDescriptor
|
val typeParameter =
|
||||||
assert(!typeParameterDescriptor.isReified) { "reified parameters have to be lowered before" }
|
(toType.classifierOrNull as? IrTypeParameterSymbol)?.owner ?: error("expected type parameter, but $toType")
|
||||||
|
|
||||||
return typeParameterDescriptor.upperBounds.fold(litTrue) { r, t ->
|
assert(!typeParameter.isReified) { "reified parameters have to be lowered before" }
|
||||||
val check = generateTypeCheckNonNull(argument, t.makeNotNullable())
|
|
||||||
|
return typeParameter.superTypes.fold(litTrue) { r, t ->
|
||||||
|
val check = generateTypeCheckNonNull(argument, t.makeNotNull())
|
||||||
calculator.and(r, check)
|
calculator.and(r, check)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,11 +227,11 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
private fun generateCheckForChar(argument: IrExpression) =
|
private fun generateCheckForChar(argument: IrExpression) =
|
||||||
JsIrBuilder.buildCall(isCharSymbol).apply { dispatchReceiver = argument }
|
JsIrBuilder.buildCall(isCharSymbol).apply { dispatchReceiver = argument }
|
||||||
|
|
||||||
private fun generateTypeOfCheck(argument: IrExpression, toType: KotlinType): IrExpression {
|
private fun generateTypeOfCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||||
val marker = when {
|
val marker = when {
|
||||||
toType.isFunctionOrKFunctionType -> functionMarker
|
toType.isFunctionOrKFunction() -> functionMarker
|
||||||
toType.isBoolean() -> booleanMarker
|
toType.isBoolean() -> booleanMarker
|
||||||
KotlinBuiltIns.isString(toType) -> stringMarker
|
toType.isString() -> stringMarker
|
||||||
else -> numberMarker
|
else -> numberMarker
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,17 +242,17 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapTypeReference(toType: KotlinType) =
|
private fun wrapTypeReference(toType: IrType) =
|
||||||
JsIrBuilder.buildCall(toJSTypeIntrinsicSymbol).apply { putTypeArgument(0, toType) }
|
JsIrBuilder.buildCall(toJSTypeIntrinsicSymbol).apply { putTypeArgument(0, toType) }
|
||||||
|
|
||||||
private fun generateGenericArrayCheck(argument: IrExpression) =
|
private fun generateGenericArrayCheck(argument: IrExpression) =
|
||||||
JsIrBuilder.buildCall(isArraySymbol).apply { putValueArgument(0, argument) }
|
JsIrBuilder.buildCall(isArraySymbol).apply { putValueArgument(0, argument) }
|
||||||
|
|
||||||
private fun generatePrimitiveArrayTypeCheck(argument: IrExpression, toType: KotlinType): IrExpression {
|
private fun generatePrimitiveArrayTypeCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||||
TODO("Implement Typed Array check")
|
TODO("Implement Typed Array check")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateInterfaceCheck(argument: IrExpression, toType: KotlinType): IrExpression {
|
private fun generateInterfaceCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||||
val irType = wrapTypeReference(toType)
|
val irType = wrapTypeReference(toType)
|
||||||
return JsIrBuilder.buildCall(isInterfaceSymbol).apply {
|
return JsIrBuilder.buildCall(isInterfaceSymbol).apply {
|
||||||
putValueArgument(0, argument)
|
putValueArgument(0, argument)
|
||||||
@@ -254,7 +260,7 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateNativeInstanceOf(argument: IrExpression, toType: KotlinType): IrExpression {
|
private fun generateNativeInstanceOf(argument: IrExpression, toType: IrType): IrExpression {
|
||||||
val irType = wrapTypeReference(toType)
|
val irType = wrapTypeReference(toType)
|
||||||
return JsIrBuilder.buildCall(instanceOfIntrinsicSymbol).apply {
|
return JsIrBuilder.buildCall(instanceOfIntrinsicSymbol).apply {
|
||||||
putValueArgument(0, argument)
|
putValueArgument(0, argument)
|
||||||
@@ -264,12 +270,12 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
|
|
||||||
private fun lowerCoercionToUnit(expression: IrTypeOperatorCall): IrExpression {
|
private fun lowerCoercionToUnit(expression: IrTypeOperatorCall): IrExpression {
|
||||||
assert(expression.operator === IrTypeOperator.IMPLICIT_COERCION_TO_UNIT)
|
assert(expression.operator === IrTypeOperator.IMPLICIT_COERCION_TO_UNIT)
|
||||||
return expression.run { IrCompositeImpl(startOffset, endOffset, unit.defaultType, null, listOf(argument, unitValue)) }
|
return expression.run { IrCompositeImpl(startOffset, endOffset, unit, null, listOf(argument, unitValue)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun lowerIntegerCoercion(expression: IrTypeOperatorCall, containingDeclaration: DeclarationDescriptor): IrExpression {
|
private fun lowerIntegerCoercion(expression: IrTypeOperatorCall, containingDeclaration: DeclarationDescriptor): IrExpression {
|
||||||
assert(expression.operator === IrTypeOperator.IMPLICIT_INTEGER_COERCION)
|
assert(expression.operator === IrTypeOperator.IMPLICIT_INTEGER_COERCION)
|
||||||
assert(KotlinBuiltIns.isInt(expression.argument.type))
|
assert(expression.argument.type.isInt())
|
||||||
|
|
||||||
val isNullable = expression.argument.type.isNullable()
|
val isNullable = expression.argument.type.isNullable()
|
||||||
val toType = expression.typeOperand
|
val toType = expression.typeOperand
|
||||||
@@ -284,9 +290,9 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
if (isNullable) cacheValue(expression.argument, newStatements, containingDeclaration) else expression.argument
|
if (isNullable) cacheValue(expression.argument, newStatements, containingDeclaration) else expression.argument
|
||||||
|
|
||||||
val casted = when {
|
val casted = when {
|
||||||
KotlinBuiltIns.isByte(toType) -> maskOp(argument, byteMask, lit24)
|
toType.isByte() -> maskOp(argument, byteMask, lit24)
|
||||||
KotlinBuiltIns.isShort(toType) -> maskOp(argument, shortMask, lit16)
|
toType.isShort() -> maskOp(argument, shortMask, lit16)
|
||||||
KotlinBuiltIns.isLong(toType) -> TODO("Long coercion")
|
toType.isLong() -> TODO("Long coercion")
|
||||||
else -> error("Unreachable execution (coercion to non-Integer type")
|
else -> error("Unreachable execution (coercion to non-Integer type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-9
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
|
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.createValueSymbol
|
import org.jetbrains.kotlin.ir.symbols.impl.createValueSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -34,7 +35,6 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
|
||||||
|
|
||||||
|
|
||||||
// backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DeepCopyIrTreeWithDescriptors.kt
|
// backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DeepCopyIrTreeWithDescriptors.kt
|
||||||
@@ -479,7 +479,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
|||||||
return IrCallImpl(
|
return IrCallImpl(
|
||||||
startOffset = expression.startOffset,
|
startOffset = expression.startOffset,
|
||||||
endOffset = expression.endOffset,
|
endOffset = expression.endOffset,
|
||||||
type = newDescriptor.returnType!!,
|
type = newDescriptor.returnType?.toIrType()!!,
|
||||||
descriptor = newDescriptor,
|
descriptor = newDescriptor,
|
||||||
typeArgumentsCount = expression.typeArgumentsCount,
|
typeArgumentsCount = expression.typeArgumentsCount,
|
||||||
origin = expression.origin,
|
origin = expression.origin,
|
||||||
@@ -517,7 +517,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
|||||||
|
|
||||||
//---------------------------------------------------------------------//
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
fun getTypeOperatorReturnType(operator: IrTypeOperator, type: KotlinType) : KotlinType {
|
fun getTypeOperatorReturnType(operator: IrTypeOperator, type: IrType) : IrType {
|
||||||
return when (operator) {
|
return when (operator) {
|
||||||
IrTypeOperator.CAST,
|
IrTypeOperator.CAST,
|
||||||
IrTypeOperator.IMPLICIT_CAST,
|
IrTypeOperator.IMPLICIT_CAST,
|
||||||
@@ -526,7 +526,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
|||||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> type
|
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> type
|
||||||
IrTypeOperator.SAFE_CAST -> type.makeNullable()
|
IrTypeOperator.SAFE_CAST -> type.makeNullable()
|
||||||
IrTypeOperator.INSTANCEOF,
|
IrTypeOperator.INSTANCEOF,
|
||||||
IrTypeOperator.NOT_INSTANCEOF -> context.builtIns.booleanType
|
IrTypeOperator.NOT_INSTANCEOF -> context.irBuiltIns.booleanType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +541,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
|||||||
type = returnType,
|
type = returnType,
|
||||||
operator = expression.operator,
|
operator = expression.operator,
|
||||||
typeOperand = typeOperand,
|
typeOperand = typeOperand,
|
||||||
argument = expression.argument.transform(this, null)
|
argument = expression.argument.transform(this, null),
|
||||||
|
typeOperandClassifier = typeOperand.classifierOrFail
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -610,6 +611,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun substituteType(oldType: IrType?): IrType? = substituteType(oldType?.toKotlinType())?.toIrType()
|
||||||
|
|
||||||
private fun substituteType(oldType: KotlinType?): KotlinType? {
|
private fun substituteType(oldType: KotlinType?): KotlinType? {
|
||||||
if (typeSubstitutor == null) return oldType
|
if (typeSubstitutor == null) return oldType
|
||||||
if (oldType == null) return oldType
|
if (oldType == null) return oldType
|
||||||
@@ -699,7 +702,8 @@ class DescriptorSubstitutorForExternalScope(val globalSubstituteMap: MutableMap<
|
|||||||
endOffset = declaration.endOffset,
|
endOffset = declaration.endOffset,
|
||||||
origin = declaration.origin,
|
origin = declaration.origin,
|
||||||
descriptor = newDescriptor,
|
descriptor = newDescriptor,
|
||||||
initializer = declaration.initializer
|
initializer = declaration.initializer,
|
||||||
|
type = declaration.type
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,7 +719,8 @@ class DescriptorSubstitutorForExternalScope(val globalSubstituteMap: MutableMap<
|
|||||||
startOffset = expression.startOffset,
|
startOffset = expression.startOffset,
|
||||||
endOffset = expression.endOffset,
|
endOffset = expression.endOffset,
|
||||||
origin = expression.origin,
|
origin = expression.origin,
|
||||||
symbol = createValueSymbol(newDescriptor)
|
symbol = createValueSymbol(newDescriptor),
|
||||||
|
type = expression.type
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -732,7 +737,7 @@ class DescriptorSubstitutorForExternalScope(val globalSubstituteMap: MutableMap<
|
|||||||
return IrCallImpl(
|
return IrCallImpl(
|
||||||
startOffset = oldExpression.startOffset,
|
startOffset = oldExpression.startOffset,
|
||||||
endOffset = oldExpression.endOffset,
|
endOffset = oldExpression.endOffset,
|
||||||
type = newDescriptor.returnType!!,
|
type = oldExpression.type,
|
||||||
symbol = createFunctionSymbol(newDescriptor),
|
symbol = createFunctionSymbol(newDescriptor),
|
||||||
descriptor = newDescriptor,
|
descriptor = newDescriptor,
|
||||||
typeArgumentsCount = oldExpression.typeArgumentsCount,
|
typeArgumentsCount = oldExpression.typeArgumentsCount,
|
||||||
@@ -763,4 +768,3 @@ class DescriptorSubstitutorForExternalScope(val globalSubstituteMap: MutableMap<
|
|||||||
return oldExpression.shallowCopy(oldExpression.origin, createFunctionSymbol(newDescriptor), oldExpression.superQualifierSymbol)
|
return oldExpression.shallowCopy(oldExpression.origin, createFunctionSymbol(newDescriptor), oldExpression.superQualifierSymbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-13
@@ -23,14 +23,16 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.declarations.getDefault
|
import org.jetbrains.kotlin.ir.declarations.getDefault
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.createValueSymbol
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.TypeProjection
|
import org.jetbrains.kotlin.types.TypeProjection
|
||||||
@@ -149,8 +151,8 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, startOffset, endOffset)
|
val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, startOffset, endOffset)
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
val constructorDescriptor = delegatingConstructorCall.descriptor.original
|
val constructorDescriptor = delegatingConstructorCall.descriptor.original
|
||||||
val constructorCall = irCall(delegatingConstructorCall.symbol,
|
val constructorCall = irCall(delegatingConstructorCall.symbol).apply {
|
||||||
constructorDescriptor.typeParameters.associate { it to delegatingConstructorCall.getTypeArgument(it)!! }).apply {
|
constructorDescriptor.typeParameters.forEach() { putTypeArgument(it.index, delegatingConstructorCall.getTypeArgument(it)!!) }
|
||||||
constructorDescriptor.valueParameters.forEach { putValueArgument(it, delegatingConstructorCall.getValueArgument(it)) }
|
constructorDescriptor.valueParameters.forEach { putValueArgument(it, delegatingConstructorCall.getValueArgument(it)) }
|
||||||
}
|
}
|
||||||
val oldThis = delegatingConstructorCall.descriptor.constructedClass.thisAsReceiverParameter
|
val oldThis = delegatingConstructorCall.descriptor.constructedClass.thisAsReceiverParameter
|
||||||
@@ -159,12 +161,12 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
nameHint = delegatingConstructorCall.descriptor.fqNameSafe.toString() + ".this"
|
nameHint = delegatingConstructorCall.descriptor.fqNameSafe.toString() + ".this"
|
||||||
)
|
)
|
||||||
statements[0] = newThis
|
statements[0] = newThis
|
||||||
substituteMap[oldThis] = irGet(newThis.symbol)
|
substituteMap[oldThis] = irGet(newThis)
|
||||||
statements.add(irReturn(irGet(newThis.symbol)))
|
statements.add(irReturn(irGet(newThis)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val returnType = copyFunctionDeclaration.descriptor.returnType!! // Substituted return type.
|
val returnType = copyFunctionDeclaration.returnType // Substituted return type.
|
||||||
val sourceFileName = context.originalModuleIndex.declarationToFile[caller.descriptor.original] ?: ""
|
val sourceFileName = context.originalModuleIndex.declarationToFile[caller.descriptor.original] ?: ""
|
||||||
val inlineFunctionBody = IrReturnableBlockImpl( // Create new IR element to replace "call".
|
val inlineFunctionBody = IrReturnableBlockImpl( // Create new IR element to replace "call".
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
@@ -248,7 +250,7 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
val substitutionContext = mutableMapOf<TypeConstructor, TypeProjection>()
|
val substitutionContext = mutableMapOf<TypeConstructor, TypeProjection>()
|
||||||
for (index in 0 until irCall.typeArgumentsCount) {
|
for (index in 0 until irCall.typeArgumentsCount) {
|
||||||
val typeArgument = irCall.getTypeArgument(index) ?: continue
|
val typeArgument = irCall.getTypeArgument(index) ?: continue
|
||||||
substitutionContext[typeParameters[index].typeConstructor] = TypeProjectionImpl(typeArgument)
|
substitutionContext[typeParameters[index].typeConstructor] = TypeProjectionImpl(typeArgument.toKotlinType())
|
||||||
}
|
}
|
||||||
return TypeSubstitutor.create(substitutionContext)
|
return TypeSubstitutor.create(substitutionContext)
|
||||||
}
|
}
|
||||||
@@ -309,7 +311,8 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val parametersWithDefaultToArgument = mutableListOf<ParameterToArgument>()
|
val parametersWithDefaultToArgument = mutableListOf<ParameterToArgument>()
|
||||||
functionDescriptor.valueParameters.forEach { parameterDescriptor -> // Iterate value parameter descriptors.
|
irFunction.valueParameters.forEach { parameter -> // Iterate value parameter descriptors.
|
||||||
|
val parameterDescriptor = parameter.descriptor as ValueParameterDescriptor
|
||||||
val argument = valueArguments[parameterDescriptor.index] // Get appropriate argument from call site.
|
val argument = valueArguments[parameterDescriptor.index] // Get appropriate argument from call site.
|
||||||
when {
|
when {
|
||||||
argument != null -> { // Argument is good enough.
|
argument != null -> { // Argument is good enough.
|
||||||
@@ -331,8 +334,8 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
val emptyArray = IrVarargImpl(
|
val emptyArray = IrVarargImpl(
|
||||||
startOffset = irCall.startOffset,
|
startOffset = irCall.startOffset,
|
||||||
endOffset = irCall.endOffset,
|
endOffset = irCall.endOffset,
|
||||||
type = parameterDescriptor.type,
|
type = parameter.type,
|
||||||
varargElementType = parameterDescriptor.varargElementType!!
|
varargElementType = parameter.varargElementType!!
|
||||||
)
|
)
|
||||||
parameterToArgument += ParameterToArgument(
|
parameterToArgument += ParameterToArgument(
|
||||||
parameterDescriptor = parameterDescriptor,
|
parameterDescriptor = parameterDescriptor,
|
||||||
@@ -377,7 +380,8 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
val getVal = IrGetValueImpl( // Create new expression, representing access the new variable.
|
val getVal = IrGetValueImpl( // Create new expression, representing access the new variable.
|
||||||
startOffset = currentScope.irElement.startOffset,
|
startOffset = currentScope.irElement.startOffset,
|
||||||
endOffset = currentScope.irElement.endOffset,
|
endOffset = currentScope.irElement.endOffset,
|
||||||
symbol = createValueSymbol(newVariable.descriptor)
|
type = newVariable.type,
|
||||||
|
symbol = newVariable.symbol
|
||||||
)
|
)
|
||||||
substituteMap[parameterDescriptor] = getVal // Parameter will be replaced with the new variable.
|
substituteMap[parameterDescriptor] = getVal // Parameter will be replaced with the new variable.
|
||||||
}
|
}
|
||||||
|
|||||||
+60
-34
@@ -11,12 +11,13 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.addChildren
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
|
import org.jetbrains.kotlin.ir.types.toIrType
|
||||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.visitors.*
|
||||||
@@ -51,7 +52,11 @@ internal fun IrModuleFragment.replaceUnboundSymbols(context: JsIrBackendContext)
|
|||||||
// Generate missing external stubs:
|
// Generate missing external stubs:
|
||||||
// TODO: ModuleGenerator::generateUnboundSymbolsAsDependencies(IRModuleFragment) is private function :/
|
// TODO: ModuleGenerator::generateUnboundSymbolsAsDependencies(IRModuleFragment) is private function :/
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
ExternalDependenciesGenerator(symbolTable = context.symbolTable, irBuiltIns = context.irBuiltIns).generateUnboundSymbolsAsDependencies(this)
|
ExternalDependenciesGenerator(
|
||||||
|
descriptor,
|
||||||
|
symbolTable = context.symbolTable,
|
||||||
|
irBuiltIns = context.irBuiltIns
|
||||||
|
).generateUnboundSymbolsAsDependencies(this)
|
||||||
|
|
||||||
// Merge duplicated module and package declarations:
|
// Merge duplicated module and package declarations:
|
||||||
this.acceptVoid(object : IrElementVisitorVoid {
|
this.acceptVoid(object : IrElementVisitorVoid {
|
||||||
@@ -161,7 +166,7 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrGetValueImpl(startOffset, endOffset, symbol, origin)
|
IrGetValueImpl(startOffset, endOffset, expression.type, symbol, origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,13 +175,13 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrSetVariableImpl(startOffset, endOffset, symbol, value, origin)
|
IrSetVariableImpl(startOffset, endOffset, expression.type, symbol, value, origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {
|
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {
|
||||||
val symbol = expression.symbol.replace(SymbolTable::referenceClass) ?:
|
val symbol = expression.symbol.replace(SymbolTable::referenceClass) ?:
|
||||||
return super.visitGetObjectValue(expression)
|
return super.visitGetObjectValue(expression)
|
||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
@@ -186,7 +191,7 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression {
|
override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression {
|
||||||
val symbol = expression.symbol.replace(SymbolTable::referenceEnumEntry) ?:
|
val symbol = expression.symbol.replace(SymbolTable::referenceEnumEntry) ?:
|
||||||
return super.visitGetEnumValue(expression)
|
return super.visitGetEnumValue(expression)
|
||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
@@ -200,17 +205,11 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrClassReferenceImpl(startOffset, endOffset, type, symbol, symbol.descriptor.defaultType)
|
IrClassReferenceImpl(startOffset, endOffset, type, symbol, symbol.descriptor.toIrType())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass): IrStatement {
|
override fun visitClass(declaration: IrClass): IrStatement {
|
||||||
declaration.superClasses.forEachIndexed { index, symbol ->
|
|
||||||
val newSymbol = symbol.replace(SymbolTable::referenceClass)
|
|
||||||
if (newSymbol != null) {
|
|
||||||
declaration.superClasses[index] = newSymbol
|
|
||||||
}
|
|
||||||
}
|
|
||||||
withLocal(declaration.thisReceiver?.symbol) {
|
withLocal(declaration.thisReceiver?.symbol) {
|
||||||
return super.visitClass(declaration)
|
return super.visitClass(declaration)
|
||||||
}
|
}
|
||||||
@@ -227,7 +226,7 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver, origin, superQualifierSymbol)
|
IrGetFieldImpl(startOffset, endOffset, symbol, type, receiver, origin, superQualifierSymbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,11 +241,13 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrSetFieldImpl(startOffset, endOffset, symbol, receiver, value, origin, superQualifierSymbol)
|
IrSetFieldImpl(startOffset, endOffset, symbol, receiver, value, type /*wrong*/, origin, superQualifierSymbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
expression.replaceTypeArguments()
|
||||||
|
|
||||||
val symbol = expression.symbol.replace(SymbolTable::referenceFunction) ?: expression.symbol
|
val symbol = expression.symbol.replace(SymbolTable::referenceFunction) ?: expression.symbol
|
||||||
|
|
||||||
val superQualifierSymbol = expression.superQualifierSymbol?.replaceOrSame(SymbolTable::referenceClass)
|
val superQualifierSymbol = expression.superQualifierSymbol?.replaceOrSame(SymbolTable::referenceClass)
|
||||||
@@ -257,17 +258,21 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
expression.transformChildrenVoid()
|
expression.transformChildrenVoid()
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrCallImpl(startOffset, endOffset, symbol, descriptor,
|
IrCallImpl(startOffset, endOffset, type, symbol, descriptor,
|
||||||
getTypeArgumentsMap(),
|
typeArgumentsCount,
|
||||||
origin, superQualifierSymbol).also {
|
origin, superQualifierSymbol).also {
|
||||||
|
|
||||||
it.copyArgumentsFrom(this)
|
it.copyArgumentsFrom(this)
|
||||||
|
it.copyTypeArgumentsFrom(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrMemberAccessExpression.getTypeArgumentsMap() =
|
private fun IrMemberAccessExpression.replaceTypeArguments() {
|
||||||
descriptor.original.typeParameters.associate { it to getTypeArgumentOrDefault(it) }
|
repeat(typeArgumentsCount) {
|
||||||
|
putTypeArgument(it, getTypeArgument(it)/*?.toKotlinType()?.let { context.ir.translateErased(it) }*/)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun IrMemberAccessExpressionBase.copyArgumentsFrom(original: IrMemberAccessExpression) {
|
private fun IrMemberAccessExpressionBase.copyArgumentsFrom(original: IrMemberAccessExpression) {
|
||||||
dispatchReceiver = original.dispatchReceiver
|
dispatchReceiver = original.dispatchReceiver
|
||||||
@@ -279,40 +284,48 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression {
|
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression {
|
||||||
val symbol = expression.symbol.replace(SymbolTable::referenceConstructor) ?:
|
val symbol = expression.symbol.replace(SymbolTable::referenceConstructor) ?:
|
||||||
return super.visitEnumConstructorCall(expression)
|
return super.visitEnumConstructorCall(expression)
|
||||||
|
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrEnumConstructorCallImpl(startOffset, endOffset, symbol, null).also {
|
IrEnumConstructorCallImpl(startOffset, endOffset, expression.type, symbol, 0).also {
|
||||||
it.copyArgumentsFrom(this)
|
it.copyArgumentsFrom(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
||||||
|
expression.replaceTypeArguments()
|
||||||
|
|
||||||
val symbol = expression.symbol.replace(SymbolTable::referenceConstructor) ?:
|
val symbol = expression.symbol.replace(SymbolTable::referenceConstructor) ?:
|
||||||
return super.visitDelegatingConstructorCall(expression)
|
return super.visitDelegatingConstructorCall(expression)
|
||||||
|
|
||||||
expression.transformChildrenVoid()
|
expression.transformChildrenVoid()
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, symbol, descriptor, getTypeArgumentsMap()).also {
|
IrDelegatingConstructorCallImpl(startOffset, endOffset, type, symbol, descriptor, typeArgumentsCount).also {
|
||||||
it.copyArgumentsFrom(this)
|
it.copyArgumentsFrom(this)
|
||||||
|
it.copyTypeArgumentsFrom(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||||
|
expression.replaceTypeArguments()
|
||||||
|
|
||||||
val symbol = expression.symbol.replace(SymbolTable::referenceFunction) ?:
|
val symbol = expression.symbol.replace(SymbolTable::referenceFunction) ?:
|
||||||
return super.visitFunctionReference(expression)
|
return super.visitFunctionReference(expression)
|
||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrFunctionReferenceImpl(startOffset, endOffset, type, symbol, descriptor, getTypeArgumentsMap()).also {
|
IrFunctionReferenceImpl(startOffset, endOffset, type, symbol, descriptor, 0).also {
|
||||||
it.copyArgumentsFrom(this)
|
it.copyArgumentsFrom(this)
|
||||||
|
it.copyTypeArgumentsFrom(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitPropertyReference(expression: IrPropertyReference): IrExpression {
|
override fun visitPropertyReference(expression: IrPropertyReference): IrExpression {
|
||||||
|
expression.replaceTypeArguments()
|
||||||
|
|
||||||
val field = expression.field?.replaceOrSame(SymbolTable::referenceField)
|
val field = expression.field?.replaceOrSame(SymbolTable::referenceField)
|
||||||
val getter = expression.getter?.replace(SymbolTable::referenceFunction) ?: expression.getter
|
val getter = expression.getter?.replace(SymbolTable::referenceFunction) ?: expression.getter
|
||||||
val setter = expression.setter?.replace(SymbolTable::referenceFunction) ?: expression.setter
|
val setter = expression.setter?.replace(SymbolTable::referenceFunction) ?: expression.setter
|
||||||
@@ -323,13 +336,14 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrPropertyReferenceImpl(startOffset, endOffset, type, descriptor,
|
IrPropertyReferenceImpl(startOffset, endOffset, type, descriptor, 0,
|
||||||
field,
|
field,
|
||||||
getter,
|
getter,
|
||||||
setter,
|
setter,
|
||||||
getTypeArgumentsMap(), origin).also {
|
origin).also {
|
||||||
|
|
||||||
it.copyArgumentsFrom(this)
|
it.copyArgumentsFrom(this)
|
||||||
|
it.copyTypeArgumentsFrom(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,7 +360,7 @@ private class IrUnboundSymbolReplacer(
|
|||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrLocalDelegatedPropertyReferenceImpl(startOffset, endOffset, type, descriptor,
|
IrLocalDelegatedPropertyReferenceImpl(startOffset, endOffset, type, descriptor,
|
||||||
delegate, getter, setter, origin).also {
|
delegate, getter, setter, origin).also {
|
||||||
|
|
||||||
it.copyArgumentsFrom(this)
|
it.copyArgumentsFrom(this)
|
||||||
}
|
}
|
||||||
@@ -406,12 +420,24 @@ private class IrUnboundSymbolReplacer(
|
|||||||
|
|
||||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
|
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
|
||||||
val classSymbol = expression.classSymbol.replace(SymbolTable::referenceClass) ?:
|
val classSymbol = expression.classSymbol.replace(SymbolTable::referenceClass) ?:
|
||||||
return super.visitInstanceInitializerCall(expression)
|
return super.visitInstanceInitializerCall(expression)
|
||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
return with(expression) {
|
return with(expression) {
|
||||||
IrInstanceInitializerCallImpl(startOffset, endOffset, classSymbol)
|
IrInstanceInitializerCallImpl(startOffset, endOffset, classSymbol, type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
|
||||||
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
|
return with(expression) {
|
||||||
|
val newTypeOperand = typeOperand /*context.ir.translateErased(typeOperand.toKotlinType())*/
|
||||||
|
IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, newTypeOperand).also {
|
||||||
|
it.argument = argument
|
||||||
|
it.typeOperandClassifier = newTypeOperand.classifierOrFail
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-18
@@ -5,10 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.inline
|
package org.jetbrains.kotlin.ir.backend.js.lower.inline
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
|
||||||
@@ -19,21 +20,6 @@ fun IrSimpleFunction.setOverrides(symbolTable: SymbolTable) {
|
|||||||
this.descriptor.overriddenDescriptors.mapTo(this.overriddenSymbols) {
|
this.descriptor.overriddenDescriptors.mapTo(this.overriddenSymbols) {
|
||||||
symbolTable.referenceSimpleFunction(it.original)
|
symbolTable.referenceSimpleFunction(it.original)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.typeParameters.forEach { it.setSupers(symbolTable) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrTypeParameter.setSupers(symbolTable: SymbolTable) {
|
|
||||||
assert(this.superClassifiers.isEmpty())
|
|
||||||
this.descriptor.upperBounds.mapNotNullTo(this.superClassifiers) {
|
|
||||||
it.constructor.declarationDescriptor?.let {
|
|
||||||
if (it is TypeParameterDescriptor) {
|
|
||||||
IrTypeParameterSymbolImpl(it) // Workaround for deserialized inline functions
|
|
||||||
} else {
|
|
||||||
symbolTable.referenceClassifier(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrDeclarationContainer.addChildren(declarations: List<IrDeclaration>) {
|
fun IrDeclarationContainer.addChildren(declarations: List<IrDeclaration>) {
|
||||||
|
|||||||
+7
-1
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.getTypeArgumentOrDefault
|
import org.jetbrains.kotlin.ir.expressions.getTypeArgumentOrDefault
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -43,6 +45,10 @@ fun IrModuleFragment.referenceAllTypeExternalClassifiers(symbolTable: SymbolTabl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IrType.referenceAllClassifiers() {
|
||||||
|
this.toKotlinType().referenceAllClassifiers()
|
||||||
|
}
|
||||||
|
|
||||||
val visitor = object : IrElementVisitorVoid {
|
val visitor = object : IrElementVisitorVoid {
|
||||||
override fun visitElement(element: IrElement) {
|
override fun visitElement(element: IrElement) {
|
||||||
element.acceptChildrenVoid(this)
|
element.acceptChildrenVoid(this)
|
||||||
@@ -125,4 +131,4 @@ fun IrModuleFragment.referenceAllTypeExternalClassifiers(symbolTable: SymbolTabl
|
|||||||
it.acceptVoid(visitor)
|
it.acceptVoid(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-11
@@ -10,14 +10,18 @@ import org.jetbrains.kotlin.ir.IrStatement
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
import org.jetbrains.kotlin.ir.backend.js.symbols.JsSymbolBuilder
|
import org.jetbrains.kotlin.ir.backend.js.symbols.JsSymbolBuilder
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrReturn
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrReturnableBlock
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrDoWhileLoopImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrDoWhileLoopImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces returnable blocks and `return`'s with loops and `break`'s correspondingly.
|
* Replaces returnable blocks and `return`'s with loops and `break`'s correspondingly.
|
||||||
@@ -93,7 +97,7 @@ private class ReturnableBlockTransformer(
|
|||||||
return super.visitDeclaration(declaration, data)
|
return super.visitDeclaration(declaration, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val constFalse = JsIrBuilder.buildBoolean(context.builtIns.booleanType, false)
|
private val constFalse = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false)
|
||||||
|
|
||||||
override fun visitContainerExpression(expression: IrContainerExpression, data: ReturnableBlockLoweringContext): IrExpression {
|
override fun visitContainerExpression(expression: IrContainerExpression, data: ReturnableBlockLoweringContext): IrExpression {
|
||||||
if (expression !is IrReturnableBlock) return super.visitContainerExpression(expression, data)
|
if (expression !is IrReturnableBlock) return super.visitContainerExpression(expression, data)
|
||||||
@@ -111,7 +115,7 @@ private class ReturnableBlockTransformer(
|
|||||||
IrDoWhileLoopImpl(
|
IrDoWhileLoopImpl(
|
||||||
expression.startOffset,
|
expression.startOffset,
|
||||||
expression.endOffset,
|
expression.endOffset,
|
||||||
context.builtIns.unitType,
|
context.irBuiltIns.unitType,
|
||||||
expression.origin
|
expression.origin
|
||||||
).apply {
|
).apply {
|
||||||
label = "l\$ret\$${data.labelCnt++}"
|
label = "l\$ret\$${data.labelCnt++}"
|
||||||
@@ -127,10 +131,10 @@ private class ReturnableBlockTransformer(
|
|||||||
IrCompositeImpl(
|
IrCompositeImpl(
|
||||||
returnExpression.startOffset,
|
returnExpression.startOffset,
|
||||||
returnExpression.endOffset,
|
returnExpression.endOffset,
|
||||||
context.builtIns.unitType
|
context.irBuiltIns.unitType
|
||||||
).apply {
|
).apply {
|
||||||
statements += JsIrBuilder.buildSetVariable(variable, returnExpression.value)
|
statements += JsIrBuilder.buildSetVariable(variable, returnExpression.value, context.irBuiltIns.unitType)
|
||||||
statements += JsIrBuilder.buildBreak(context.builtIns.unitType, loop)
|
statements += JsIrBuilder.buildBreak(context.irBuiltIns.unitType, loop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +142,7 @@ private class ReturnableBlockTransformer(
|
|||||||
if (i == expression.statements.lastIndex && s is IrReturn && s.returnTargetSymbol == expression.symbol) {
|
if (i == expression.statements.lastIndex && s is IrReturn && s.returnTargetSymbol == expression.symbol) {
|
||||||
s.transformChildren(this, data)
|
s.transformChildren(this, data)
|
||||||
if (!hasReturned) s.value else {
|
if (!hasReturned) s.value else {
|
||||||
JsIrBuilder.buildSetVariable(variable, s.value)
|
JsIrBuilder.buildSetVariable(variable, s.value, context.irBuiltIns.unitType)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s.transform(this, data)
|
s.transform(this, data)
|
||||||
@@ -159,7 +163,7 @@ private class ReturnableBlockTransformer(
|
|||||||
loop.body = IrBlockImpl(
|
loop.body = IrBlockImpl(
|
||||||
expression.startOffset,
|
expression.startOffset,
|
||||||
expression.endOffset,
|
expression.endOffset,
|
||||||
context.builtIns.unitType,
|
context.irBuiltIns.unitType,
|
||||||
expression.origin,
|
expression.origin,
|
||||||
newStatements
|
newStatements
|
||||||
)
|
)
|
||||||
@@ -170,7 +174,7 @@ private class ReturnableBlockTransformer(
|
|||||||
expression.type,
|
expression.type,
|
||||||
expression.origin
|
expression.origin
|
||||||
).apply {
|
).apply {
|
||||||
statements += JsIrBuilder.buildVar(variable)
|
statements += JsIrBuilder.buildVar(variable, type = expression.type)
|
||||||
statements += loop
|
statements += loop
|
||||||
statements += JsIrBuilder.buildGetValue(variable)
|
statements += JsIrBuilder.buildGetValue(variable)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-12
@@ -18,12 +18,13 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
|
|
||||||
object JsSymbolBuilder {
|
object JsSymbolBuilder {
|
||||||
fun buildValueParameter(containingSymbol: IrSimpleFunctionSymbol, index: Int, type: KotlinType, name: String? = null) =
|
fun buildValueParameter(containingSymbol: IrSimpleFunctionSymbol, index: Int, type: IrType, name: String? = null) =
|
||||||
IrValueParameterSymbolImpl(createValueParameter(containingSymbol.descriptor, index, name ?: "param$index", type))
|
IrValueParameterSymbolImpl(createValueParameter(containingSymbol.descriptor, index, name ?: "param$index", type.toKotlinType()))
|
||||||
|
|
||||||
fun buildSimpleFunction(
|
fun buildSimpleFunction(
|
||||||
containingDeclaration: DeclarationDescriptor,
|
containingDeclaration: DeclarationDescriptor,
|
||||||
@@ -53,7 +54,7 @@ object JsSymbolBuilder {
|
|||||||
|
|
||||||
fun buildVar(
|
fun buildVar(
|
||||||
containingDeclaration: DeclarationDescriptor,
|
containingDeclaration: DeclarationDescriptor,
|
||||||
type: KotlinType,
|
type: IrType,
|
||||||
name: String,
|
name: String,
|
||||||
mutable: Boolean = false
|
mutable: Boolean = false
|
||||||
) = IrVariableSymbolImpl(
|
) = IrVariableSymbolImpl(
|
||||||
@@ -61,42 +62,42 @@ object JsSymbolBuilder {
|
|||||||
containingDeclaration,
|
containingDeclaration,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
Name.identifier(name),
|
Name.identifier(name),
|
||||||
type,
|
type.toKotlinType(),
|
||||||
mutable,
|
mutable,
|
||||||
false,
|
false,
|
||||||
SourceElement.NO_SOURCE
|
SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun buildTempVar(containingSymbol: IrSymbol, type: KotlinType, name: String? = null, mutable: Boolean = false) =
|
fun buildTempVar(containingSymbol: IrSymbol, type: IrType, name: String? = null, mutable: Boolean = false) =
|
||||||
buildTempVar(containingSymbol.descriptor, type, name, mutable)
|
buildTempVar(containingSymbol.descriptor, type, name, mutable)
|
||||||
|
|
||||||
fun buildTempVar(containingDeclaration: DeclarationDescriptor, type: KotlinType, name: String? = null, mutable: Boolean = false) =
|
fun buildTempVar(containingDeclaration: DeclarationDescriptor, type: IrType, name: String? = null, mutable: Boolean = false) =
|
||||||
IrVariableSymbolImpl(
|
IrVariableSymbolImpl(
|
||||||
IrTemporaryVariableDescriptorImpl(
|
IrTemporaryVariableDescriptorImpl(
|
||||||
containingDeclaration,
|
containingDeclaration,
|
||||||
Name.identifier(name ?: "tmp"),
|
Name.identifier(name ?: "tmp"),
|
||||||
type, mutable
|
type.toKotlinType(), mutable
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun IrSimpleFunctionSymbol.initialize(
|
fun IrSimpleFunctionSymbol.initialize(
|
||||||
receiverParameterType: KotlinType? = null,
|
receiverParameterType: IrType? = null,
|
||||||
dispatchParameterDescriptor: ReceiverParameterDescriptor? = null,
|
dispatchParameterDescriptor: ReceiverParameterDescriptor? = null,
|
||||||
typeParameters: List<TypeParameterDescriptor> = emptyList(),
|
typeParameters: List<TypeParameterDescriptor> = emptyList(),
|
||||||
valueParameters: List<ValueParameterDescriptor> = emptyList(),
|
valueParameters: List<ValueParameterDescriptor> = emptyList(),
|
||||||
type: KotlinType? = null,
|
returnType: IrType? = null,
|
||||||
modality: Modality = Modality.FINAL,
|
modality: Modality = Modality.FINAL,
|
||||||
visibility: Visibility = Visibilities.LOCAL
|
visibility: Visibility = Visibilities.LOCAL
|
||||||
) = this.apply {
|
) = this.apply {
|
||||||
(descriptor as FunctionDescriptorImpl).initialize(
|
(descriptor as FunctionDescriptorImpl).initialize(
|
||||||
receiverParameterType,
|
receiverParameterType?.toKotlinType(),
|
||||||
dispatchParameterDescriptor,
|
dispatchParameterDescriptor,
|
||||||
typeParameters,
|
typeParameters,
|
||||||
valueParameters,
|
valueParameters,
|
||||||
type,
|
returnType?.toKotlinType(),
|
||||||
modality,
|
modality,
|
||||||
visibility
|
visibility
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-3
@@ -5,15 +5,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
import org.jetbrains.kotlin.backend.common.utils.isFunctionTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.isUnit
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsExpression, JsGenerationContext> {
|
class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsExpression, JsGenerationContext> {
|
||||||
@@ -158,7 +158,7 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
|||||||
val arguments = translateCallArguments(expression, context)
|
val arguments = translateCallArguments(expression, context)
|
||||||
|
|
||||||
if (dispatchReceiver != null &&
|
if (dispatchReceiver != null &&
|
||||||
dispatchReceiver.type.isFunctionTypeOrSubtype && symbol.owner.name == OperatorNameConventions.INVOKE
|
dispatchReceiver.type.isFunctionTypeOrSubtype() && symbol.owner.name == OperatorNameConventions.INVOKE
|
||||||
) {
|
) {
|
||||||
return JsInvocation(jsDispatchReceiver!!, arguments)
|
return JsInvocation(jsDispatchReceiver!!, arguments)
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-6
@@ -11,12 +11,14 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.isAny
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
|
import org.jetbrains.kotlin.ir.types.isAny
|
||||||
import org.jetbrains.kotlin.ir.util.isInterface
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
import org.jetbrains.kotlin.ir.util.isReal
|
import org.jetbrains.kotlin.ir.util.isReal
|
||||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||||
@@ -26,8 +28,8 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
|
|
||||||
private val className = context.getNameForSymbol(irClass.symbol)
|
private val className = context.getNameForSymbol(irClass.symbol)
|
||||||
private val classNameRef = className.makeRef()
|
private val classNameRef = className.makeRef()
|
||||||
private val baseClass = irClass.superClasses.firstOrNull { !it.owner.isInterface }
|
private val baseClass = irClass.superTypes.firstOrNull { !it.classifierOrFail.isInterface }
|
||||||
private val baseClassName = baseClass?.let { context.getNameForSymbol(it) }
|
private val baseClassName = baseClass?.let { context.getNameForSymbol(it.classifierOrFail) }
|
||||||
private val classPrototypeRef = prototypeOf(classNameRef)
|
private val classPrototypeRef = prototypeOf(classNameRef)
|
||||||
private val classBlock = JsGlobalBlock()
|
private val classBlock = JsGlobalBlock()
|
||||||
private val classModel = JsClassModel(className, baseClassName)
|
private val classModel = JsClassModel(className, baseClassName)
|
||||||
@@ -130,7 +132,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateInheritanceCode(): List<JsStatement> {
|
private fun generateInheritanceCode(): List<JsStatement> {
|
||||||
if (baseClass == null || baseClass.isAny) {
|
if (baseClass == null || baseClass.isAny()) {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +160,13 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
|
|
||||||
private fun generateSuperClasses(): JsPropertyInitializer = JsPropertyInitializer(
|
private fun generateSuperClasses(): JsPropertyInitializer = JsPropertyInitializer(
|
||||||
JsNameRef(Namer.METADATA_INTERFACES),
|
JsNameRef(Namer.METADATA_INTERFACES),
|
||||||
JsArrayLiteral(irClass.superClasses.filter { it.owner.isInterface }.map { JsNameRef(context.getNameForSymbol(it.owner.symbol)) })
|
JsArrayLiteral(
|
||||||
|
irClass.superTypes.mapNotNull {
|
||||||
|
val symbol = it.classifierOrFail
|
||||||
|
if (symbol.isInterface) JsNameRef(context.getNameForSymbol(symbol)) else null
|
||||||
|
}
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val IrClassifierSymbol.isInterface get() = (owner as? IrClass)?.isInterface == true
|
||||||
+3
-5
@@ -5,14 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
|
|
||||||
typealias IrCallTransformer = (IrCall, context: JsGenerationContext) -> JsExpression
|
typealias IrCallTransformer = (IrCall, context: JsGenerationContext) -> JsExpression
|
||||||
@@ -69,7 +68,7 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
|||||||
|
|
||||||
add(intrinsics.jsObjectCreate) { call, context ->
|
add(intrinsics.jsObjectCreate) { call, context ->
|
||||||
val classToCreate = call.getTypeArgument(0)!!
|
val classToCreate = call.getTypeArgument(0)!!
|
||||||
val className = context.getNameForSymbol(IrClassSymbolImpl(classToCreate.constructor.declarationDescriptor as ClassDescriptor))
|
val className = context.getNameForSymbol(classToCreate.classifierOrFail)
|
||||||
val prototype = prototypeOf(className.makeRef())
|
val prototype = prototypeOf(className.makeRef())
|
||||||
JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototype)
|
JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototype)
|
||||||
}
|
}
|
||||||
@@ -86,8 +85,7 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
add(intrinsics.jsToJsType) { call, context ->
|
add(intrinsics.jsToJsType) { call, context ->
|
||||||
val typeParameter = call.getTypeArgument(0)!!
|
val typeName = context.getNameForSymbol(call.getTypeArgument(0)!!.classifierOrFail)
|
||||||
val typeName = context.getNameForSymbol(IrClassSymbolImpl(typeParameter.constructor.declarationDescriptor as ClassDescriptor))
|
|
||||||
typeName.makeRef()
|
typeName.makeRef()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user