backend: update kotlin-compiler and remove code contributed to Kotlin
Update kotlin-compiler to 1.1-20170112.203631-353 Also remove workarounds for fixed bugs.
This commit is contained in:
committed by
Konstantin Anisimov
parent
abd30d2e04
commit
497de0dc8d
-27
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.SharedVariablesManager
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
|
||||||
|
|
||||||
interface BackendContext {
|
|
||||||
val builtIns: KotlinBuiltIns
|
|
||||||
val irBuiltIns: IrBuiltIns
|
|
||||||
val sharedVariablesManager: SharedVariablesManager
|
|
||||||
}
|
|
||||||
-97
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
|
||||||
|
|
||||||
interface FileLoweringPass {
|
|
||||||
fun lower(irFile: IrFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ClassLoweringPass {
|
|
||||||
fun lower(irClass: IrClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DeclarationContainerLoweringPass {
|
|
||||||
fun lower(irDeclarationContainer: IrDeclarationContainer)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FunctionLoweringPass {
|
|
||||||
fun lower(irFunction: IrFunction)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BodyLoweringPass {
|
|
||||||
fun lower(irBody: IrBody)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
|
||||||
irFile.acceptVoid(object : IrElementVisitorVoid {
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass) {
|
|
||||||
declaration.acceptChildrenVoid(this)
|
|
||||||
lower(declaration)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun DeclarationContainerLoweringPass.asClassLoweringPass() = object : ClassLoweringPass {
|
|
||||||
override fun lower(irClass: IrClass) {
|
|
||||||
this@asClassLoweringPass.lower(irClass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun DeclarationContainerLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
|
||||||
this.asClassLoweringPass().runOnFilePostfix(irFile)
|
|
||||||
this.lower(irFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun BodyLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
|
||||||
irFile.acceptVoid(object : IrElementVisitorVoid {
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitBody(body: IrBody) {
|
|
||||||
body.acceptChildrenVoid(this)
|
|
||||||
lower(body)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun FunctionLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
|
||||||
irFile.acceptVoid(object : IrElementVisitorVoid {
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunction(declaration: IrFunction) {
|
|
||||||
declaration.acceptChildrenVoid(this)
|
|
||||||
lower(declaration)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.descriptors
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
-371
@@ -1,371 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.lower
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
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.IrDeclarationContainer
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
|
||||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
|
||||||
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.descriptorUtil.parents
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class LocalFunctionsLowering(val context: BackendContext): DeclarationContainerLoweringPass {
|
|
||||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
|
||||||
irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
|
|
||||||
if (memberDeclaration is IrFunction)
|
|
||||||
LocalFunctionsTransformer(memberDeclaration).lowerLocalFunctions()
|
|
||||||
else
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LocalFunctionContext(val declaration: IrFunction) {
|
|
||||||
lateinit var closure: Closure
|
|
||||||
|
|
||||||
val closureParametersCount: Int get() = closure.capturedValues.size
|
|
||||||
|
|
||||||
lateinit var transformedDescriptor: FunctionDescriptor
|
|
||||||
|
|
||||||
val old2new: MutableMap<ValueDescriptor, ValueDescriptor> = HashMap()
|
|
||||||
|
|
||||||
var index: Int = -1
|
|
||||||
|
|
||||||
override fun toString(): String =
|
|
||||||
"LocalFunctionContext for ${declaration.descriptor}"
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class LocalFunctionsTransformer(val memberFunction: IrFunction) {
|
|
||||||
val localFunctions: MutableMap<FunctionDescriptor, LocalFunctionContext> = LinkedHashMap()
|
|
||||||
val new2old: MutableMap<ValueDescriptor, ValueDescriptor> = HashMap()
|
|
||||||
|
|
||||||
fun lowerLocalFunctions(): List<IrDeclaration>? {
|
|
||||||
collectLocalFunctions()
|
|
||||||
if (localFunctions.isEmpty()) return null
|
|
||||||
|
|
||||||
collectClosures()
|
|
||||||
|
|
||||||
transformDescriptors()
|
|
||||||
|
|
||||||
rewriteBodies()
|
|
||||||
|
|
||||||
return collectRewrittenDeclarations()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun collectRewrittenDeclarations(): ArrayList<IrDeclaration> =
|
|
||||||
ArrayList<IrDeclaration>(localFunctions.size + 1).apply {
|
|
||||||
add(memberFunction)
|
|
||||||
|
|
||||||
localFunctions.values.mapTo(this) {
|
|
||||||
val original = it.declaration
|
|
||||||
IrFunctionImpl(
|
|
||||||
original.startOffset, original.endOffset, original.origin,
|
|
||||||
it.transformedDescriptor,
|
|
||||||
original.body
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class FunctionBodiesRewriter(val localFunctionContext: LocalFunctionContext?) : IrElementTransformerVoid() {
|
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass): IrStatement {
|
|
||||||
// ignore local classes for now
|
|
||||||
return declaration
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
|
||||||
// replace local function definition with an empty composite
|
|
||||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
|
||||||
val remapped = localFunctionContext?.let { it.old2new[expression.descriptor] }
|
|
||||||
return if (remapped == null)
|
|
||||||
expression
|
|
||||||
else
|
|
||||||
IrGetValueImpl(expression.startOffset, expression.endOffset, remapped, expression.origin)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
val oldCallee = expression.descriptor.original
|
|
||||||
val localFunctionData = localFunctions[oldCallee] ?: return expression
|
|
||||||
|
|
||||||
val newCallee = localFunctionData.transformedDescriptor
|
|
||||||
|
|
||||||
val newCall = createNewCall(expression, newCallee).fillArguments(localFunctionData, expression)
|
|
||||||
|
|
||||||
return newCall
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T : IrMemberAccessExpression> T.fillArguments(calleeContext: LocalFunctionContext, oldExpression: IrMemberAccessExpression): T {
|
|
||||||
val closureParametersCount = calleeContext.closureParametersCount
|
|
||||||
|
|
||||||
mapValueParametersIndexed { index, newValueParameterDescriptor ->
|
|
||||||
val capturedValueDescriptor = new2old[newValueParameterDescriptor] ?:
|
|
||||||
throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
|
||||||
if (index >= closureParametersCount)
|
|
||||||
oldExpression.getValueArgument(capturedValueDescriptor as ValueParameterDescriptor)
|
|
||||||
else {
|
|
||||||
val remappedValueDescriptor = localFunctionContext?.let { it.old2new[capturedValueDescriptor] }
|
|
||||||
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset,
|
|
||||||
remappedValueDescriptor ?: capturedValueDescriptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatchReceiver = oldExpression.dispatchReceiver
|
|
||||||
extensionReceiver = oldExpression.extensionReceiver
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCallableReference(expression: IrCallableReference): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
val oldCallee = expression.descriptor.original
|
|
||||||
val localFunctionData = localFunctions[oldCallee] ?: return expression
|
|
||||||
val newCallee = localFunctionData.transformedDescriptor
|
|
||||||
|
|
||||||
val newCallableReference = IrCallableReferenceImpl(
|
|
||||||
expression.startOffset, expression.endOffset,
|
|
||||||
expression.type, // TODO functional type for transformed descriptor
|
|
||||||
newCallee,
|
|
||||||
remapTypeArguments(expression, newCallee),
|
|
||||||
expression.origin
|
|
||||||
).fillArguments(localFunctionData, expression)
|
|
||||||
|
|
||||||
return newCallableReference
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitReturn(expression: IrReturn): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
val oldReturnTarget = expression.returnTarget
|
|
||||||
val localFunctionData = localFunctions[oldReturnTarget] ?: return expression
|
|
||||||
val newReturnTarget = localFunctionData.transformedDescriptor
|
|
||||||
|
|
||||||
return IrReturnImpl(expression.startOffset, expression.endOffset, newReturnTarget, expression.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun rewriteFunctionDeclaration(irFunction: IrFunction, localFunctionContext: LocalFunctionContext?) {
|
|
||||||
irFunction.transformChildrenVoid(FunctionBodiesRewriter(localFunctionContext))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun rewriteBodies() {
|
|
||||||
localFunctions.values.forEach {
|
|
||||||
rewriteFunctionDeclaration(it.declaration, it)
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteFunctionDeclaration(memberFunction, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createNewCall(oldCall: IrCall, newCallee: FunctionDescriptor) =
|
|
||||||
if (oldCall is IrCallWithShallowCopy)
|
|
||||||
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifier)
|
|
||||||
else
|
|
||||||
IrCallImpl(
|
|
||||||
oldCall.startOffset, oldCall.endOffset,
|
|
||||||
newCallee,
|
|
||||||
remapTypeArguments(oldCall, newCallee),
|
|
||||||
oldCall.origin, oldCall.superQualifier
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun remapTypeArguments(oldExpression: IrMemberAccessExpression, newCallee: FunctionDescriptor): Map<TypeParameterDescriptor, KotlinType>? {
|
|
||||||
val oldCallee = oldExpression.descriptor
|
|
||||||
|
|
||||||
return if (oldCallee.typeParameters.isEmpty())
|
|
||||||
null
|
|
||||||
else oldCallee.typeParameters.associateBy(
|
|
||||||
{ newCallee.typeParameters[it.index] },
|
|
||||||
{ oldExpression.getTypeArgument(it)!! }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun transformDescriptors() {
|
|
||||||
localFunctions.values.forEach {
|
|
||||||
it.transformedDescriptor = createTransformedDescriptor(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun suggestLocalName(descriptor: DeclarationDescriptor): String {
|
|
||||||
val localFunctionContext = localFunctions[descriptor]
|
|
||||||
return if (localFunctionContext != null && localFunctionContext.index >= 0)
|
|
||||||
"lambda-${localFunctionContext.index}"
|
|
||||||
else
|
|
||||||
descriptor.name.asString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateNameForLiftedFunction(functionDescriptor: FunctionDescriptor): Name =
|
|
||||||
Name.identifier(
|
|
||||||
functionDescriptor.parentsWithSelf
|
|
||||||
.takeWhile { it is FunctionDescriptor }
|
|
||||||
.toList().reversed()
|
|
||||||
.map { suggestLocalName(it) }
|
|
||||||
.joinToString(separator = "$")
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun createTransformedDescriptor(localFunctionContext: LocalFunctionContext): FunctionDescriptor {
|
|
||||||
val oldDescriptor = localFunctionContext.declaration.descriptor
|
|
||||||
|
|
||||||
val memberOwner = memberFunction.descriptor.containingDeclaration
|
|
||||||
val newDescriptor = SimpleFunctionDescriptorImpl.create(
|
|
||||||
memberOwner,
|
|
||||||
oldDescriptor.annotations,
|
|
||||||
generateNameForLiftedFunction(oldDescriptor),
|
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
|
||||||
oldDescriptor.source
|
|
||||||
)
|
|
||||||
|
|
||||||
val closureParametersCount = localFunctionContext.closureParametersCount
|
|
||||||
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
|
||||||
|
|
||||||
val newDispatchReceiverParameter =
|
|
||||||
if (memberOwner is ClassDescriptor && oldDescriptor.dispatchReceiverParameter != null)
|
|
||||||
memberOwner.thisAsReceiverParameter
|
|
||||||
else
|
|
||||||
null
|
|
||||||
|
|
||||||
// Do not substitute type parameters for now.
|
|
||||||
val newTypeParameters = oldDescriptor.typeParameters
|
|
||||||
|
|
||||||
val newValueParameters = ArrayList<ValueParameterDescriptor>(newValueParametersCount).apply {
|
|
||||||
localFunctionContext.closure.capturedValues.mapIndexedTo(this) { i, capturedValueDescriptor ->
|
|
||||||
createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValueDescriptor, i).apply {
|
|
||||||
localFunctionContext.recordRemapped(capturedValueDescriptor, this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
oldDescriptor.valueParameters.mapIndexedTo(this) { i, oldValueParameterDescriptor ->
|
|
||||||
createUnsubstitutedParameter(newDescriptor, oldValueParameterDescriptor, closureParametersCount + i).apply {
|
|
||||||
localFunctionContext.recordRemapped(oldValueParameterDescriptor, this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newDescriptor.initialize(
|
|
||||||
oldDescriptor.extensionReceiverParameter?.type,
|
|
||||||
newDispatchReceiverParameter,
|
|
||||||
newTypeParameters,
|
|
||||||
newValueParameters,
|
|
||||||
oldDescriptor.returnType,
|
|
||||||
Modality.FINAL,
|
|
||||||
Visibilities.PRIVATE
|
|
||||||
)
|
|
||||||
|
|
||||||
oldDescriptor.extensionReceiverParameter?.let {
|
|
||||||
localFunctionContext.recordRemapped(it, newDescriptor.extensionReceiverParameter!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
return newDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun LocalFunctionContext.recordRemapped(oldDescriptor: ValueDescriptor, newDescriptor: ValueDescriptor): ValueDescriptor {
|
|
||||||
old2new[oldDescriptor] = newDescriptor
|
|
||||||
new2old[newDescriptor] = oldDescriptor
|
|
||||||
return newDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun suggestNameForCapturedValueParameter(valueDescriptor: ValueDescriptor): Name =
|
|
||||||
if (valueDescriptor.name.isSpecial) {
|
|
||||||
val oldNameStr = valueDescriptor.name.asString()
|
|
||||||
Name.identifier("$" + oldNameStr.substring(1, oldNameStr.length - 1))
|
|
||||||
}
|
|
||||||
else
|
|
||||||
valueDescriptor.name
|
|
||||||
|
|
||||||
private fun createUnsubstitutedCapturedValueParameter(
|
|
||||||
newParameterOwner: CallableMemberDescriptor,
|
|
||||||
valueDescriptor: ValueDescriptor,
|
|
||||||
index: Int
|
|
||||||
): ValueParameterDescriptor =
|
|
||||||
ValueParameterDescriptorImpl(
|
|
||||||
newParameterOwner, null, index,
|
|
||||||
valueDescriptor.annotations,
|
|
||||||
suggestNameForCapturedValueParameter(valueDescriptor),
|
|
||||||
valueDescriptor.type,
|
|
||||||
false, false, false, null, valueDescriptor.source
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun createUnsubstitutedParameter(
|
|
||||||
newParameterOwner: CallableMemberDescriptor,
|
|
||||||
valueParameterDescriptor: ValueParameterDescriptor,
|
|
||||||
newIndex: Int
|
|
||||||
): ValueParameterDescriptor =
|
|
||||||
valueParameterDescriptor.copy(newParameterOwner, valueParameterDescriptor.name, newIndex)
|
|
||||||
|
|
||||||
|
|
||||||
private fun collectClosures() {
|
|
||||||
memberFunction.acceptChildrenVoid(object : AbstractClosureAnnotator() {
|
|
||||||
override fun visitClass(declaration: IrClass) {
|
|
||||||
// ignore local classes for now
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun recordFunctionClosure(functionDescriptor: FunctionDescriptor, closure: Closure) {
|
|
||||||
localFunctions[functionDescriptor]?.closure = closure
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun recordClassClosure(classDescriptor: ClassDescriptor, closure: Closure) {
|
|
||||||
// ignore local classes for now
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun collectLocalFunctions() {
|
|
||||||
memberFunction.acceptChildrenVoid(object : IrElementVisitorVoid {
|
|
||||||
var lambdasCount = 0
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunction(declaration: IrFunction) {
|
|
||||||
declaration.acceptChildrenVoid(this)
|
|
||||||
val localFunctionContext = LocalFunctionContext(declaration)
|
|
||||||
localFunctions[declaration.descriptor] = localFunctionContext
|
|
||||||
if (declaration.descriptor.name.isSpecial) {
|
|
||||||
localFunctionContext.index = lambdasCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass) {
|
|
||||||
// ignore local classes for now
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+2
-5
@@ -5,16 +5,13 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class IrLoweringContext(backendContext: BackendContext) : GeneratorContext {
|
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContext(backendContext.irBuiltIns)
|
||||||
override val irBuiltIns: IrBuiltIns = backendContext.irBuiltIns
|
|
||||||
}
|
|
||||||
|
|
||||||
class FunctionIrGenerator(backendContext: BackendContext, functionDescriptor: FunctionDescriptor) : GeneratorWithScope {
|
class FunctionIrGenerator(backendContext: BackendContext, functionDescriptor: FunctionDescriptor) : IrGeneratorWithScope {
|
||||||
override val context = IrLoweringContext(backendContext)
|
override val context = IrLoweringContext(backendContext)
|
||||||
override val scope = Scope(functionDescriptor)
|
override val scope = Scope(functionDescriptor)
|
||||||
}
|
}
|
||||||
|
|||||||
-133
@@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.lower
|
|
||||||
|
|
||||||
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
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
|
||||||
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.IrValueAccessExpression
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPass {
|
|
||||||
override fun lower(irFunction: IrFunction) {
|
|
||||||
SharedVariablesTransformer(irFunction).lowerSharedVariables()
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class SharedVariablesTransformer(val irFunction: IrFunction) {
|
|
||||||
val sharedVariables = HashSet<ValueDescriptor>()
|
|
||||||
|
|
||||||
fun lowerSharedVariables() {
|
|
||||||
collectSharedVariables()
|
|
||||||
if (sharedVariables.isEmpty()) return
|
|
||||||
|
|
||||||
rewriteSharedVariables()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun collectSharedVariables() {
|
|
||||||
irFunction.acceptVoid(object : IrElementVisitorVoid {
|
|
||||||
val declarationsStack = ArrayDeque<IrDeclaration>()
|
|
||||||
val currentDeclaration: DeclarationDescriptor
|
|
||||||
get() = declarationsStack.peek().descriptor
|
|
||||||
|
|
||||||
val relevantVars = HashSet<VariableDescriptor>()
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunction(declaration: IrFunction) {
|
|
||||||
declarationsStack.push(declaration)
|
|
||||||
declaration.acceptChildrenVoid(this)
|
|
||||||
declarationsStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitVariable(declaration: IrVariable) {
|
|
||||||
declaration.acceptChildrenVoid(this)
|
|
||||||
|
|
||||||
val variableDescriptor = declaration.descriptor
|
|
||||||
if (variableDescriptor.isVar) {
|
|
||||||
relevantVars.add(variableDescriptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitVariableAccess(expression: IrValueAccessExpression) {
|
|
||||||
expression.acceptChildrenVoid(this)
|
|
||||||
|
|
||||||
val descriptor = expression.descriptor
|
|
||||||
if (descriptor in relevantVars && descriptor.containingDeclaration != currentDeclaration) {
|
|
||||||
sharedVariables.add(descriptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun rewriteSharedVariables() {
|
|
||||||
val transformedDescriptors = HashMap<ValueDescriptor, VariableDescriptor>()
|
|
||||||
|
|
||||||
irFunction.transformChildrenVoid(object : IrElementTransformerVoid() {
|
|
||||||
override fun visitVariable(declaration: IrVariable): IrStatement {
|
|
||||||
declaration.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
val oldDescriptor = declaration.descriptor
|
|
||||||
if (oldDescriptor !in sharedVariables) return declaration
|
|
||||||
|
|
||||||
val newDescriptor = context.sharedVariablesManager.createSharedVariableDescriptor(oldDescriptor)
|
|
||||||
transformedDescriptors[oldDescriptor] = newDescriptor
|
|
||||||
|
|
||||||
return context.sharedVariablesManager.defineSharedValue(newDescriptor, declaration)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
irFunction.transformChildrenVoid(object : IrElementTransformerVoid() {
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
val newDescriptor = getTransformedDescriptor(expression.descriptor) ?: return expression
|
|
||||||
|
|
||||||
return context.sharedVariablesManager.getSharedValue(newDescriptor, expression)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
val newDescriptor = getTransformedDescriptor(expression.descriptor) ?: return expression
|
|
||||||
|
|
||||||
return context.sharedVariablesManager.setSharedValue(newDescriptor, expression)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getTransformedDescriptor(oldDescriptor: ValueDescriptor): VariableDescriptor? =
|
|
||||||
transformedDescriptors.getOrElse(oldDescriptor) {
|
|
||||||
assert(oldDescriptor !in sharedVariables) {
|
|
||||||
"Shared variable is not transformed: $oldDescriptor"
|
|
||||||
}
|
|
||||||
null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+2
-2
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.backend.konan
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanPlatformConfigurator
|
import org.jetbrains.kotlin.backend.konan.KonanPlatformConfigurator
|
||||||
import org.jetbrains.kotlin.descriptors.PlatformKind
|
|
||||||
import org.jetbrains.kotlin.resolve.ImportPath
|
import org.jetbrains.kotlin.resolve.ImportPath
|
||||||
|
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.PlatformConfigurator
|
import org.jetbrains.kotlin.resolve.PlatformConfigurator
|
||||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
@@ -35,7 +35,7 @@ class KonanBuiltIns: KotlinBuiltIns {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object KonanPlatform : TargetPlatform("Konan") {
|
object KonanPlatform : TargetPlatform("Konan") {
|
||||||
override val kind = PlatformKind.DEFAULT /* TODO: native */
|
override val multiTargetPlatform = MultiTargetPlatform.Specific(platformName)
|
||||||
override val defaultImports: List<ImportPath> = Default.defaultImports + listOf(
|
override val defaultImports: List<ImportPath> = Default.defaultImports + listOf(
|
||||||
ImportPath("kotlin.*"),
|
ImportPath("kotlin.*"),
|
||||||
ImportPath("kotlin.collections.*"),
|
ImportPath("kotlin.collections.*"),
|
||||||
|
|||||||
+2
-1
@@ -31,7 +31,8 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProvid
|
|||||||
|
|
||||||
object TopDownAnalyzerFacadeForKonan {
|
object TopDownAnalyzerFacadeForKonan {
|
||||||
fun analyzeFiles(files: Collection<KtFile>, config: KonanConfig): AnalysisResult {
|
fun analyzeFiles(files: Collection<KtFile>, config: KonanConfig): AnalysisResult {
|
||||||
val context = ContextForNewModule(ProjectContext(config.project), Name.special("<${config.moduleId}>"), KonanPlatform.builtIns)
|
val context = ContextForNewModule(ProjectContext(config.project), Name.special("<${config.moduleId}>"),
|
||||||
|
KonanPlatform.builtIns, null)
|
||||||
|
|
||||||
val builtinsForCompilerModule = KonanBuiltIns(context.storageManager, true)
|
val builtinsForCompilerModule = KonanBuiltIns(context.storageManager, true)
|
||||||
val compilerBuiltInsModule = builtinsForCompilerModule.builtInsModule
|
val compilerBuiltInsModule = builtinsForCompilerModule.builtInsModule
|
||||||
|
|||||||
+4
-14
@@ -1337,11 +1337,12 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
private fun evaluateGetField(value: IrGetField): LLVMValueRef {
|
private fun evaluateGetField(value: IrGetField): LLVMValueRef {
|
||||||
context.log("evaluateGetField : ${ir2string(value)}")
|
context.log("evaluateGetField : ${ir2string(value)}")
|
||||||
if (value.descriptor.dispatchReceiverParameter != null) {
|
if (value.descriptor.dispatchReceiverParameter != null) {
|
||||||
val thisPtr = instanceFieldAccessReceiver(value)
|
val thisPtr = evaluateExpression(value.receiver!!)
|
||||||
return codegen.loadSlot(
|
return codegen.loadSlot(
|
||||||
fieldPtrOfClass(thisPtr, value.descriptor), value.descriptor.isVar())
|
fieldPtrOfClass(thisPtr, value.descriptor), value.descriptor.isVar())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
assert (value.receiver == null)
|
||||||
val ptr = LLVMGetNamedGlobal(context.llvmModule, value.descriptor.symbolName)!!
|
val ptr = LLVMGetNamedGlobal(context.llvmModule, value.descriptor.symbolName)!!
|
||||||
return codegen.loadSlot(ptr, value.descriptor.isVar())
|
return codegen.loadSlot(ptr, value.descriptor.isVar())
|
||||||
}
|
}
|
||||||
@@ -1362,26 +1363,15 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun instanceFieldAccessReceiver(expression: IrFieldAccessExpression): LLVMValueRef {
|
|
||||||
val receiverExpression = expression.receiver
|
|
||||||
if (receiverExpression != null) {
|
|
||||||
return evaluateExpression(receiverExpression)
|
|
||||||
} else {
|
|
||||||
val classDescriptor = expression.descriptor.containingDeclaration as ClassDescriptor
|
|
||||||
return currentCodeContext.genGetValue(classDescriptor.thisAsReceiverParameter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun evaluateSetField(value: IrSetField): LLVMValueRef {
|
private fun evaluateSetField(value: IrSetField): LLVMValueRef {
|
||||||
context.log("evaluateSetField : ${ir2string(value)}")
|
context.log("evaluateSetField : ${ir2string(value)}")
|
||||||
val valueToAssign = evaluateExpression(value.value)
|
val valueToAssign = evaluateExpression(value.value)
|
||||||
if (value.descriptor.dispatchReceiverParameter != null) {
|
if (value.descriptor.dispatchReceiverParameter != null) {
|
||||||
val thisPtr = instanceFieldAccessReceiver(value)
|
val thisPtr = evaluateExpression(value.receiver!!)
|
||||||
codegen.storeAnyGlobal(valueToAssign, fieldPtrOfClass(thisPtr, value.descriptor))
|
codegen.storeAnyGlobal(valueToAssign, fieldPtrOfClass(thisPtr, value.descriptor))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
assert (value.receiver == null)
|
||||||
val globalValue = LLVMGetNamedGlobal(context.llvmModule, value.descriptor.symbolName)
|
val globalValue = LLVMGetNamedGlobal(context.llvmModule, value.descriptor.symbolName)
|
||||||
codegen.storeAnyGlobal(valueToAssign, globalValue!!)
|
codegen.storeAnyGlobal(valueToAssign, globalValue!!)
|
||||||
}
|
}
|
||||||
|
|||||||
-13
@@ -33,19 +33,6 @@ private class BuiltinOperatorTransformer(val context: Context) : IrElementTransf
|
|||||||
private val builtIns = context.builtIns
|
private val builtIns = context.builtIns
|
||||||
private val irBuiltins = context.irModule!!.irBuiltins
|
private val irBuiltins = context.irModule!!.irBuiltins
|
||||||
|
|
||||||
override fun visitTry(aTry: IrTry): IrExpression {
|
|
||||||
// Workaround for the bug in IrTryImpl.transformChildren: transform `finallyExpression` too.
|
|
||||||
// TODO: fix the bug and remove it.
|
|
||||||
val transformer = this
|
|
||||||
return (aTry as IrTryImpl).apply {
|
|
||||||
tryResult = tryResult.transform(transformer, null)
|
|
||||||
catches.forEachIndexed { i, irCatch ->
|
|
||||||
catches[i] = irCatch.transform(transformer, null)
|
|
||||||
}
|
|
||||||
finallyExpression = finallyExpression?.transform(transformer, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
|
|||||||
-138
@@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.builders
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
|
|
||||||
|
|
||||||
inline fun IrBuilderWithScope.irLet(
|
|
||||||
value: IrExpression,
|
|
||||||
origin: IrStatementOrigin? = null,
|
|
||||||
nameHint: String? = null,
|
|
||||||
body: (VariableDescriptor) -> IrExpression
|
|
||||||
): IrExpression {
|
|
||||||
val irTemporary = scope.createTemporaryVariable(value, nameHint)
|
|
||||||
val irResult = body(irTemporary.descriptor)
|
|
||||||
val irBlock = IrBlockImpl(startOffset, endOffset, irResult.type, origin)
|
|
||||||
irBlock.statements.add(irTemporary)
|
|
||||||
irBlock.statements.add(irResult)
|
|
||||||
return irBlock
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : IrElement> IrStatementsBuilder<T>.defineTemporary(value: IrExpression, nameHint: String? = null): VariableDescriptor {
|
|
||||||
val temporary = scope.createTemporaryVariable(value, nameHint)
|
|
||||||
+temporary
|
|
||||||
return temporary.descriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : IrElement> IrStatementsBuilder<T>.defineTemporaryVar(value: IrExpression, nameHint: String? = null): VariableDescriptor {
|
|
||||||
val temporary = scope.createTemporaryVariable(value, nameHint, isMutable = true)
|
|
||||||
+temporary
|
|
||||||
return temporary.descriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irReturn(value: IrExpression) =
|
|
||||||
IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, scope.assertCastOwner(), value)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irReturnTrue() =
|
|
||||||
irReturn(IrConstImpl(startOffset, endOffset, context.builtIns.booleanType, IrConstKind.Boolean, true))
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irReturnFalse() =
|
|
||||||
irReturn(IrConstImpl(startOffset, endOffset, context.builtIns.booleanType, IrConstKind.Boolean, false))
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfThenElse(type: KotlinType, condition: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
|
||||||
IrIfThenElseImpl(startOffset, endOffset, type, condition, thenPart, elsePart)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfNull(type: KotlinType, subject: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
|
||||||
irIfThenElse(type, irEqualsNull(subject), thenPart, elsePart)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irThrowNpe(origin: IrStatementOrigin) =
|
|
||||||
IrNullaryPrimitiveImpl(startOffset, endOffset, origin, context.irBuiltIns.throwNpe)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) =
|
|
||||||
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnTrue())
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfThenReturnFalse(condition: IrExpression) =
|
|
||||||
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnFalse())
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irThis() =
|
|
||||||
scope.classOwner().let { classOwner ->
|
|
||||||
IrGetValueImpl(startOffset, endOffset, classOwner.thisAsReceiverParameter)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGet(variable: VariableDescriptor) =
|
|
||||||
IrGetValueImpl(startOffset, endOffset, variable)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irSetVar(variable: VariableDescriptor, value: IrExpression) =
|
|
||||||
IrSetVariableImpl(startOffset, endOffset, variable, value, IrStatementOrigin.EQ)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irOther() =
|
|
||||||
irGet(scope.functionOwner().valueParameters.single())
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irEqeqeq(arg1: IrExpression, arg2: IrExpression) =
|
|
||||||
context.eqeqeq(startOffset, endOffset, arg1, arg2)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irNull() =
|
|
||||||
IrConstImpl.constNull(startOffset, endOffset, context.builtIns.nullableNothingType)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irEqualsNull(argument: IrExpression) =
|
|
||||||
primitiveOp2(startOffset, endOffset, context.irBuiltIns.eqeq, IrStatementOrigin.EQEQ,
|
|
||||||
argument, irNull())
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irNotEquals(arg1: IrExpression, arg2: IrExpression) =
|
|
||||||
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNot, IrStatementOrigin.EXCLEQ,
|
|
||||||
primitiveOp2(startOffset, endOffset, context.irBuiltIns.eqeq, IrStatementOrigin.EXCLEQ,
|
|
||||||
arg1, arg2))
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGet(receiver: IrExpression, property: PropertyDescriptor): IrExpression =
|
|
||||||
IrGetterCallImpl(startOffset, endOffset, property.getter!!, null, receiver, null, IrStatementOrigin.GET_PROPERTY)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irCall(callee: CallableDescriptor) =
|
|
||||||
IrCallImpl(startOffset, endOffset, callee.returnType!!, callee, null)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irCallOp(callee: CallableDescriptor, dispatchReceiver: IrExpression, argument: IrExpression) =
|
|
||||||
IrCallImpl(startOffset, endOffset, callee.returnType!!, callee, null).apply {
|
|
||||||
this.dispatchReceiver = dispatchReceiver
|
|
||||||
putValueArgument(0, argument)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType) =
|
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType) =
|
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.NOT_INSTANCEOF, type, argument)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irAs(argument: IrExpression, type: KotlinType) =
|
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, argument)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: KotlinType) =
|
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, argument)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irInt(value: Int) =
|
|
||||||
IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, value)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irString(value: String) =
|
|
||||||
IrConstImpl.string(startOffset, endOffset, context.builtIns.stringType, value)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irConcat() =
|
|
||||||
IrStringConcatenationImpl(startOffset, endOffset, context.builtIns.stringType)
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.builders
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
|
||||||
|
|
||||||
// TODO: rename Generator* to IrGenerator* when contributing back to Kotlin.
|
|
||||||
|
|
||||||
interface Generator {
|
|
||||||
val context: GeneratorContext
|
|
||||||
}
|
|
||||||
|
|
||||||
interface GeneratorWithScope : Generator {
|
|
||||||
val scope: Scope
|
|
||||||
}
|
|
||||||
|
|
||||||
interface GeneratorContext {
|
|
||||||
val irBuiltIns: IrBuiltIns
|
|
||||||
val builtIns: KotlinBuiltIns get() = irBuiltIns.builtIns
|
|
||||||
}
|
|
||||||
-127
@@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.builders
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
abstract class IrBuilder(
|
|
||||||
override val context: GeneratorContext,
|
|
||||||
var startOffset: Int,
|
|
||||||
var endOffset: Int
|
|
||||||
) : Generator
|
|
||||||
|
|
||||||
abstract class IrBuilderWithScope(
|
|
||||||
context: GeneratorContext,
|
|
||||||
override val scope: Scope,
|
|
||||||
startOffset: Int,
|
|
||||||
endOffset: Int
|
|
||||||
) : IrBuilder(context, startOffset, endOffset), GeneratorWithScope
|
|
||||||
|
|
||||||
abstract class IrStatementsBuilder<out T : IrElement>(
|
|
||||||
context: GeneratorContext,
|
|
||||||
scope: Scope,
|
|
||||||
startOffset: Int,
|
|
||||||
endOffset: Int
|
|
||||||
) : IrBuilderWithScope(context, scope, startOffset, endOffset) {
|
|
||||||
operator fun IrStatement.unaryPlus() {
|
|
||||||
addStatement(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun addStatement(irStatement: IrStatement)
|
|
||||||
protected abstract fun doBuild(): T
|
|
||||||
}
|
|
||||||
|
|
||||||
open class IrBlockBodyBuilder(
|
|
||||||
context: GeneratorContext,
|
|
||||||
scope: Scope,
|
|
||||||
startOffset: Int,
|
|
||||||
endOffset: Int
|
|
||||||
) : IrStatementsBuilder<IrBlockBody>(context, scope, startOffset, endOffset) {
|
|
||||||
private val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
|
|
||||||
|
|
||||||
inline fun blockBody(body: IrBlockBodyBuilder.() -> Unit): IrBlockBody {
|
|
||||||
body()
|
|
||||||
return doBuild()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun addStatement(irStatement: IrStatement) {
|
|
||||||
irBlockBody.statements.add(irStatement)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doBuild(): IrBlockBody {
|
|
||||||
return irBlockBody
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class IrBlockBuilder(
|
|
||||||
context: GeneratorContext, scope: Scope,
|
|
||||||
startOffset: Int, endOffset: Int,
|
|
||||||
val origin: IrStatementOrigin? = null,
|
|
||||||
var resultType: KotlinType? = null
|
|
||||||
) : IrStatementsBuilder<IrBlock>(context, scope, startOffset, endOffset) {
|
|
||||||
private val statements = ArrayList<IrStatement>()
|
|
||||||
|
|
||||||
inline fun block(body: IrBlockBuilder.() -> Unit): IrBlock {
|
|
||||||
body()
|
|
||||||
return doBuild()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun addStatement(irStatement: IrStatement) {
|
|
||||||
statements.add(irStatement)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doBuild(): IrBlock {
|
|
||||||
val resultType = this.resultType ?:
|
|
||||||
(statements.lastOrNull() as? IrExpression)?.type ?:
|
|
||||||
context.builtIns.unitType
|
|
||||||
val irBlock = IrBlockImpl(startOffset, endOffset, resultType, origin)
|
|
||||||
irBlock.statements.addAll(statements)
|
|
||||||
return irBlock
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : IrBuilder> T.at(startOffset: Int, endOffset: Int): T {
|
|
||||||
this.startOffset = startOffset
|
|
||||||
this.endOffset = endOffset
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun GeneratorWithScope.irBlock(startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET,
|
|
||||||
origin: IrStatementOrigin? = null,
|
|
||||||
resultType: KotlinType? = null,
|
|
||||||
body: IrBlockBuilder.() -> Unit
|
|
||||||
): IrExpression =
|
|
||||||
IrBlockBuilder(context, scope,
|
|
||||||
startOffset,
|
|
||||||
endOffset,
|
|
||||||
origin, resultType
|
|
||||||
).block(body)
|
|
||||||
|
|
||||||
inline fun GeneratorWithScope.irBlockBody(startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET,
|
|
||||||
body: IrBlockBodyBuilder.() -> Unit
|
|
||||||
) : IrBlockBody =
|
|
||||||
IrBlockBodyBuilder(context, scope,
|
|
||||||
startOffset,
|
|
||||||
endOffset
|
|
||||||
).blockBody(body)
|
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.builders
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
|
||||||
|
|
||||||
class IrMemberFunctionBuilder(
|
|
||||||
context: GeneratorContext,
|
|
||||||
val irClass: IrClassImpl,
|
|
||||||
val function: FunctionDescriptor,
|
|
||||||
val origin: IrDeclarationOrigin,
|
|
||||||
startOffset: Int = UNDEFINED_OFFSET,
|
|
||||||
endOffset: Int = UNDEFINED_OFFSET
|
|
||||||
) : IrBlockBodyBuilder(context, Scope(function), startOffset, endOffset) {
|
|
||||||
inline fun addToClass(body: IrMemberFunctionBuilder.() -> Unit) {
|
|
||||||
val irFunction = IrFunctionImpl(startOffset, endOffset, origin, function)
|
|
||||||
body()
|
|
||||||
irFunction.body = doBuild()
|
|
||||||
irClass.addMember(irFunction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-64
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.builders
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
|
||||||
|
|
||||||
fun primitiveOp1(startOffset: Int, endOffset: Int, primitiveOpDescriptor: CallableDescriptor, origin: IrStatementOrigin,
|
|
||||||
argument: IrExpression): IrExpression =
|
|
||||||
IrUnaryPrimitiveImpl(startOffset, endOffset, origin, primitiveOpDescriptor, argument)
|
|
||||||
|
|
||||||
fun primitiveOp2(startOffset: Int, endOffset: Int, primitiveOpDescriptor: CallableDescriptor, origin: IrStatementOrigin,
|
|
||||||
argument1: IrExpression, argument2: IrExpression): IrExpression =
|
|
||||||
IrBinaryPrimitiveImpl(startOffset, endOffset, origin, primitiveOpDescriptor, argument1, argument2)
|
|
||||||
|
|
||||||
fun GeneratorContext.constNull(startOffset: Int, endOffset: Int): IrExpression =
|
|
||||||
IrConstImpl.constNull(startOffset, endOffset, builtIns.nullableNothingType)
|
|
||||||
|
|
||||||
fun GeneratorContext.equalsNull(startOffset: Int, endOffset: Int, argument: IrExpression): IrExpression =
|
|
||||||
primitiveOp2(startOffset, endOffset, irBuiltIns.eqeq, IrStatementOrigin.EQEQ,
|
|
||||||
argument, constNull(startOffset, endOffset))
|
|
||||||
|
|
||||||
fun GeneratorContext.eqeqeq(startOffset: Int, endOffset: Int, argument1: IrExpression, argument2: IrExpression): IrExpression =
|
|
||||||
primitiveOp2(startOffset, endOffset, irBuiltIns.eqeqeq, IrStatementOrigin.EQEQEQ, argument1, argument2)
|
|
||||||
|
|
||||||
fun GeneratorContext.throwNpe(startOffset: Int, endOffset: Int, origin: IrStatementOrigin): IrExpression =
|
|
||||||
IrNullaryPrimitiveImpl(startOffset, endOffset, origin, irBuiltIns.throwNpe)
|
|
||||||
|
|
||||||
// a || b == if (a) true else b
|
|
||||||
fun GeneratorContext.oror(startOffset: Int, endOffset: Int, a: IrExpression, b: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.OROR): IrWhen =
|
|
||||||
IrIfThenElseImpl(startOffset, endOffset, builtIns.booleanType,
|
|
||||||
a, IrConstImpl.constTrue(b.startOffset, b.endOffset, b.type), b,
|
|
||||||
origin)
|
|
||||||
|
|
||||||
fun GeneratorContext.oror(a: IrExpression, b: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.OROR): IrWhen =
|
|
||||||
oror(b.startOffset, b.endOffset, a, b, origin)
|
|
||||||
|
|
||||||
fun GeneratorContext.whenComma(a: IrExpression, b: IrExpression): IrWhen =
|
|
||||||
oror(a, b, IrStatementOrigin.WHEN_COMMA)
|
|
||||||
|
|
||||||
// a && b == if (a) b else false
|
|
||||||
fun GeneratorContext.andand(startOffset: Int, endOffset: Int, a: IrExpression, b: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.ANDAND): IrWhen =
|
|
||||||
IrIfThenElseImpl(startOffset, endOffset, builtIns.booleanType,
|
|
||||||
a, b, IrConstImpl.constFalse(b.startOffset, b.endOffset, b.type),
|
|
||||||
origin)
|
|
||||||
|
|
||||||
fun GeneratorContext.andand(a: IrExpression, b: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.ANDAND): IrWhen =
|
|
||||||
andand(b.startOffset, b.endOffset, a, b, origin)
|
|
||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.builders
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
|
|
||||||
class Scope(val scopeOwner: DeclarationDescriptor) {
|
|
||||||
private var lastTemporaryIndex: Int = 0
|
|
||||||
private fun nextTemporaryIndex(): Int = lastTemporaryIndex++
|
|
||||||
|
|
||||||
private fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null, isMutable: Boolean = false): IrTemporaryVariableDescriptor =
|
|
||||||
IrTemporaryVariableDescriptorImpl(scopeOwner, Name.identifier(getNameForTemporary(nameHint)), type, isMutable)
|
|
||||||
|
|
||||||
private fun getNameForTemporary(nameHint: String?): String {
|
|
||||||
val index = nextTemporaryIndex()
|
|
||||||
return if (nameHint != null) "tmp${index}_$nameHint" else "tmp$index"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createTemporaryVariable(irExpression: IrExpression, nameHint: String? = null, isMutable: Boolean = false): IrVariable =
|
|
||||||
IrVariableImpl(
|
|
||||||
irExpression.startOffset, irExpression.endOffset, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
|
||||||
createDescriptorForTemporaryVariable(irExpression.type, nameHint, isMutable),
|
|
||||||
irExpression
|
|
||||||
)
|
|
||||||
}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.builders
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
|
|
||||||
inline fun <reified T> Scope.assertCastOwner() =
|
|
||||||
scopeOwner as? T ?:
|
|
||||||
throw AssertionError("Unexpected scopeOwner: $scopeOwner")
|
|
||||||
|
|
||||||
fun Scope.functionOwner(): FunctionDescriptor =
|
|
||||||
assertCastOwner()
|
|
||||||
|
|
||||||
fun Scope.classOwner(): ClassDescriptor =
|
|
||||||
when (scopeOwner) {
|
|
||||||
is ClassDescriptor -> scopeOwner
|
|
||||||
is MemberDescriptor -> scopeOwner.containingDeclaration as ClassDescriptor
|
|
||||||
else -> throw AssertionError("Unexpected scopeOwner: $scopeOwner")
|
|
||||||
}
|
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
kotlin_version=1.1-M03
|
kotlin_version=1.1-M03
|
||||||
#kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-SNAPSHOT
|
#kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-SNAPSHOT
|
||||||
kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-20161229.093306-344
|
kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-20170112.203631-353
|
||||||
|
|||||||
Reference in New Issue
Block a user