backend/common: extract common part from copied sources

This commit is contained in:
Svyatoslav Scherbina
2016-12-08 11:22:52 +07:00
committed by SvyatoslavScherbina
parent 191c98ec60
commit 0fec2e743c
5 changed files with 18 additions and 220 deletions
@@ -14,20 +14,12 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.jvm
package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager
import org.jetbrains.kotlin.backend.jvm.descriptors.SpecialDescriptorsFactory
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
import org.jetbrains.kotlin.backend.common.descriptors.SharedVariablesManager
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
class JvmBackendContext(
val state: GenerationState,
val psiSourceManager: PsiSourceManager,
val irBuiltIns: IrBuiltIns
) {
val builtIns = state.module.builtIns
val specialDescriptorsFactory = SpecialDescriptorsFactory(psiSourceManager, builtIns)
val sharedVariablesManager = JvmSharedVariablesManager(builtIns)
interface BackendContext {
val builtIns: KotlinBuiltIns
val sharedVariablesManager: SharedVariablesManager
}
@@ -14,9 +14,8 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.jvm
package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.backend.jvm.lower.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -26,27 +25,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
class JvmLower(val context: JvmBackendContext) {
fun lower(irFile: IrFile) {
// TODO run lowering passes as callbacks in bottom-up visitor
FileClassLowering(context).lower(irFile)
ConstAndJvmFieldPropertiesLowering().lower(irFile)
PropertiesLowering().lower(irFile)
InterfaceLowering(context.state).runOnFilePostfix(irFile)
InterfaceDelegationLowering(context.state).runOnFilePostfix(irFile)
SharedVariablesLowering(context).runOnFilePostfix(irFile)
InnerClassesLowering(context).runOnFilePostfix(irFile)
InnerClassConstructorCallsLowering(context).runOnFilePostfix(irFile)
LocalFunctionsLowering(context).runOnFilePostfix(irFile)
EnumClassLowering(context).runOnFilePostfix(irFile)
ObjectClassLowering(context).runOnFilePostfix(irFile)
InitializersLowering(context).runOnFilePostfix(irFile)
SingletonReferencesLowering(context).runOnFilePostfix(irFile)
SyntheticAccessorLowering(context.state).lower(irFile)
BridgeLowering(context.state).runOnFilePostfix(irFile)
}
}
interface FileLoweringPass {
fun lower(irFile: IrFile)
}
@@ -14,190 +14,18 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.jvm.descriptors
package org.jetbrains.kotlin.backend.common.descriptors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.*
interface SharedVariablesManager {
fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor
fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement
fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression
fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression
}
class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesManager {
private val kotlinJvmInternalPackage = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.jvm.internal"))
private val refNamespaceClass = KnownClassDescriptor.createClass(Name.identifier("Ref"), kotlinJvmInternalPackage, listOf(builtIns.anyType))
private class PrimitiveRefDescriptorsProvider(type: KotlinType, refClass: ClassDescriptor) {
val refType: KotlinType = refClass.defaultType
val refConstructor: ClassConstructorDescriptor =
ClassConstructorDescriptorImpl.create(refClass, Annotations.EMPTY, true, SourceElement.NO_SOURCE).apply {
initialize(emptyList(), Visibilities.PUBLIC, emptyList())
returnType = refType
}
val elementField: PropertyDescriptor =
PropertyDescriptorImpl.create(
refClass, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, true,
Name.identifier("element"), CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE,
false, false, false, false
).initialize(type, dispatchReceiverParameter = refClass.thisAsReceiverParameter)
}
private val primitiveRefDescriptorProviders: Map<PrimitiveType, PrimitiveRefDescriptorsProvider> =
PrimitiveType.values().associate {
val type = builtIns.getPrimitiveKotlinType(it)
val refClassName = Name.identifier(it.typeName.asString() + "Ref")
val refClass = KnownClassDescriptor.createClass(refClassName, refNamespaceClass, listOf(builtIns.anyType))
it to PrimitiveRefDescriptorsProvider(type, refClass)
}
private inner class ObjectRefDescriptorsProvider {
val genericRefClass: ClassDescriptor =
KnownClassDescriptor.createClassWithTypeParameters(
Name.identifier("ObjectRef"), refNamespaceClass, listOf(builtIns.anyType), listOf(Name.identifier("T"))
)
val genericRefConstructor: ClassConstructorDescriptor =
ClassConstructorDescriptorImpl.create(genericRefClass, Annotations.EMPTY, true, SourceElement.NO_SOURCE).apply {
initialize(emptyList(), Visibilities.PUBLIC)
val typeParameter = typeParameters[0]
val typeParameterType = KotlinTypeFactory.simpleType(Annotations.EMPTY, typeParameter.typeConstructor, listOf(), false, MemberScope.Empty)
returnType = KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, genericRefClass, listOf(TypeProjectionImpl(Variance.INVARIANT, typeParameterType)))
}
val constructorTypeParameter: TypeParameterDescriptor =
genericRefConstructor.typeParameters[0]
fun getSubstitutedRefConstructor(valueType: KotlinType): ClassConstructorDescriptor =
genericRefConstructor.substitute(TypeSubstitutor.create(
mapOf(constructorTypeParameter.typeConstructor to TypeProjectionImpl(Variance.INVARIANT, valueType))
))!!
val genericElementField: PropertyDescriptor =
PropertyDescriptorImpl.create(
genericRefClass, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, true,
Name.identifier("element"), CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE,
false, false, false, false
).initialize(
type = builtIns.anyType,
dispatchReceiverParameter = genericRefClass.thisAsReceiverParameter
)
fun getRefType(valueType: KotlinType) =
KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, genericRefClass, listOf(TypeProjectionImpl(Variance.INVARIANT, valueType)))
}
private val objectRefDescriptorsProvider = ObjectRefDescriptorsProvider()
override fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor =
LocalVariableDescriptor(
variableDescriptor.containingDeclaration, variableDescriptor.annotations, variableDescriptor.name,
getSharedVariableType(variableDescriptor.type),
false, false, variableDescriptor.source
)
override fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement {
val valueType = originalDeclaration.descriptor.type
val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)]
val refConstructor =
primitiveRefDescriptorsProvider?.refConstructor ?:
objectRefDescriptorsProvider.getSubstitutedRefConstructor(valueType)
val refConstructorTypeArguments =
if (primitiveRefDescriptorsProvider != null) null
else mapOf(objectRefDescriptorsProvider.constructorTypeParameter to valueType)
val elementPropertyDescriptor =
primitiveRefDescriptorsProvider?.elementField ?:
objectRefDescriptorsProvider.genericElementField
val refConstructorCall = IrCallImpl(
originalDeclaration.startOffset, originalDeclaration.endOffset,
refConstructor, refConstructorTypeArguments
)
val sharedVariableDeclaration = IrVariableImpl(
originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.origin,
sharedVariableDescriptor, refConstructorCall
)
val initializer = originalDeclaration.initializer ?:
return sharedVariableDeclaration
val sharedVariableInitialization = IrSetFieldImpl(
initializer.startOffset, initializer.endOffset,
elementPropertyDescriptor,
IrGetValueImpl(initializer.startOffset, initializer.endOffset, sharedVariableDescriptor),
initializer
)
return IrCompositeImpl(
originalDeclaration.startOffset, originalDeclaration.endOffset, builtIns.unitType, null,
listOf(sharedVariableDeclaration, sharedVariableInitialization)
)
}
private fun getElementFieldDescriptor(valueType: KotlinType): PropertyDescriptor {
val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)]
return primitiveRefDescriptorsProvider?.elementField ?:
objectRefDescriptorsProvider.genericElementField
}
override fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression =
IrGetFieldImpl(
originalGet.startOffset, originalGet.endOffset,
getElementFieldDescriptor(originalGet.descriptor.type),
IrGetValueImpl(originalGet.startOffset, originalGet.endOffset, sharedVariableDescriptor),
originalGet.origin
)
override fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression =
IrSetFieldImpl(
originalSet.startOffset, originalSet.endOffset,
getElementFieldDescriptor(originalSet.descriptor.type),
IrGetValueImpl(originalSet.startOffset, originalSet.endOffset, sharedVariableDescriptor),
originalSet.value,
originalSet.origin
)
private fun getSharedVariableType(valueType: KotlinType): KotlinType =
primitiveRefDescriptorProviders[getPrimitiveType(valueType)]?.refType ?:
objectRefDescriptorsProvider.getRefType(valueType)
private fun getPrimitiveType(type: KotlinType): PrimitiveType? =
when {
KotlinBuiltIns.isBoolean(type) -> PrimitiveType.BOOLEAN
KotlinBuiltIns.isChar(type) -> PrimitiveType.CHAR
KotlinBuiltIns.isByte(type) -> PrimitiveType.BYTE
KotlinBuiltIns.isShort(type) -> PrimitiveType.SHORT
KotlinBuiltIns.isInt(type) -> PrimitiveType.INT
KotlinBuiltIns.isLong(type) -> PrimitiveType.LONG
KotlinBuiltIns.isFloat(type) -> PrimitiveType.FLOAT
KotlinBuiltIns.isDouble(type) -> PrimitiveType.DOUBLE
else -> null
}
}
}
@@ -14,12 +14,12 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.jvm.lower
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.AbstractClosureAnnotator
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.Closure
import org.jetbrains.kotlin.backend.jvm.ClassLoweringPass
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
@@ -42,7 +42,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
class LocalFunctionsLowering(val context: JvmBackendContext): ClassLoweringPass {
class LocalFunctionsLowering(val context: BackendContext): ClassLoweringPass {
override fun lower(irClass: IrClass) {
irClass.declarations.transformFlat { memberDeclaration ->
if (memberDeclaration is IrFunction)
@@ -14,10 +14,10 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.jvm.lower
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.jvm.FunctionLoweringPass
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.FunctionLoweringPass
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.ir.expressions.IrValueAccessExpression
import org.jetbrains.kotlin.ir.visitors.*
import java.util.*
class SharedVariablesLowering(val context: JvmBackendContext) : FunctionLoweringPass {
class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPass {
override fun lower(irFunction: IrFunction) {
SharedVariablesTransformer(irFunction).lowerSharedVariables()
}