[FIR] Add extracting contracts in raw fir builder and light tree builder
This commit is contained in:
+35
@@ -9,6 +9,8 @@ import com.intellij.psi.tree.IElementType
|
|||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.builder.buildRawContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
@@ -17,7 +19,9 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
|||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.buildSingleExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.buildSingleExpressionBlock
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.*
|
import org.jetbrains.kotlin.fir.references.builder.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.symbols.constructStarProjectedType
|
import org.jetbrains.kotlin.fir.symbols.constructStarProjectedType
|
||||||
@@ -35,6 +39,8 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
fun String.parseCharacter(): Char? {
|
fun String.parseCharacter(): Char? {
|
||||||
// Strip the quotes
|
// Strip the quotes
|
||||||
@@ -458,3 +464,32 @@ private val GET_VALUE = Name.identifier("getValue")
|
|||||||
private val SET_VALUE = Name.identifier("setValue")
|
private val SET_VALUE = Name.identifier("setValue")
|
||||||
private val PROVIDE_DELEGATE = Name.identifier("provideDelegate")
|
private val PROVIDE_DELEGATE = Name.identifier("provideDelegate")
|
||||||
private val DELEGATED_SETTER_PARAM = Name.special("<set-?>")
|
private val DELEGATED_SETTER_PARAM = Name.special("<set-?>")
|
||||||
|
|
||||||
|
fun FirBlock?.extractContractDescriptionIfPossible(): Pair<FirBlock?, FirContractDescription?> {
|
||||||
|
if (this == null) return null to null
|
||||||
|
if (!isContractPresentFirCheck()) return this to null
|
||||||
|
val contractCall = replaceFirstStatement(FirStubStatement) as FirFunctionCall
|
||||||
|
return this to buildRawContractDescription {
|
||||||
|
source = contractCall.source
|
||||||
|
this.contractCall = contractCall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirBlock.isContractPresentFirCheck(): Boolean {
|
||||||
|
val firstStatement = statements.firstOrNull() ?: return false
|
||||||
|
val contractCall = firstStatement as? FirFunctionCall ?: return false
|
||||||
|
if (contractCall.calleeReference.name.asString() != "contract") return false
|
||||||
|
val receiver = contractCall.explicitReceiver as? FirQualifiedAccessExpression ?: return true
|
||||||
|
if (!contractCall.checkReceiver("contracts")) return false
|
||||||
|
if (!receiver.checkReceiver("kotlin")) return false
|
||||||
|
val receiverOfReceiver = receiver.explicitReceiver as? FirQualifiedAccessExpression ?: return false
|
||||||
|
if (receiverOfReceiver.explicitReceiver != null) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirExpression.checkReceiver(name: String?): Boolean {
|
||||||
|
if (this !is FirQualifiedAccessExpression) return false
|
||||||
|
val receiver = explicitReceiver as? FirQualifiedAccessExpression ?: return false
|
||||||
|
val receiverName = (receiver.calleeReference as? FirNamedReference)?.name?.asString() ?: return false
|
||||||
|
return receiverName == name
|
||||||
|
}
|
||||||
|
|||||||
+21
-7
@@ -15,7 +15,9 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.builder.Context
|
import org.jetbrains.kotlin.fir.builder.Context
|
||||||
|
import org.jetbrains.kotlin.fir.builder.extractContractDescriptionIfPossible
|
||||||
import org.jetbrains.kotlin.fir.builder.generateAccessorsByDelegate
|
import org.jetbrains.kotlin.fir.builder.generateAccessorsByDelegate
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||||
@@ -757,7 +759,8 @@ class DeclarationsConverter(
|
|||||||
annotations += modifiers.annotations
|
annotations += modifiers.annotations
|
||||||
typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
|
typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
|
||||||
valueParameters += firValueParameters.map { it.firValueParameter }
|
valueParameters += firValueParameters.map { it.firValueParameter }
|
||||||
body = convertFunctionBody(block, null)
|
val (body, _) = convertFunctionBody(block, null)
|
||||||
|
this.body = body
|
||||||
context.firFunctionTargets.removeLast()
|
context.firFunctionTargets.removeLast()
|
||||||
}.also {
|
}.also {
|
||||||
target.bind(it)
|
target.bind(it)
|
||||||
@@ -1053,7 +1056,11 @@ class DeclarationsConverter(
|
|||||||
valueParameters += firValueParameters
|
valueParameters += firValueParameters
|
||||||
}
|
}
|
||||||
|
|
||||||
body = convertFunctionBody(block, expression)
|
val (body, contractDescription) = convertFunctionBody(block, expression)
|
||||||
|
this.body = body
|
||||||
|
contractDescription?.let {
|
||||||
|
this.contractDescription = contractDescription
|
||||||
|
}
|
||||||
context.firFunctionTargets.removeLast()
|
context.firFunctionTargets.removeLast()
|
||||||
}.also {
|
}.also {
|
||||||
target.bind(it)
|
target.bind(it)
|
||||||
@@ -1178,7 +1185,14 @@ class DeclarationsConverter(
|
|||||||
addCapturedTypeParameters(typeParameters)
|
addCapturedTypeParameters(typeParameters)
|
||||||
}
|
}
|
||||||
valueParametersList?.let { list -> valueParameters += convertValueParameters(list).map { it.firValueParameter } }
|
valueParametersList?.let { list -> valueParameters += convertValueParameters(list).map { it.firValueParameter } }
|
||||||
body = convertFunctionBody(block, expression)
|
val (body, contractDescription) = convertFunctionBody(block, expression)
|
||||||
|
this.body = body
|
||||||
|
contractDescription?.let {
|
||||||
|
// TODO: add error reporting for contracts on lambdas
|
||||||
|
if (this is FirSimpleFunctionBuilder) {
|
||||||
|
this.contractDescription = it
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
context.firFunctionTargets.removeLast()
|
context.firFunctionTargets.removeLast()
|
||||||
}.build().also {
|
}.build().also {
|
||||||
@@ -1190,13 +1204,13 @@ class DeclarationsConverter(
|
|||||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseFunctionBody
|
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseFunctionBody
|
||||||
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.buildFirBody
|
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.buildFirBody
|
||||||
*/
|
*/
|
||||||
private fun convertFunctionBody(blockNode: LighterASTNode?, expression: LighterASTNode?): FirBlock? {
|
private fun convertFunctionBody(blockNode: LighterASTNode?, expression: LighterASTNode?): Pair<FirBlock?, FirContractDescription?> {
|
||||||
return when {
|
return when {
|
||||||
blockNode != null -> return convertBlock(blockNode)
|
blockNode != null -> convertBlock(blockNode).extractContractDescriptionIfPossible()
|
||||||
expression != null -> FirSingleExpressionBlock(
|
expression != null -> FirSingleExpressionBlock(
|
||||||
expressionConverter.getAsFirExpression<FirExpression>(expression, "Function has no body (but should)").toReturn()
|
expressionConverter.getAsFirExpression<FirExpression>(expression, "Function has no body (but should)").toReturn()
|
||||||
)
|
) to null
|
||||||
else -> null
|
else -> null to null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
@@ -55,6 +55,11 @@ public class LightTree2FirConverterTestCaseGenerated extends AbstractLightTree2F
|
|||||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("contractDescription.kt")
|
||||||
|
public void testContractDescription() throws Exception {
|
||||||
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contractDescription.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("derivedClass.kt")
|
@TestMetadata("derivedClass.kt")
|
||||||
public void testDerivedClass() throws Exception {
|
public void testDerivedClass() throws Exception {
|
||||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import org.jetbrains.kotlin.descriptors.Modality
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.builder.buildRawContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||||
@@ -26,6 +28,7 @@ import org.jetbrains.kotlin.fir.expressions.*
|
|||||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirModifiableQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.impl.FirModifiableQualifiedAccess
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.*
|
import org.jetbrains.kotlin.fir.references.builder.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||||
@@ -42,10 +45,24 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.isContractDescriptionCallPsiCheck
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
|
import kotlin.collections.MutableList
|
||||||
|
import kotlin.collections.any
|
||||||
|
import kotlin.collections.contains
|
||||||
|
import kotlin.collections.filterIsInstance
|
||||||
|
import kotlin.collections.first
|
||||||
|
import kotlin.collections.firstOrNull
|
||||||
|
import kotlin.collections.forEach
|
||||||
|
import kotlin.collections.isNotEmpty
|
||||||
|
import kotlin.collections.lastOrNull
|
||||||
|
import kotlin.collections.plusAssign
|
||||||
|
import kotlin.collections.reverse
|
||||||
|
import kotlin.collections.withIndex
|
||||||
|
import kotlin.collections.zip
|
||||||
|
|
||||||
class RawFirBuilder(
|
class RawFirBuilder(
|
||||||
session: FirSession, val baseScopeProvider: FirScopeProvider, val stubMode: Boolean
|
session: FirSession, val baseScopeProvider: FirScopeProvider, val stubMode: Boolean
|
||||||
@@ -199,19 +216,20 @@ class RawFirBuilder(
|
|||||||
FirSingleExpressionBlock(convert())
|
FirSingleExpressionBlock(convert())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtDeclarationWithBody.buildFirBody(): FirBlock? =
|
private fun KtDeclarationWithBody.buildFirBody(): Pair<FirBlock?, FirContractDescription?> =
|
||||||
when {
|
when {
|
||||||
!hasBody() ->
|
!hasBody() ->
|
||||||
null
|
null to null
|
||||||
hasBlockBody() -> if (!stubMode) {
|
hasBlockBody() -> if (!stubMode) {
|
||||||
bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock
|
val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock
|
||||||
|
block.extractContractDescriptionIfPossible()
|
||||||
} else {
|
} else {
|
||||||
FirSingleExpressionBlock(buildExpressionStub { source = this@buildFirBody.toFirSourceElement() }.toReturn())
|
FirSingleExpressionBlock(buildExpressionStub { source = this@buildFirBody.toFirSourceElement() }.toReturn()) to null
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val result = { bodyExpression }.toFirExpression("Function has no body (but should)")
|
val result = { bodyExpression }.toFirExpression("Function has no body (but should)")
|
||||||
// basePsi is null, because 'return' is synthetic & should not be bound to some PSI
|
// basePsi is null, because 'return' is synthetic & should not be bound to some PSI
|
||||||
FirSingleExpressionBlock(result.toReturn(baseSource = null))
|
FirSingleExpressionBlock(result.toReturn(baseSource = null)) to null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +307,11 @@ class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
symbol = FirPropertyAccessorSymbol()
|
symbol = FirPropertyAccessorSymbol()
|
||||||
body = this@toFirPropertyAccessor.buildFirBody()
|
val (body, contractDescription) = this@toFirPropertyAccessor.buildFirBody()
|
||||||
|
this.body = body
|
||||||
|
contractDescription?.let {
|
||||||
|
this.contractDescription = it
|
||||||
|
}
|
||||||
}.also {
|
}.also {
|
||||||
accessorTarget.bind(it)
|
accessorTarget.bind(it)
|
||||||
this@RawFirBuilder.context.firFunctionTargets.removeLast()
|
this@RawFirBuilder.context.firFunctionTargets.removeLast()
|
||||||
@@ -824,7 +846,14 @@ class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
withCapturedTypeParameters {
|
withCapturedTypeParameters {
|
||||||
if (this is FirSimpleFunctionBuilder) addCapturedTypeParameters(this.typeParameters)
|
if (this is FirSimpleFunctionBuilder) addCapturedTypeParameters(this.typeParameters)
|
||||||
body = function.buildFirBody()
|
val (body, contractDescription) = function.buildFirBody()
|
||||||
|
this.body = body
|
||||||
|
contractDescription?.let {
|
||||||
|
// TODO: add error reporting for contracts on lambdas
|
||||||
|
if (this is FirSimpleFunctionBuilder) {
|
||||||
|
this.contractDescription = it
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
context.firFunctionTargets.removeLast()
|
context.firFunctionTargets.removeLast()
|
||||||
}.build().also {
|
}.build().also {
|
||||||
@@ -945,7 +974,8 @@ class RawFirBuilder(
|
|||||||
extractAnnotationsTo(this)
|
extractAnnotationsTo(this)
|
||||||
typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters)
|
typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters)
|
||||||
extractValueParametersTo(this)
|
extractValueParametersTo(this)
|
||||||
body = buildFirBody()
|
val (body, _) = buildFirBody()
|
||||||
|
this.body = body
|
||||||
this@RawFirBuilder.context.firFunctionTargets.removeLast()
|
this@RawFirBuilder.context.firFunctionTargets.removeLast()
|
||||||
}.also {
|
}.also {
|
||||||
target.bind(it)
|
target.bind(it)
|
||||||
|
|||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
// Should have raw description
|
||||||
|
fun test_1() {
|
||||||
|
contract {
|
||||||
|
callsInPlace()
|
||||||
|
}
|
||||||
|
test_1()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_2() {
|
||||||
|
kotlin.contracts.contract {
|
||||||
|
callsInPlace()
|
||||||
|
callsInPlace()
|
||||||
|
}
|
||||||
|
test_2()
|
||||||
|
}
|
||||||
|
|
||||||
|
var test_3: Int = 1
|
||||||
|
get() {
|
||||||
|
contract {
|
||||||
|
callsInPlace()
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
kotlin.contracts.contract {
|
||||||
|
callsInPlace()
|
||||||
|
callsInPlace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_4() {
|
||||||
|
contract()
|
||||||
|
test_4()
|
||||||
|
}
|
||||||
|
|
||||||
|
// should not have raw description
|
||||||
|
|
||||||
|
fun test_5() {
|
||||||
|
test_5()
|
||||||
|
contract()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_6() {
|
||||||
|
aaa.bbb.ccc.contract {
|
||||||
|
|
||||||
|
}
|
||||||
|
test_6()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_7() {
|
||||||
|
contracts.contract {
|
||||||
|
|
||||||
|
}
|
||||||
|
test_7()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_8() {
|
||||||
|
aaa.kotlin.contracts.contract {
|
||||||
|
|
||||||
|
}
|
||||||
|
test_8()
|
||||||
|
}
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
FILE: contractDescription.kt
|
||||||
|
public? final? fun test_1(): R|kotlin/Unit|
|
||||||
|
[Contract description] <
|
||||||
|
contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> {
|
||||||
|
callsInPlace#()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
>
|
||||||
|
{
|
||||||
|
[StubStatement]
|
||||||
|
test_1#()
|
||||||
|
}
|
||||||
|
public? final? fun test_2(): R|kotlin/Unit|
|
||||||
|
[Contract description] <
|
||||||
|
kotlin#.contracts#.contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> {
|
||||||
|
callsInPlace#()
|
||||||
|
callsInPlace#()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
>
|
||||||
|
{
|
||||||
|
[StubStatement]
|
||||||
|
test_2#()
|
||||||
|
}
|
||||||
|
public? final? var test_3: Int = IntegerLiteral(1)
|
||||||
|
public? get(): Int
|
||||||
|
[Contract description] <
|
||||||
|
contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> {
|
||||||
|
callsInPlace#()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
>
|
||||||
|
{
|
||||||
|
[StubStatement]
|
||||||
|
^ IntegerLiteral(1)
|
||||||
|
}
|
||||||
|
public? set(value: Int): R|kotlin/Unit|
|
||||||
|
[Contract description] <
|
||||||
|
kotlin#.contracts#.contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> {
|
||||||
|
callsInPlace#()
|
||||||
|
callsInPlace#()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
>
|
||||||
|
{
|
||||||
|
[StubStatement]
|
||||||
|
}
|
||||||
|
public? final? fun test_4(): R|kotlin/Unit|
|
||||||
|
[Contract description] <
|
||||||
|
contract#()
|
||||||
|
>
|
||||||
|
{
|
||||||
|
[StubStatement]
|
||||||
|
test_4#()
|
||||||
|
}
|
||||||
|
public? final? fun test_5(): R|kotlin/Unit| {
|
||||||
|
test_5#()
|
||||||
|
contract#()
|
||||||
|
}
|
||||||
|
public? final? fun test_6(): R|kotlin/Unit| {
|
||||||
|
aaa#.bbb#.ccc#.contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> {
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
)
|
||||||
|
test_6#()
|
||||||
|
}
|
||||||
|
public? final? fun test_7(): R|kotlin/Unit| {
|
||||||
|
contracts#.contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> {
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
)
|
||||||
|
test_7#()
|
||||||
|
}
|
||||||
|
public? final? fun test_8(): R|kotlin/Unit| {
|
||||||
|
aaa#.kotlin#.contracts#.contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> {
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
)
|
||||||
|
test_8#()
|
||||||
|
}
|
||||||
+5
@@ -55,6 +55,11 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
|
|||||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("contractDescription.kt")
|
||||||
|
public void testContractDescription() throws Exception {
|
||||||
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contractDescription.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("derivedClass.kt")
|
@TestMetadata("derivedClass.kt")
|
||||||
public void testDerivedClass() throws Exception {
|
public void testDerivedClass() throws Exception {
|
||||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
|
||||||
|
|||||||
@@ -544,7 +544,11 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitStatement(statement: FirStatement) {
|
override fun visitStatement(statement: FirStatement) {
|
||||||
visitElement(statement)
|
if (statement is FirStubStatement) {
|
||||||
|
print("[StubStatement]")
|
||||||
|
} else {
|
||||||
|
visitElement(statement)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitReturnExpression(returnExpression: FirReturnExpression) {
|
override fun visitReturnExpression(returnExpression: FirReturnExpression) {
|
||||||
|
|||||||
@@ -84,4 +84,13 @@ fun <D> FirBlock.transformAllStatementsExceptLast(transformer: FirTransformer<D>
|
|||||||
TransformData.Nothing
|
TransformData.Nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirBlock.replaceFirstStatement(statement: FirStatement): FirStatement {
|
||||||
|
require(this is FirBlockImpl) {
|
||||||
|
"replaceFirstStatement should not be called for ${this::class.simpleName}"
|
||||||
|
}
|
||||||
|
val existed = statements[0]
|
||||||
|
statements[0] = statement
|
||||||
|
return existed
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.expressions.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirPureAbstractElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
|
|
||||||
|
object FirStubStatement : FirPureAbstractElement(), FirStatement {
|
||||||
|
override val source: FirSourceElement?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
override val annotations: List<FirAnnotationCall>
|
||||||
|
get() = emptyList()
|
||||||
|
|
||||||
|
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirStatement {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||||
|
|
||||||
|
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -55,6 +55,11 @@ public class FirVisualizerForRawFirDataGenerated extends AbstractFirVisualizer {
|
|||||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("contractDescription.kt")
|
||||||
|
public void testContractDescription() throws Exception {
|
||||||
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contractDescription.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("derivedClass.kt")
|
@TestMetadata("derivedClass.kt")
|
||||||
public void testDerivedClass() throws Exception {
|
public void testDerivedClass() throws Exception {
|
||||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
|
||||||
|
|||||||
+5
@@ -55,6 +55,11 @@ public class PsiVisualizerForRawFirDataGenerated extends AbstractPsiVisualizer {
|
|||||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("contractDescription.kt")
|
||||||
|
public void testContractDescription() throws Exception {
|
||||||
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contractDescription.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("derivedClass.kt")
|
@TestMetadata("derivedClass.kt")
|
||||||
public void testDerivedClass() throws Exception {
|
public void testDerivedClass() throws Exception {
|
||||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
|
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user