From c248dd29c21699ab22ff6fd7a77f1395c9b58632 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 19 Feb 2019 17:43:44 +0300 Subject: [PATCH] IR: declaration builders, initial iteration, use in some JVM lowerings --- .../declarations/declarationBuilders.kt | 121 ++++++++++ .../jvm/lower/CallableReferenceLowering.kt | 208 +++++++---------- .../jvm/lower/SyntheticAccessorLowering.kt | 217 ++++++------------ .../kotlin/ir/builders/IrElementBuilder.kt | 26 +++ .../builders/declarations/IrClassBuilder.kt | 33 +++ .../declarations/IrDeclarationBuilder.kt | 28 +++ .../builders/declarations/IrFieldBuilder.kt | 27 +++ .../declarations/IrFunctionBuilder.kt | 48 ++++ .../declarations/IrValueParameterBuilder.kt | 30 +++ 9 files changed, 459 insertions(+), 279 deletions(-) create mode 100644 compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrElementBuilder.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrClassBuilder.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrDeclarationBuilder.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFieldBuilder.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFunctionBuilder.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrValueParameterBuilder.kt diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt new file mode 100644 index 00000000000..63af1303384 --- /dev/null +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt @@ -0,0 +1,121 @@ +/* + * Copyright 2010-2019 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.ir.builders.declarations + +import org.jetbrains.kotlin.backend.common.descriptors.* +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.* +import org.jetbrains.kotlin.ir.symbols.impl.* +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.name.Name + +fun IrClassBuilder.buildClass(): IrClass { + val wrappedDescriptor = WrappedClassDescriptor() + return IrClassImpl( + startOffset, endOffset, origin, + IrClassSymbolImpl(wrappedDescriptor), + name, kind, visibility, modality, isCompanion, isInner, isData, isExternal, isInline + ).also { + wrappedDescriptor.bind(it) + } +} + +inline fun buildClass(b: IrClassBuilder.() -> Unit) = + IrClassBuilder().run { + b() + buildClass() + } + + +fun IrFieldBuilder.buildField(): IrField { + val wrappedDescriptor = WrappedFieldDescriptor() + return IrFieldImpl( + startOffset, endOffset, origin, + IrFieldSymbolImpl(wrappedDescriptor), + name, type, visibility, isFinal, isExternal, isStatic + ).also { + wrappedDescriptor.bind(it) + } +} + +inline fun buildField(b: IrFieldBuilder.() -> Unit) = + IrFieldBuilder().run { + b() + buildField() + } + +fun IrFunctionBuilder.buildFun(): IrSimpleFunction { + val wrappedDescriptor = WrappedSimpleFunctionDescriptor() + return IrFunctionImpl( + startOffset, endOffset, origin, + IrSimpleFunctionSymbolImpl(wrappedDescriptor), + name, visibility, modality, returnType, + isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend + ).also { + wrappedDescriptor.bind(it) + } +} + +fun IrFunctionBuilder.buildConstructor(): IrConstructor { + val wrappedDescriptor = WrappedClassConstructorDescriptor() + return IrConstructorImpl( + startOffset, endOffset, origin, + IrConstructorSymbolImpl(wrappedDescriptor), + Name.special(""), + visibility, returnType, + isInline = isInline, isExternal = isExternal, isPrimary = isPrimary + ).also { + wrappedDescriptor.bind(it) + } +} + +inline fun buildFun(b: IrFunctionBuilder.() -> Unit): IrSimpleFunction = + IrFunctionBuilder().run { + b() + buildFun() + } + +inline fun buildConstructor(b: IrFunctionBuilder.() -> Unit): IrConstructor = + IrFunctionBuilder().run { + b() + buildConstructor() + } + +fun IrValueParameterBuilder.build(): IrValueParameter { + val wrappedDescriptor = WrappedValueParameterDescriptor() + return IrValueParameterImpl( + startOffset, endOffset, origin, + IrValueParameterSymbolImpl(wrappedDescriptor), + name, index, type, varargElementType, isCrossInline, isNoinline + ).also { + wrappedDescriptor.bind(it) + } +} + +inline fun buildValueParameter(b: IrValueParameterBuilder.() -> Unit): IrValueParameter = + IrValueParameterBuilder().run { + b() + build() + } + +inline fun IrFunction.addValueParameter(b: IrValueParameterBuilder.() -> Unit): IrValueParameter = + IrValueParameterBuilder().run { + b() + if (index == UNDEFINED_PARAMETER_INDEX) { + index = valueParameters.size + } + build().also { valueParameter -> + valueParameters.add(valueParameter) + valueParameter.parent = this@addValueParameter + } + } + +fun IrFunction.addValueParameter(name: Name, type: IrType, origin: IrDeclarationOrigin): IrValueParameter = + addValueParameter { + this.name = name + this.type = type + this.origin = origin + } \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt index 5f98bbe6d44..bed32dfb2af 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt @@ -18,24 +18,31 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext -import org.jetbrains.kotlin.backend.common.descriptors.* +import org.jetbrains.kotlin.backend.common.descriptors.isFunctionOrKFunctionType +import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor -import org.jetbrains.kotlin.backend.common.lower.* +import org.jetbrains.kotlin.backend.common.lower.createIrBuilder +import org.jetbrains.kotlin.backend.common.lower.irBlock +import org.jetbrains.kotlin.backend.common.lower.irIfThen import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.builders.declarations.buildClass +import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor +import org.jetbrains.kotlin.ir.builders.declarations.buildField +import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* -import org.jetbrains.kotlin.ir.symbols.* -import org.jetbrains.kotlin.ir.symbols.impl.* +import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection @@ -177,9 +184,6 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL var useVararg: Boolean = false fun build(): BuiltFunctionReference { - val startOffset = irFunctionReference.startOffset - val endOffset = irFunctionReference.endOffset - val returnType = irFunctionReference.symbol.owner.returnType val functionReferenceClassSuperTypes: MutableList = mutableListOf( functionReferenceOrLambda.owner.defaultType // type arguments? @@ -206,12 +210,11 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL ) var suspendFunctionClass: IrClass? = null - var suspendFunctionClassTypeParameters: List? = null val lastParameterType = unboundCalleeParameters.lastOrNull()?.type if ((lastParameterType as? IrSimpleType)?.classifier == continuationClass) { // If the last parameter is Continuation<> inherit from SuspendFunction. suspendFunctionClass = context.getIrClass(FqName("kotlin.Suspendfunction${numberOfParameters - 1}")).owner - suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) + + val suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) + (lastParameterType.arguments.single() as IrTypeProjection).type functionReferenceClassSuperTypes += IrSimpleTypeImpl( suspendFunctionClass.symbol, @@ -221,22 +224,14 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL ) } - val functionReferenceClassDescriptor = WrappedClassDescriptor() - functionReferenceClass = IrClassImpl( - startOffset, endOffset, - JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL, - IrClassSymbolImpl(functionReferenceClassDescriptor), - name = "${callee.name}\$${functionReferenceCount++}".synthesizedName, - kind = ClassKind.CLASS, - visibility = Visibilities.PUBLIC, - modality = Modality.FINAL, - isCompanion = false, - isInner = false, - isData = false, - isExternal = false, - isInline = false - ).apply { - functionReferenceClassDescriptor.bind(this) + functionReferenceClass = buildClass { + setSourceRange(irFunctionReference) + origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + name = "${callee.name}\$${functionReferenceCount++}".synthesizedName + kind = ClassKind.CLASS + visibility = Visibilities.PUBLIC + modality = Modality.FINAL + }.apply { parent = referenceParent superTypes.addAll(functionReferenceClassSuperTypes) createImplicitParameterDeclarationWithWrappedDescriptor() @@ -256,9 +251,12 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL functionReferenceClass.declarations.add(invokeMethod) if (!isLambda) { - val getSignatureMethod = createGetSignatureMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getSignature"}!!) - val getNameMethod = createGetNameMethod(functionReferenceOrLambda.owner.properties.find { it.name.asString() == "name" }!!) - val getOwnerMethod = createGetOwnerMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getOwner" }!!) + val getSignatureMethod = + createGetSignatureMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getSignature"}!!) + val getNameMethod = + createGetNameMethod(functionReferenceOrLambda.owner.properties.find { it.name.asString() == "name" }!!) + val getOwnerMethod = + createGetOwnerMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getOwner" }!!) val suspendInvokeMethod = if (suspendFunctionClass != null) { @@ -276,21 +274,15 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL return BuiltFunctionReference(functionReferenceClass, constructor) } - private fun createConstructor(): IrConstructor { - val descriptor = WrappedClassConstructorDescriptor() - return IrConstructorImpl( - irFunctionReference.startOffset, irFunctionReference.endOffset, - JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL, - IrConstructorSymbolImpl(descriptor), - name = Name.special(""), - visibility = Visibilities.PUBLIC, - returnType = functionReferenceClass.defaultType, - isInline = false, - isExternal = false, + private fun createConstructor(): IrConstructor = + buildConstructor { + setSourceRange(irFunctionReference) + origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + visibility = Visibilities.PUBLIC + returnType = functionReferenceClass.defaultType isPrimary = true - ).apply { + }.apply { val constructor = this - descriptor.bind(this) parent = functionReferenceClass val boundArgsSet = boundCalleeParameters.toSet() @@ -341,25 +333,17 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL +IrInstanceInitializerCallImpl(startOffset, endOffset, functionReferenceClass.symbol, context.irBuiltIns.unitType) } } - } - private fun createInvokeMethod(superFunction: IrSimpleFunction) : IrSimpleFunction { - val descriptor = WrappedSimpleFunctionDescriptor() - return IrFunctionImpl( - irFunctionReference.startOffset, irFunctionReference.endOffset, - JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL, - IrSimpleFunctionSymbolImpl(descriptor), - Name.identifier("invoke"), - Visibilities.PUBLIC, - Modality.FINAL, - returnType = callee.returnType, - isInline = false, // not sure - isExternal = false, - isTailrec = false, + private fun createInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction = + buildFun { + setSourceRange(irFunctionReference) + origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + name = Name.identifier("invoke") + visibility = Visibilities.PUBLIC + returnType = callee.returnType isSuspend = superFunction.isSuspend - ).apply { + }.apply { val function = this - descriptor.bind(this) parent = functionReferenceClass overriddenSymbols.add(superFunction.symbol) dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function) @@ -448,47 +432,29 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL } } - } - private fun buildField(name: Name, type: IrType): IrField { - val descriptor = WrappedFieldDescriptor() - // TODO: make it synthetic - val field = IrFieldImpl( - irFunctionReference.startOffset, - irFunctionReference.endOffset, - JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL, - IrFieldSymbolImpl(descriptor), - name, - type, - JavaVisibilities.PACKAGE_VISIBILITY, - isFinal = true, - isExternal = false, - isStatic = false - ).apply { - descriptor.bind(this) + private fun buildField(fieldName: Name, fieldType: IrType): IrField = + buildField { + setSourceRange(irFunctionReference) + origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + name = fieldName + type = fieldType + visibility = JavaVisibilities.PACKAGE_VISIBILITY + isFinal = true + }.also { + functionReferenceClass.declarations.add(it) } - functionReferenceClass.declarations.add(field) - return field - } - - private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction { - val descriptor = WrappedSimpleFunctionDescriptor() - return IrFunctionImpl( - irFunctionReference.startOffset, irFunctionReference.endOffset, - JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL, - IrSimpleFunctionSymbolImpl(descriptor), - Name.identifier("getSignature"), - superFunction.visibility, - superFunction.modality, - returnType = superFunction.returnType, - isInline = false, - isExternal = false, - isTailrec = false, - isSuspend = false - ).apply { + private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction = + buildFun { + setSourceRange(irFunctionReference) + origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + name = Name.identifier("getSignature") + returnType = superFunction.returnType + visibility = superFunction.visibility + modality = superFunction.modality + }.apply { val function = this - descriptor.bind(this) parent = functionReferenceClass overriddenSymbols.add(superFunction.symbol) dispatchReceiverParameter = functionReferenceClass.thisReceiver!!.copyTo(function) @@ -505,26 +471,18 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL ) } } - } private fun createGetNameMethod(superNameProperty: IrProperty): IrSimpleFunction { val superGetter = superNameProperty.getter!! - val descriptor = WrappedSimpleFunctionDescriptor() - return IrFunctionImpl( - irFunctionReference.startOffset, irFunctionReference.endOffset, - JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL, - IrSimpleFunctionSymbolImpl(descriptor), - Name.identifier("getName"), - superGetter.visibility, - superGetter.modality, - returnType = superGetter.returnType, - isInline = false, - isExternal = false, - isTailrec = false, - isSuspend = false - ).apply { + return buildFun { + setSourceRange(irFunctionReference) + origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + name = Name.identifier("getName") + returnType = superGetter.returnType + visibility = superGetter.visibility + modality = superGetter.modality + }.apply { val function = this - descriptor.bind(this) parent = functionReferenceClass overriddenSymbols.add(superGetter.symbol) dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function) @@ -538,23 +496,16 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL } } - private fun createGetOwnerMethod(superFunction: IrSimpleFunction): IrSimpleFunction { - val descriptor = WrappedSimpleFunctionDescriptor() - return IrFunctionImpl( - functionReferenceClass.startOffset, functionReferenceClass.endOffset, - JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL, - IrSimpleFunctionSymbolImpl(descriptor), - Name.identifier("getOwner"), - superFunction.visibility, - superFunction.modality, - returnType = superFunction.returnType, - isInline = false, - isExternal = false, - isTailrec = false, - isSuspend = false - ).apply { + private fun createGetOwnerMethod(superFunction: IrSimpleFunction): IrSimpleFunction = + buildFun { + setSourceRange(functionReferenceClass) + origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + name = Name.identifier("getOwner") + returnType = superFunction.returnType + visibility = superFunction.visibility + modality = superFunction.modality + }.apply { val function = this - descriptor.bind(this) parent = functionReferenceClass overriddenSymbols.add(superFunction.symbol) dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function) @@ -566,7 +517,6 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL ) } } - } fun IrBuilderWithScope.generateCallableReferenceDeclarationContainer(): IrExpression { val globalContext = this@CallableReferenceLowering.context diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt index 66edceab86a..6a00ae17b85 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt @@ -5,31 +5,32 @@ package org.jetbrains.kotlin.backend.jvm.lower -import org.jetbrains.kotlin.backend.common.* -import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor -import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor -import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor -import org.jetbrains.kotlin.backend.common.ir.* +import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext +import org.jetbrains.kotlin.backend.common.IrElementVisitorVoidWithContext +import org.jetbrains.kotlin.backend.common.ScopeWithIr +import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom +import org.jetbrains.kotlin.backend.common.ir.copyValueParametersToStatic +import org.jetbrains.kotlin.backend.common.ir.remapTypeParameters import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs import org.jetbrains.kotlin.codegen.OwnerKind -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter +import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor +import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl -import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl -import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* -import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl -import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid @@ -82,14 +83,13 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem accumMap: MutableMap, symbolConverter: (FromSyT) -> ToSyT, exprConverter: (ExprT, ToSyT) -> IrDeclarationReference - ): IrExpression { + ): IrExpression = if (!symbol.isAccessible()) { - val accessorSymbol = accumMap.getOrPut(symbol, { symbolConverter(symbol) }) - return exprConverter(expression, accessorSymbol) + val accessorSymbol = accumMap.getOrPut(symbol) { symbolConverter(symbol) } + exprConverter(expression, accessorSymbol) } else { - return expression + expression } - } private fun makeFunctionAccessorSymbol(functionSymbol: IrFunctionSymbol): IrFunctionSymbol = when (functionSymbol) { is IrConstructorSymbol -> functionSymbol.owner.makeConstructorAccessor().symbol @@ -99,19 +99,13 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem private fun IrConstructor.makeConstructorAccessor(): IrConstructor { val source = this - val accessorDescriptor = WrappedClassConstructorDescriptor() - return IrConstructorImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, - IrConstructorSymbolImpl(accessorDescriptor), - name, - Visibilities.PUBLIC, - IrUninitializedType, - isInline = false, - isExternal = false, - isPrimary = false - ).also { accessor -> - accessorDescriptor.bind(accessor) + + return buildConstructor { + origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR + name = source.name + visibility = Visibilities.PUBLIC + + }.also { accessor -> accessor.parent = source.parent pendingTransformations.add { (accessor.parent as IrDeclarationContainer).declarations.add(accessor) } @@ -119,22 +113,11 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem accessor.copyValueParametersToStatic(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR) accessor.returnType = source.returnType.remapTypeParameters(source, accessor) - val markerParameterDescriptor = WrappedValueParameterDescriptor() - val markerParameter = IrValueParameterImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, - IrValueParameterSymbolImpl(markerParameterDescriptor), + accessor.addValueParameter( Name.identifier("marker"), - index = accessor.valueParameters.size, - type = context.ir.symbols.defaultConstructorMarker.owner.defaultType, - varargElementType = null, - isCrossinline = false, - isNoinline = false - ).apply { - markerParameterDescriptor.bind(this) - parent = accessor - } - accessor.valueParameters.add(markerParameter) + context.ir.symbols.defaultConstructorMarker.owner.defaultType, + JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR + ) accessor.body = IrExpressionBodyImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, @@ -154,21 +137,12 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem private fun IrSimpleFunction.makeSimpleFunctionAccessor(): IrSimpleFunction { val source = this - val accessorDescriptor = WrappedSimpleFunctionDescriptor() - return IrFunctionImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, - IrSimpleFunctionSymbolImpl(accessorDescriptor), - source.descriptor.accessorName(), - Visibilities.PUBLIC, - Modality.FINAL, - IrUninitializedType, - isInline = false, - isExternal = false, - isTailrec = false, + return buildFun { + origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR + name = source.descriptor.accessorName() + visibility = Visibilities.PUBLIC isSuspend = source.isSuspend - ).also { accessor -> - accessorDescriptor.bind(accessor) + }.also { accessor -> accessor.parent = source.parent pendingTransformations.add { (accessor.parent as IrDeclarationContainer).declarations.add(accessor) } @@ -193,48 +167,27 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem copyAllParamsToArgs(it, accessor) } - private fun makeGetterAccessorSymbol(fieldSymbol: IrFieldSymbol): IrSimpleFunctionSymbol { - val accessorDescriptor = WrappedSimpleFunctionDescriptor() - return IrFunctionImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, - IrSimpleFunctionSymbolImpl(accessorDescriptor), - fieldSymbol.descriptor.accessorNameForGetter(), - Visibilities.PUBLIC, - Modality.FINAL, - fieldSymbol.owner.type, - isInline = false, - isExternal = false, - isTailrec = false, - isSuspend = false - ).also { accessor -> - accessorDescriptor.bind(accessor) + private fun makeGetterAccessorSymbol(fieldSymbol: IrFieldSymbol): IrSimpleFunctionSymbol = + buildFun { + origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR + name = fieldSymbol.descriptor.accessorNameForGetter() + visibility = Visibilities.PUBLIC + modality = Modality.FINAL + returnType = fieldSymbol.owner.type + }.also { accessor -> accessor.parent = fieldSymbol.owner.parent pendingTransformations.add { (accessor.parent as IrDeclarationContainer).declarations.add(accessor) } if (!fieldSymbol.owner.isStatic) { - val receiverDescriptor = WrappedValueParameterDescriptor() - accessor.valueParameters.add( - IrValueParameterImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, - IrValueParameterSymbolImpl(receiverDescriptor), - Name.identifier("\$this"), - index = 0, - type = (fieldSymbol.owner.parent as IrClass).defaultType, - varargElementType = null, - isCrossinline = false, - isNoinline = false - ).apply { - receiverDescriptor.bind(this) - parent = accessor - } + accessor.addValueParameter( + Name.identifier("\$this"), + (fieldSymbol.owner.parent as IrClass).defaultType, + JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR ) } accessor.body = createAccessorBodyForGetter(fieldSymbol.owner, accessor) }.symbol - } private fun createAccessorBodyForGetter(targetField: IrField, accessor: IrSimpleFunction): IrBody { val resolvedTargetField = targetField.resolveFakeOverride()!! @@ -252,65 +205,29 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem ) } - private fun makeSetterAccessorSymbol(fieldSymbol: IrFieldSymbol): IrSimpleFunctionSymbol { - val accessorDescriptor = WrappedSimpleFunctionDescriptor() - return IrFunctionImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, - IrSimpleFunctionSymbolImpl(accessorDescriptor), - fieldSymbol.descriptor.accessorNameForSetter(), - Visibilities.PUBLIC, - Modality.FINAL, - returnType = context.irBuiltIns.unitType, - isInline = false, - isExternal = false, - isTailrec = false, - isSuspend = false - ).also { accessor -> - accessorDescriptor.bind(accessor) + private fun makeSetterAccessorSymbol(fieldSymbol: IrFieldSymbol): IrSimpleFunctionSymbol = + buildFun { + origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR + name = fieldSymbol.descriptor.accessorNameForSetter() + visibility = Visibilities.PUBLIC + modality = Modality.FINAL + returnType = context.irBuiltIns.unitType + }.also { accessor -> accessor.parent = fieldSymbol.owner.parent pendingTransformations.add { (accessor.parent as IrDeclarationContainer).declarations.add(accessor) } if (!fieldSymbol.owner.isStatic) { - val receiverDescriptor = WrappedValueParameterDescriptor() - accessor.valueParameters.add( - IrValueParameterImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, - IrValueParameterSymbolImpl(receiverDescriptor), - Name.identifier("\$this"), - index = 0, - type = (fieldSymbol.owner.parent as IrClass).defaultType, - varargElementType = null, - isCrossinline = false, - isNoinline = false - ).apply { - receiverDescriptor.bind(this) - parent = accessor - } + accessor.addValueParameter( + Name.identifier("\$this"), + (fieldSymbol.owner.parent as IrClass).defaultType, + JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR ) } - val valueDescriptor = WrappedValueParameterDescriptor() - accessor.valueParameters.add( - IrValueParameterImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, - IrValueParameterSymbolImpl(valueDescriptor), - Name.identifier("value"), - index = if (fieldSymbol.owner.isStatic) 0 else 1, - type = fieldSymbol.owner.type, - varargElementType = null, - isCrossinline = false, - isNoinline = false - ).apply { - valueDescriptor.bind(this) - parent = accessor - } - ) + + accessor.addValueParameter(Name.identifier("value"), fieldSymbol.owner.type, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR) accessor.body = createAccessorBodyForSetter(fieldSymbol.owner, accessor) }.symbol - } private fun createAccessorBodyForSetter(targetField: IrField, accessor: IrSimpleFunction): IrBody { val resolvedTargetField = targetField.resolveFakeOverride()!! @@ -418,12 +335,12 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem } delegateTo.dispatchReceiverParameter?.let { call.dispatchReceiver = - IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol) + IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol) } delegateTo.extensionReceiverParameter?.let { call.extensionReceiver = - IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol) + IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol) } delegateTo.valueParameters.forEachIndexed { i, _ -> @@ -472,9 +389,8 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem // The only two visibilities where Kotlin rules differ from JVM rules. if (!Visibilities.isPrivate(declaration.visibility) && declaration.visibility != Visibilities.PROTECTED) return true - val symbolDeclarationContainer = (declaration.parent as? IrDeclarationContainer) as? IrElement // If local variables are accessible by Kotlin rules, they also are by Java rules. - if (symbolDeclarationContainer == null) return true + val symbolDeclarationContainer = (declaration.parent as? IrDeclarationContainer) as? IrElement ?: return true // Within inline functions, we have to assume the worst. if (inlinedLambdasCollector.isInlineNonpublicContext(allScopes)) @@ -497,8 +413,8 @@ private class InlinedLambdasCollector : IrElementVisitorVoidWithContext() { private val inlinedLambdasInNonPublicContexts = mutableSetOf() fun isInlineNonpublicContext(scopeStack: List): Boolean { - val currentFunction = scopeStack.map { it.irElement }. lastOrNull { it is IrFunction } as? IrFunction ?: return false - return (currentFunction.isInline == true && currentFunction.visibility in setOf(Visibilities.PRIVATE, Visibilities.PROTECTED)) + val currentFunction = scopeStack.map { it.irElement }.lastOrNull { it is IrFunction } as? IrFunction ?: return false + return (currentFunction.isInline && currentFunction.visibility in setOf(Visibilities.PRIVATE, Visibilities.PROTECTED)) || currentFunction in inlinedLambdasInNonPublicContexts } @@ -513,7 +429,8 @@ private class InlinedLambdasCollector : IrElementVisitorVoidWithContext() { val argument = expression.getValueArgument(i)?.removeBlocks() if (argument is IrFunctionReference && argument.symbol.owner.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA && - !callTarget.valueParameters[i].isNoinline) { + !callTarget.valueParameters[i].isNoinline + ) { inlinedLambdasInNonPublicContexts.add(argument.symbol.owner) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrElementBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrElementBuilder.kt new file mode 100644 index 00000000000..9ddb8800ec5 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrElementBuilder.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2019 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.ir.builders + +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET + +abstract class IrElementBuilder { + + var startOffset: Int = UNDEFINED_OFFSET + var endOffset: Int = UNDEFINED_OFFSET + + fun updateFrom(from: IrElement) { + startOffset = from.startOffset + endOffset = from.endOffset + } +} + + +fun IrElementBuilder.setSourceRange(from: IrElement) { + startOffset = from.startOffset + endOffset = from.endOffset +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrClassBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrClassBuilder.kt new file mode 100644 index 00000000000..6543e8df899 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrClassBuilder.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2019 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.ir.builders.declarations + +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.ir.declarations.IrClass + +class IrClassBuilder : IrDeclarationBuilder() { + var kind: ClassKind = ClassKind.CLASS + var modality: Modality = Modality.FINAL + + var isCompanion: Boolean = false + var isInner: Boolean = false + var isData: Boolean = false + var isExternal: Boolean = false + var isInline: Boolean = false + + fun updateFrom(from: IrClass) { + super.updateFrom(from) + + kind = from.kind + modality = from.modality + isCompanion = from.isCompanion + isInner = from.isInner + isData = from.isData + isExternal = from.isExternal + isInline = from.isInline + } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrDeclarationBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrDeclarationBuilder.kt new file mode 100644 index 00000000000..52ff7432a09 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrDeclarationBuilder.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2019 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.ir.builders.declarations + +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.ir.builders.IrElementBuilder +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.name.Name + +abstract class IrDeclarationBuilder : IrElementBuilder() { + + var origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED + var visibility: Visibility = Visibilities.PUBLIC + + lateinit var name: Name + + fun updateFrom(from: IrDeclaration) { + super.updateFrom(from) + + origin = from.origin + visibility = if (from is IrDeclarationWithVisibility) from.visibility else Visibilities.PUBLIC + } + +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFieldBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFieldBuilder.kt new file mode 100644 index 00000000000..e28ae0a3deb --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFieldBuilder.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2019 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.ir.builders.declarations + +import org.jetbrains.kotlin.ir.declarations.IrField +import org.jetbrains.kotlin.ir.types.IrType + +class IrFieldBuilder : IrDeclarationBuilder() { + + lateinit var type: IrType + + var isFinal: Boolean = false + var isExternal: Boolean = false + var isStatic: Boolean = false + + fun updateFrom(from: IrField) { + super.updateFrom(from) + + type = from.type + isFinal = from.isFinal + isExternal = from.isExternal + isStatic = from.isStatic + } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFunctionBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFunctionBuilder.kt new file mode 100644 index 00000000000..204eca9e101 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFunctionBuilder.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2019 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.ir.builders.declarations + +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.ir.declarations.IrConstructor +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType + +class IrFunctionBuilder : IrDeclarationBuilder() { + + var isInline: Boolean = false + var isExternal: Boolean = false + + var returnType: IrType = IrUninitializedType + + var modality: Modality = Modality.FINAL + var isTailrec: Boolean = false + var isSuspend: Boolean = false + + var isPrimary: Boolean = false + + fun updateFrom(from: IrFunction) { + super.updateFrom(from) + + isInline = from.isInline + isExternal = from.isExternal + + if (from is IrSimpleFunction) { + modality = from.modality + isTailrec = from.isTailrec + isSuspend = from.isSuspend + } else { + modality = Modality.FINAL + isTailrec = false + isSuspend = false + } + + if (from is IrConstructor) { + isPrimary = from.isPrimary + } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrValueParameterBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrValueParameterBuilder.kt new file mode 100644 index 00000000000..1cc8c0c7e14 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrValueParameterBuilder.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2019 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.ir.builders.declarations + +import org.jetbrains.kotlin.ir.declarations.IrValueParameter +import org.jetbrains.kotlin.ir.types.IrType + +const val UNDEFINED_PARAMETER_INDEX = -1 + +class IrValueParameterBuilder : IrDeclarationBuilder() { + lateinit var type: IrType + + var index: Int = UNDEFINED_PARAMETER_INDEX + var varargElementType: IrType? = null + var isCrossInline = false + var isNoinline = false + + fun updateFrom(from: IrValueParameter) { + super.updateFrom(from) + + type = from.type + index = from.index + varargElementType = from.varargElementType + isCrossInline = from.isCrossinline + isNoinline = from.isNoinline + } +}