JS IR: initial lowerings reuse

This commit is contained in:
Anton Bannykh
2018-03-20 20:19:21 +03:00
committed by Anton Bannykh
parent 6adf7eaf04
commit a514c0f515
12 changed files with 222 additions and 53 deletions
@@ -34,7 +34,14 @@ abstract class Symbols<out T: CommonBackendContext>(val context: T, private val
protected fun builtInsPackage(vararg packageNameSegments: String) =
context.builtIns.builtInsModule.getPackage(FqName.fromSegments(listOf(*packageNameSegments))).memberScope
val refClass = symbolTable.referenceClass(context.getInternalClass("Ref"))
// This hack allows to disable related symbol instantiation in descendants
// TODO move relevant symbols to non-common code
open fun calc(initializer: () -> IrClassSymbol): IrClassSymbol {
return initializer()
}
val refClass = calc { symbolTable.referenceClass(context.getInternalClass("Ref")) }
//abstract val areEqualByValue: List<IrFunctionSymbol>
@@ -44,7 +51,7 @@ abstract class Symbols<out T: CommonBackendContext>(val context: T, private val
abstract val ThrowNoWhenBranchMatchedException: IrFunctionSymbol
abstract val ThrowTypeCastException: IrFunctionSymbol
abstract val ThrowUninitializedPropertyAccessException: IrFunctionSymbol
abstract val ThrowUninitializedPropertyAccessException: IrSimpleFunctionSymbol
abstract val stringBuilder: IrClassSymbol
@@ -74,7 +81,7 @@ abstract class Symbols<out T: CommonBackendContext>(val context: T, private val
// val getProgressionLast = context.getInternalFunctions("getProgressionLast")
// .map { Pair(it.returnType, symbolTable.referenceSimpleFunction(it)) }.toMap()
val defaultConstructorMarker = symbolTable.referenceClass(context.getInternalClass("DefaultConstructorMarker"))
val defaultConstructorMarker = calc { symbolTable.referenceClass(context.getInternalClass("DefaultConstructorMarker")) }
val any = symbolTable.referenceClass(builtIns.any)
val unit = symbolTable.referenceClass(builtIns.unit)
@@ -137,13 +144,13 @@ abstract class Symbols<out T: CommonBackendContext>(val context: T, private val
abstract val copyRangeTo: Map<ClassDescriptor, IrSimpleFunctionSymbol>
val intAnd = symbolTable.referenceFunction(
val intAnd = symbolTable.referenceSimpleFunction(
builtIns.intType.memberScope
.getContributedFunctions(OperatorNameConventions.AND, NoLookupLocation.FROM_BACKEND)
.single()
)
val intPlusInt = symbolTable.referenceFunction(
val intPlusInt = symbolTable.referenceSimpleFunction(
builtIns.intType.memberScope
.getContributedFunctions(OperatorNameConventions.PLUS, NoLookupLocation.FROM_BACKEND)
.single {
@@ -164,14 +171,14 @@ abstract class Symbols<out T: CommonBackendContext>(val context: T, private val
abstract val coroutineSuspendedGetter: IrSimpleFunctionSymbol
val kFunctionImpl = symbolTable.referenceClass(context.reflectionTypes.kFunctionImpl)
val kFunctionImpl = calc { symbolTable.referenceClass(context.reflectionTypes.kFunctionImpl) }
val kProperty0Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty0Impl)
val kProperty1Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty1Impl)
val kProperty2Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty2Impl)
val kMutableProperty0Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty0Impl)
val kMutableProperty1Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty1Impl)
val kMutableProperty2Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty2Impl)
val kProperty0Impl = calc { symbolTable.referenceClass(context.reflectionTypes.kProperty0Impl) }
val kProperty1Impl = calc { symbolTable.referenceClass(context.reflectionTypes.kProperty1Impl) }
val kProperty2Impl = calc { symbolTable.referenceClass(context.reflectionTypes.kProperty2Impl) }
val kMutableProperty0Impl = calc { symbolTable.referenceClass(context.reflectionTypes.kMutableProperty0Impl) }
val kMutableProperty1Impl = calc { symbolTable.referenceClass(context.reflectionTypes.kMutableProperty1Impl) }
val kMutableProperty2Impl = calc { symbolTable.referenceClass(context.reflectionTypes.kMutableProperty2Impl) }
// val kLocalDelegatedPropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedPropertyImpl)
// val kLocalDelegatedMutablePropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedMutablePropertyImpl)
@@ -0,0 +1,122 @@
/*
* 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.
*/
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrAnonymousInitializer
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrInstanceInitializerCall
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import java.util.*
class InitializersLowering(val context: CommonBackendContext, val declarationOrigin: IrDeclarationOrigin) : ClassLoweringPass {
override fun lower(irClass: IrClass) {
val classInitializersBuilder = ClassInitializersBuilder(irClass)
irClass.acceptChildrenVoid(classInitializersBuilder)
classInitializersBuilder.transformInstanceInitializerCallsInConstructors(irClass)
classInitializersBuilder.createStaticInitializationMethod(irClass)
}
private inner class ClassInitializersBuilder(val irClass: IrClass) : IrElementVisitorVoid {
val staticInitializerStatements = ArrayList<IrStatement>()
val instanceInitializerStatements = ArrayList<IrStatement>()
override fun visitElement(element: IrElement) {
// skip everything else
}
override fun visitField(declaration: IrField) {
val irFieldInitializer = declaration.initializer?.expression ?: return
val receiver =
if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField
IrGetValueImpl(irFieldInitializer.startOffset, irFieldInitializer.endOffset,
irClass.descriptor.thisAsReceiverParameter)
else null
val irSetField = IrSetFieldImpl(
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
declaration.descriptor,
receiver,
irFieldInitializer,
null, null
)
if (DescriptorUtils.isStaticDeclaration(declaration.descriptor)) {
staticInitializerStatements.add(irSetField)
}
else {
instanceInitializerStatements.add(irSetField)
}
}
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) {
instanceInitializerStatements.addAll(declaration.body.statements)
}
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.builtIns.unitType, null,
instanceInitializerStatements.map { it.copy() })
}
})
}
fun createStaticInitializationMethod(irClass: IrClass) {
val staticInitializerDescriptor = SimpleFunctionDescriptorImpl.create(
irClass.descriptor, Annotations.EMPTY, clinitName,
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
)
staticInitializerDescriptor.initialize(
null, null, emptyList(), emptyList(),
irClass.descriptor.builtIns.unitType,
Modality.FINAL, Visibilities.PUBLIC
)
irClass.declarations.add(
IrFunctionImpl(irClass.startOffset, irClass.endOffset, declarationOrigin,
staticInitializerDescriptor,
IrBlockBodyImpl(irClass.startOffset, irClass.endOffset,
staticInitializerStatements.map { it.copy() }))
)
}
}
companion object {
val clinitName = Name.special("<clinit>")
fun IrStatement.copy() = deepCopyWithSymbols()
fun IrExpression.copy() = deepCopyWithSymbols()
}
}
@@ -0,0 +1,49 @@
/*
* 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.
*/
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
class PropertiesLowering : IrElementTransformerVoid(), FileLoweringPass {
override fun lower(irFile: IrFile) {
irFile.accept(this, null)
}
override fun visitFile(declaration: IrFile): IrFile {
declaration.transformChildrenVoid(this)
declaration.declarations.transformFlat { lowerProperty(it) }
return declaration
}
override fun visitClass(declaration: IrClass): IrStatement {
declaration.transformChildrenVoid(this)
declaration.declarations.transformFlat { lowerProperty(it) }
return declaration
}
private fun lowerProperty(declaration: IrDeclaration): List<IrDeclaration>? =
if (declaration is IrProperty)
ArrayList<IrDeclaration>(3).apply {
if (!DescriptorUtils.isAnnotationClass(declaration.descriptor.containingDeclaration)) {
addIfNotNull(declaration.backingField)
}
addIfNotNull(declaration.getter)
addIfNotNull(declaration.setter)
}
else
null
}