Generate delegating constructor calls as IrDelegatingConstructorCall expressions
(they have different platform-level representation in JVM and JS).
This commit is contained in:
committed by
Dmitry Petrov
parent
6fbac2ed40
commit
a6bee7a22b
@@ -104,8 +104,9 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
|||||||
val statementGenerator = createStatementGenerator()
|
val statementGenerator = createStatementGenerator()
|
||||||
val ktDelegatingConstructorCall = ktConstructor.getDelegationCall()
|
val ktDelegatingConstructorCall = ktConstructor.getDelegationCall()
|
||||||
val delegatingConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktDelegatingConstructorCall)!!)
|
val delegatingConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktDelegatingConstructorCall)!!)
|
||||||
val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateCall(
|
val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall(
|
||||||
ktDelegatingConstructorCall, delegatingConstructorCall, IrOperator.DELEGATING_CONSTRUCTOR_CALL)
|
ktDelegatingConstructorCall.startOffset, ktDelegatingConstructorCall.endOffset,
|
||||||
|
delegatingConstructorCall)
|
||||||
irBlockBody.addStatement(irDelegatingConstructorCall)
|
irBlockBody.addStatement(irDelegatingConstructorCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir.generators
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
@@ -52,6 +49,23 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun generateDelegatingConstructorCall(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
call: CallBuilder
|
||||||
|
) : IrExpression {
|
||||||
|
val descriptor = call.descriptor
|
||||||
|
if (descriptor !is ConstructorDescriptor) throw AssertionError("Constructor expected: $descriptor")
|
||||||
|
|
||||||
|
return call.callReceiver.call { dispatchReceiver, extensionReceiver ->
|
||||||
|
if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver")
|
||||||
|
if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver")
|
||||||
|
val irCall = IrDelegatingConstructorCallImpl(startOffset, endOffset, descriptor)
|
||||||
|
|
||||||
|
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.returnType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun generatePropertyGetterCall(
|
private fun generatePropertyGetterCall(
|
||||||
descriptor: PropertyDescriptor,
|
descriptor: PropertyDescriptor,
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
@@ -79,28 +93,28 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
|||||||
val returnType = descriptor.returnType!!
|
val returnType = descriptor.returnType!!
|
||||||
|
|
||||||
return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||||
val irCall = IrFunCallImpl(startOffset, endOffset, returnType, descriptor, operator, call.superQualifier)
|
val irCall = IrCallImpl(startOffset, endOffset, returnType, descriptor, operator, call.superQualifier)
|
||||||
irCall.dispatchReceiver = dispatchReceiverValue?.load()
|
irCall.dispatchReceiver = dispatchReceiverValue?.load()
|
||||||
irCall.extensionReceiver = extensionReceiverValue?.load()
|
irCall.extensionReceiver = extensionReceiverValue?.load()
|
||||||
|
|
||||||
val irCallWithReordering =
|
addParametersToCall(startOffset, endOffset, call, irCall, returnType)
|
||||||
if (call.isValueArgumentReorderingRequired()) {
|
|
||||||
generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val valueArguments = call.getValueArgumentsInParameterOrder()
|
|
||||||
for ((index, valueArgument) in valueArguments.withIndex()) {
|
|
||||||
irCall.putArgument(index, valueArgument)
|
|
||||||
}
|
|
||||||
irCall
|
|
||||||
}
|
|
||||||
|
|
||||||
irCallWithReordering
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addParametersToCall(startOffset: Int, endOffset: Int, call: CallBuilder, irCall: IrGeneralCallBase, returnType: KotlinType): IrExpression =
|
||||||
|
if (call.isValueArgumentReorderingRequired()) {
|
||||||
|
generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val valueArguments = call.getValueArgumentsInParameterOrder()
|
||||||
|
for ((index, valueArgument) in valueArguments.withIndex()) {
|
||||||
|
irCall.putArgument(index, valueArgument)
|
||||||
|
}
|
||||||
|
irCall
|
||||||
|
}
|
||||||
|
|
||||||
private fun generateCallWithArgumentReordering(
|
private fun generateCallWithArgumentReordering(
|
||||||
irCall: IrCall,
|
irCall: IrGeneralCall,
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
call: CallBuilder,
|
call: CallBuilder,
|
||||||
|
|||||||
+3
-3
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.detach
|
import org.jetbrains.kotlin.ir.detach
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrGeneralCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenationImpl
|
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenationImpl
|
||||||
@@ -38,7 +38,7 @@ class FoldStringConcatenation : IrElementVisitor<Unit, Nothing?> {
|
|||||||
element.acceptChildren(this, data)
|
element.acceptChildren(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall, data: Nothing?) {
|
override fun visitGeneralCall(expression: IrGeneralCall, data: Nothing?) {
|
||||||
if (!isStringPlus(expression.descriptor)) {
|
if (!isStringPlus(expression.descriptor)) {
|
||||||
visitElement(expression, data)
|
visitElement(expression, data)
|
||||||
return
|
return
|
||||||
@@ -54,7 +54,7 @@ class FoldStringConcatenation : IrElementVisitor<Unit, Nothing?> {
|
|||||||
|
|
||||||
private fun collectStringConcatenationArguments(expression: IrExpression, arguments: ArrayList<IrExpression>) {
|
private fun collectStringConcatenationArguments(expression: IrExpression, arguments: ArrayList<IrExpression>) {
|
||||||
when {
|
when {
|
||||||
expression is IrCall && isStringPlus(expression.descriptor)-> {
|
expression is IrGeneralCall && isStringPlus(expression.descriptor)-> {
|
||||||
collectStringConcatenationArguments(expression.dispatchReceiver!!, arguments)
|
collectStringConcatenationArguments(expression.dispatchReceiver!!, arguments)
|
||||||
collectStringConcatenationArguments(expression.getArgument(0)!!, arguments)
|
collectStringConcatenationArguments(expression.getArgument(0)!!, arguments)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitor<Unit,
|
|||||||
element.acceptChildren(this, null)
|
element.acceptChildren(this, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall, data: Nothing?) {
|
override fun visitGeneralCall(expression: IrGeneralCall, data: Nothing?) {
|
||||||
expression.acceptChildren(this, null)
|
expression.acceptChildren(this, null)
|
||||||
|
|
||||||
with(expression) {
|
with(expression) {
|
||||||
|
|||||||
@@ -17,66 +17,22 @@
|
|||||||
package org.jetbrains.kotlin.ir.expressions
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.ir.assertCast
|
|
||||||
import org.jetbrains.kotlin.ir.assertDetached
|
|
||||||
import org.jetbrains.kotlin.ir.detach
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.lang.AssertionError
|
|
||||||
|
|
||||||
interface IrCall : IrMemberAccessExpression {
|
interface IrCall : IrGeneralCall {
|
||||||
val operator: IrOperator?
|
val superQualifier: ClassDescriptor?
|
||||||
override val descriptor: CallableDescriptor
|
|
||||||
|
|
||||||
fun getArgument(index: Int): IrExpression?
|
|
||||||
fun putArgument(index: Int, valueArgument: IrExpression?)
|
|
||||||
fun removeArgument(index: Int)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IrCallBase(
|
class IrCallImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType,
|
type: KotlinType,
|
||||||
numArguments: Int,
|
override val descriptor: CallableDescriptor,
|
||||||
override val operator: IrOperator? = null
|
override val operator: IrOperator? = null,
|
||||||
) : IrMemberAccessExpressionBase(startOffset, endOffset, type), IrCall {
|
override val superQualifier: ClassDescriptor? = null
|
||||||
protected val argumentsByParameterIndex =
|
) : IrGeneralCallBase(startOffset, endOffset, type, descriptor.valueParameters.size), IrCall {
|
||||||
arrayOfNulls<IrExpression>(numArguments)
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
|
visitor.visitCall(this, data)
|
||||||
override fun getArgument(index: Int): IrExpression? =
|
|
||||||
argumentsByParameterIndex[index]
|
|
||||||
|
|
||||||
override fun putArgument(index: Int, valueArgument: IrExpression?) {
|
|
||||||
if (index >= argumentsByParameterIndex.size) {
|
|
||||||
throw AssertionError("$this: No such argument slot: $index")
|
|
||||||
}
|
|
||||||
valueArgument?.assertDetached()
|
|
||||||
argumentsByParameterIndex[index]?.detach()
|
|
||||||
argumentsByParameterIndex[index] = valueArgument
|
|
||||||
valueArgument?.setTreeLocation(this, index)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun removeArgument(index: Int) {
|
|
||||||
argumentsByParameterIndex[index]?.detach()
|
|
||||||
argumentsByParameterIndex[index] = null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getChild(slot: Int): IrElement? =
|
|
||||||
if (0 <= slot)
|
|
||||||
argumentsByParameterIndex.getOrNull(slot)
|
|
||||||
else
|
|
||||||
super.getChild(slot)
|
|
||||||
|
|
||||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
|
||||||
if (0 <= slot)
|
|
||||||
putArgument(slot, newChild.assertCast())
|
|
||||||
else
|
|
||||||
super.replaceChild(slot, newChild)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
|
||||||
super.acceptChildren(visitor, data)
|
|
||||||
argumentsByParameterIndex.forEach { it?.accept(visitor, data) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
|
|
||||||
interface IrDelegatingConstructorCall : IrCall {
|
interface IrDelegatingConstructorCall : IrGeneralCall {
|
||||||
override val descriptor: ConstructorDescriptor
|
override val descriptor: ConstructorDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ class IrDelegatingConstructorCallImpl(
|
|||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
override val descriptor: ConstructorDescriptor
|
override val descriptor: ConstructorDescriptor
|
||||||
) : IrCallBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size), IrDelegatingConstructorCall {
|
) : IrGeneralCallBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size), IrDelegatingConstructorCall {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||||
return visitor.visitDelegatingConstructorCall(this, data)
|
return visitor.visitDelegatingConstructorCall(this, data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +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.expressions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
|
|
||||||
interface IrFunCall : IrCall {
|
|
||||||
val superQualifier: ClassDescriptor?
|
|
||||||
}
|
|
||||||
|
|
||||||
class IrFunCallImpl(
|
|
||||||
startOffset: Int,
|
|
||||||
endOffset: Int,
|
|
||||||
type: KotlinType,
|
|
||||||
override val descriptor: CallableDescriptor,
|
|
||||||
override val operator: IrOperator? = null,
|
|
||||||
override val superQualifier: ClassDescriptor? = null
|
|
||||||
) : IrCallBase(startOffset, endOffset, type, descriptor.valueParameters.size), IrFunCall {
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
|
||||||
visitor.visitFunCall(this, data)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.expressions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.assertCast
|
||||||
|
import org.jetbrains.kotlin.ir.assertDetached
|
||||||
|
import org.jetbrains.kotlin.ir.detach
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import java.lang.AssertionError
|
||||||
|
|
||||||
|
interface IrGeneralCall : IrMemberAccessExpression {
|
||||||
|
val operator: IrOperator?
|
||||||
|
override val descriptor: CallableDescriptor
|
||||||
|
|
||||||
|
fun getArgument(index: Int): IrExpression?
|
||||||
|
fun putArgument(index: Int, valueArgument: IrExpression?)
|
||||||
|
fun removeArgument(index: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class IrGeneralCallBase(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
type: KotlinType,
|
||||||
|
numArguments: Int,
|
||||||
|
override val operator: IrOperator? = null
|
||||||
|
) : IrMemberAccessExpressionBase(startOffset, endOffset, type), IrGeneralCall {
|
||||||
|
protected val argumentsByParameterIndex =
|
||||||
|
arrayOfNulls<IrExpression>(numArguments)
|
||||||
|
|
||||||
|
override fun getArgument(index: Int): IrExpression? =
|
||||||
|
argumentsByParameterIndex[index]
|
||||||
|
|
||||||
|
override fun putArgument(index: Int, valueArgument: IrExpression?) {
|
||||||
|
if (index >= argumentsByParameterIndex.size) {
|
||||||
|
throw AssertionError("$this: No such argument slot: $index")
|
||||||
|
}
|
||||||
|
valueArgument?.assertDetached()
|
||||||
|
argumentsByParameterIndex[index]?.detach()
|
||||||
|
argumentsByParameterIndex[index] = valueArgument
|
||||||
|
valueArgument?.setTreeLocation(this, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeArgument(index: Int) {
|
||||||
|
argumentsByParameterIndex[index]?.detach()
|
||||||
|
argumentsByParameterIndex[index] = null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChild(slot: Int): IrElement? =
|
||||||
|
if (0 <= slot)
|
||||||
|
argumentsByParameterIndex.getOrNull(slot)
|
||||||
|
else
|
||||||
|
super.getChild(slot)
|
||||||
|
|
||||||
|
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||||
|
if (0 <= slot)
|
||||||
|
putArgument(slot, newChild.assertCast())
|
||||||
|
else
|
||||||
|
super.replaceChild(slot, newChild)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
|
super.acceptChildren(visitor, data)
|
||||||
|
argumentsByParameterIndex.forEach { it?.accept(visitor, data) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ abstract class IrPrimitiveCallBase(
|
|||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
override val operator: IrOperator,
|
override val operator: IrOperator,
|
||||||
override val descriptor: CallableDescriptor
|
override val descriptor: CallableDescriptor
|
||||||
) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrFunCall {
|
) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall {
|
||||||
override val superQualifier: ClassDescriptor? get() = null
|
override val superQualifier: ClassDescriptor? get() = null
|
||||||
override var dispatchReceiver: IrExpression?
|
override var dispatchReceiver: IrExpression?
|
||||||
get() = null
|
get() = null
|
||||||
@@ -49,7 +49,7 @@ abstract class IrPrimitiveCallBase(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||||
return visitor.visitFunCall(this, data)
|
return visitor.visitCall(this, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -29,9 +29,9 @@ abstract class IrPropertyAccessorCallBase(
|
|||||||
override val descriptor: CallableDescriptor,
|
override val descriptor: CallableDescriptor,
|
||||||
override val operator: IrOperator? = null,
|
override val operator: IrOperator? = null,
|
||||||
override val superQualifier: ClassDescriptor? = null
|
override val superQualifier: ClassDescriptor? = null
|
||||||
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrFunCall {
|
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||||
return visitor.visitFunCall(this, data)
|
return visitor.visitCall(this, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ class IrGetterCallImpl(
|
|||||||
descriptor: CallableDescriptor,
|
descriptor: CallableDescriptor,
|
||||||
operator: IrOperator? = null,
|
operator: IrOperator? = null,
|
||||||
superQualifier: ClassDescriptor? = null
|
superQualifier: ClassDescriptor? = null
|
||||||
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrFunCall {
|
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
@@ -72,7 +72,7 @@ class IrSetterCallImpl(
|
|||||||
descriptor: CallableDescriptor,
|
descriptor: CallableDescriptor,
|
||||||
operator: IrOperator? = null,
|
operator: IrOperator? = null,
|
||||||
superQualifier: ClassDescriptor? = null
|
superQualifier: ClassDescriptor? = null
|
||||||
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrFunCall {
|
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall, data: String) {
|
override fun visitGeneralCall(expression: IrGeneralCall, data: String) {
|
||||||
expression.dumpLabeledElementWith(data) {
|
expression.dumpLabeledElementWith(data) {
|
||||||
expression.dispatchReceiver?.accept(this, "\$this")
|
expression.dispatchReceiver?.accept(this, "\$this")
|
||||||
expression.extensionReceiver?.accept(this, "\$receiver")
|
expression.extensionReceiver?.accept(this, "\$receiver")
|
||||||
|
|||||||
@@ -90,13 +90,16 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
|||||||
override fun visitThisReference(expression: IrThisReference, data: Nothing?): String =
|
override fun visitThisReference(expression: IrThisReference, data: Nothing?): String =
|
||||||
"THIS ${expression.classDescriptor.render()} type=${expression.type.render()}"
|
"THIS ${expression.classDescriptor.render()} type=${expression.type.render()}"
|
||||||
|
|
||||||
override fun visitFunCall(expression: IrFunCall, data: Nothing?): String =
|
override fun visitCall(expression: IrCall, data: Nothing?): String =
|
||||||
"CALL .${expression.descriptor.name} ${expression.renderSuperQualifier()}" +
|
"CALL .${expression.descriptor.name} ${expression.renderSuperQualifier()}" +
|
||||||
"type=${expression.type.render()} operator=${expression.operator}"
|
"type=${expression.type.render()} operator=${expression.operator}"
|
||||||
|
|
||||||
private fun IrFunCall.renderSuperQualifier(): String =
|
private fun IrCall.renderSuperQualifier(): String =
|
||||||
superQualifier?.let { "superQualifier=${it.name} " } ?: ""
|
superQualifier?.let { "superQualifier=${it.name} " } ?: ""
|
||||||
|
|
||||||
|
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: Nothing?): String =
|
||||||
|
"DELEGATING_CONSTRUCTOR_CALL ${expression.descriptor.containingDeclaration.name}"
|
||||||
|
|
||||||
override fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: Nothing?): String =
|
override fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: Nothing?): String =
|
||||||
"NESTED_INITIALIZERS_CALL classDescriptor=${expression.classDescriptor.name}"
|
"NESTED_INITIALIZERS_CALL classDescriptor=${expression.classDescriptor.name}"
|
||||||
|
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ interface IrElementVisitor<out R, in D> {
|
|||||||
fun visitGetBackingField(expression: IrGetBackingField, data: D) = visitDeclarationReference(expression, data)
|
fun visitGetBackingField(expression: IrGetBackingField, data: D) = visitDeclarationReference(expression, data)
|
||||||
fun visitSetBackingField(expression: IrSetBackingField, data: D) = visitDeclarationReference(expression, data)
|
fun visitSetBackingField(expression: IrSetBackingField, data: D) = visitDeclarationReference(expression, data)
|
||||||
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: D) = visitDeclarationReference(expression, data)
|
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: D) = visitDeclarationReference(expression, data)
|
||||||
fun visitCall(expression: IrCall, data: D) = visitDeclarationReference(expression, data)
|
fun visitGeneralCall(expression: IrGeneralCall, data: D) = visitDeclarationReference(expression, data)
|
||||||
fun visitFunCall(expression: IrFunCall, data: D) = visitCall(expression, data)
|
fun visitCall(expression: IrCall, data: D) = visitGeneralCall(expression, data)
|
||||||
fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitCall(expression, data)
|
fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitGeneralCall(expression, data)
|
||||||
fun visitCallableReference(expression: IrCallableReference, data: D) = visitDeclarationReference(expression, data)
|
fun visitCallableReference(expression: IrCallableReference, data: D) = visitDeclarationReference(expression, data)
|
||||||
|
|
||||||
fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: D) = visitExpression(expression, data)
|
fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: D) = visitExpression(expression, data)
|
||||||
|
|||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
open class Base(val x: Int, val y: Int)
|
||||||
|
|
||||||
|
class Test1(xx: Int, yy: Int) : Base(y = yy, x = xx)
|
||||||
|
|
||||||
|
class Test2 : Base {
|
||||||
|
constructor(xx: Int, yy: Int) : super(y = yy, x = xx)
|
||||||
|
constructor(xxx: Int, yyy: Int, a: Any) : this(yy = yyy, xx = xxx)
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
FILE /argumentReorderingInDelegatingConstructorCall.kt
|
||||||
|
CLASS CLASS Base
|
||||||
|
FUN public constructor Base(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||||
|
BLOCK_BODY
|
||||||
|
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||||
|
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
|
SET_BACKING_FIELD y type=kotlin.Unit operator=null
|
||||||
|
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
|
PROPERTY public final val x: kotlin.Int getter=null setter=null
|
||||||
|
EXPRESSION_BODY
|
||||||
|
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
|
PROPERTY public final val y: kotlin.Int getter=null setter=null
|
||||||
|
EXPRESSION_BODY
|
||||||
|
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
|
CLASS CLASS Test1
|
||||||
|
FUN public constructor Test1(/*0*/ xx: kotlin.Int, /*1*/ yy: kotlin.Int)
|
||||||
|
BLOCK_BODY
|
||||||
|
BLOCK type=Base operator=ARGUMENTS_REORDERING_FOR_CALL
|
||||||
|
VAR val tmp0_y: kotlin.Int
|
||||||
|
GET_VAR yy type=kotlin.Int operator=null
|
||||||
|
VAR val tmp1_x: kotlin.Int
|
||||||
|
GET_VAR xx type=kotlin.Int operator=null
|
||||||
|
CALL .<init> type=Base operator=SUPER_CONSTRUCTOR_CALL
|
||||||
|
x: GET_VAR tmp1_x type=kotlin.Int operator=null
|
||||||
|
y: GET_VAR tmp0_y type=kotlin.Int operator=null
|
||||||
|
CLASS CLASS Test2
|
||||||
|
nestedInitializers: BLOCK_BODY
|
||||||
|
FUN public constructor Test2(/*0*/ xx: kotlin.Int, /*1*/ yy: kotlin.Int)
|
||||||
|
BLOCK_BODY
|
||||||
|
BLOCK type=Base operator=ARGUMENTS_REORDERING_FOR_CALL
|
||||||
|
VAR val tmp0_y: kotlin.Int
|
||||||
|
GET_VAR yy type=kotlin.Int operator=null
|
||||||
|
VAR val tmp1_x: kotlin.Int
|
||||||
|
GET_VAR xx type=kotlin.Int operator=null
|
||||||
|
TYPE_OP operator=IMPLICIT_CAST typeOperand=Base
|
||||||
|
DELEGATING_CONSTRUCTOR_CALL Base
|
||||||
|
x: GET_VAR tmp1_x type=kotlin.Int operator=null
|
||||||
|
y: GET_VAR tmp0_y type=kotlin.Int operator=null
|
||||||
|
NESTED_INITIALIZERS_CALL classDescriptor=Test2
|
||||||
|
FUN public constructor Test2(/*0*/ xxx: kotlin.Int, /*1*/ yyy: kotlin.Int, /*2*/ a: kotlin.Any)
|
||||||
|
BLOCK_BODY
|
||||||
|
BLOCK type=Test2 operator=ARGUMENTS_REORDERING_FOR_CALL
|
||||||
|
VAR val tmp0_yy: kotlin.Int
|
||||||
|
GET_VAR yyy type=kotlin.Int operator=null
|
||||||
|
VAR val tmp1_xx: kotlin.Int
|
||||||
|
GET_VAR xxx type=kotlin.Int operator=null
|
||||||
|
TYPE_OP operator=IMPLICIT_CAST typeOperand=Test2
|
||||||
|
DELEGATING_CONSTRUCTOR_CALL Test2
|
||||||
|
xx: GET_VAR tmp1_xx type=kotlin.Int operator=null
|
||||||
|
yy: GET_VAR tmp0_yy type=kotlin.Int operator=null
|
||||||
+1
-1
@@ -16,7 +16,7 @@ FILE /classMembers.kt
|
|||||||
GET_VAR z type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
GET_VAR z type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
FUN public constructor C()
|
FUN public constructor C()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=C operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL C
|
||||||
x: CONST Int type=kotlin.Int value='0'
|
x: CONST Int type=kotlin.Int value='0'
|
||||||
y: CONST Int type=kotlin.Int value='0'
|
y: CONST Int type=kotlin.Int value='0'
|
||||||
z: CONST Int type=kotlin.Int value='0'
|
z: CONST Int type=kotlin.Int value='0'
|
||||||
|
|||||||
+3
-3
@@ -6,12 +6,12 @@ FILE /delegatingConstructorCallsInSecondaryConstructors.kt
|
|||||||
nestedInitializers: BLOCK_BODY
|
nestedInitializers: BLOCK_BODY
|
||||||
FUN public constructor Test()
|
FUN public constructor Test()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=Base operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL Base
|
||||||
NESTED_INITIALIZERS_CALL classDescriptor=Test
|
NESTED_INITIALIZERS_CALL classDescriptor=Test
|
||||||
FUN public constructor Test(/*0*/ xx: kotlin.Int)
|
FUN public constructor Test(/*0*/ xx: kotlin.Int)
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=Base operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL Base
|
||||||
NESTED_INITIALIZERS_CALL classDescriptor=Test
|
NESTED_INITIALIZERS_CALL classDescriptor=Test
|
||||||
FUN public constructor Test(/*0*/ xx: kotlin.Short)
|
FUN public constructor Test(/*0*/ xx: kotlin.Short)
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=Test operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL Test
|
||||||
|
|||||||
+2
-2
@@ -48,7 +48,7 @@ FILE /initVar.kt
|
|||||||
GET_VAR value type=kotlin.Int operator=null
|
GET_VAR value type=kotlin.Int operator=null
|
||||||
FUN public constructor TestInitVarWithCustomSetterWithExplicitCtor()
|
FUN public constructor TestInitVarWithCustomSetterWithExplicitCtor()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=kotlin.Any operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL Any
|
||||||
NESTED_INITIALIZERS_CALL classDescriptor=TestInitVarWithCustomSetterWithExplicitCtor
|
NESTED_INITIALIZERS_CALL classDescriptor=TestInitVarWithCustomSetterWithExplicitCtor
|
||||||
CLASS CLASS TestInitVarWithCustomSetterInCtor
|
CLASS CLASS TestInitVarWithCustomSetterInCtor
|
||||||
nestedInitializers: BLOCK_BODY
|
nestedInitializers: BLOCK_BODY
|
||||||
@@ -59,7 +59,7 @@ FILE /initVar.kt
|
|||||||
GET_VAR value type=kotlin.Int operator=null
|
GET_VAR value type=kotlin.Int operator=null
|
||||||
FUN public constructor TestInitVarWithCustomSetterInCtor()
|
FUN public constructor TestInitVarWithCustomSetterInCtor()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=kotlin.Any operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL Any
|
||||||
NESTED_INITIALIZERS_CALL classDescriptor=TestInitVarWithCustomSetterInCtor
|
NESTED_INITIALIZERS_CALL classDescriptor=TestInitVarWithCustomSetterInCtor
|
||||||
CALL .<set-x> type=kotlin.Unit operator=EQ
|
CALL .<set-x> type=kotlin.Unit operator=EQ
|
||||||
$this: THIS public final class TestInitVarWithCustomSetterInCtor type=TestInitVarWithCustomSetterInCtor
|
$this: THIS public final class TestInitVarWithCustomSetterInCtor type=TestInitVarWithCustomSetterInCtor
|
||||||
|
|||||||
+1
-1
@@ -26,6 +26,6 @@ FILE /primaryConstructorWithSuperConstructorCall.kt
|
|||||||
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
FUN public constructor TestWithDelegatingConstructor(/*0*/ x: kotlin.Int)
|
FUN public constructor TestWithDelegatingConstructor(/*0*/ x: kotlin.Int)
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=TestWithDelegatingConstructor operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL TestWithDelegatingConstructor
|
||||||
x: GET_VAR x type=kotlin.Int operator=null
|
x: GET_VAR x type=kotlin.Int operator=null
|
||||||
y: CONST Int type=kotlin.Int value='0'
|
y: CONST Int type=kotlin.Int value='0'
|
||||||
|
|||||||
+2
-2
@@ -11,7 +11,7 @@ FILE /secondaryConstructorWithInitializersFromClassBody.kt
|
|||||||
CONST Int type=kotlin.Int value='0'
|
CONST Int type=kotlin.Int value='0'
|
||||||
FUN public constructor TestProperty()
|
FUN public constructor TestProperty()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=Base operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL Base
|
||||||
NESTED_INITIALIZERS_CALL classDescriptor=TestProperty
|
NESTED_INITIALIZERS_CALL classDescriptor=TestProperty
|
||||||
CLASS CLASS TestInitBlock
|
CLASS CLASS TestInitBlock
|
||||||
nestedInitializers: BLOCK_BODY
|
nestedInitializers: BLOCK_BODY
|
||||||
@@ -21,5 +21,5 @@ FILE /secondaryConstructorWithInitializersFromClassBody.kt
|
|||||||
PROPERTY public final val x: kotlin.Int getter=null setter=null
|
PROPERTY public final val x: kotlin.Int getter=null setter=null
|
||||||
FUN public constructor TestInitBlock()
|
FUN public constructor TestInitBlock()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=Base operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL Base
|
||||||
NESTED_INITIALIZERS_CALL classDescriptor=TestInitBlock
|
NESTED_INITIALIZERS_CALL classDescriptor=TestInitBlock
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ FILE /secondaryConstructors.kt
|
|||||||
nestedInitializers: BLOCK_BODY
|
nestedInitializers: BLOCK_BODY
|
||||||
FUN public constructor C()
|
FUN public constructor C()
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=C operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL C
|
||||||
x: CONST Int type=kotlin.Int value='0'
|
x: CONST Int type=kotlin.Int value='0'
|
||||||
FUN public constructor C(/*0*/ x: kotlin.Int)
|
FUN public constructor C(/*0*/ x: kotlin.Int)
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL .<init> type=kotlin.Any operator=DELEGATING_CONSTRUCTOR_CALL
|
DELEGATING_CONSTRUCTOR_CALL Any
|
||||||
NESTED_INITIALIZERS_CALL classDescriptor=C
|
NESTED_INITIALIZERS_CALL classDescriptor=C
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/classes"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/classes"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("argumentReorderingInDelegatingConstructorCall.kt")
|
||||||
|
public void testArgumentReorderingInDelegatingConstructorCall() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("classMembers.kt")
|
@TestMetadata("classMembers.kt")
|
||||||
public void testClassMembers() throws Exception {
|
public void testClassMembers() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/classMembers.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/classMembers.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user