From b9f09afc6fdff6b7642c68a59604afd7e7f53762 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 11 Apr 2019 16:47:35 +0300 Subject: [PATCH] Raw FIR: introduce lambda argument expressions Without it we cannot distinguish lambda argument from just last argument --- .../kotlin/fir/backend/Fir2IrVisitor.kt | 4 +-- .../kotlin/fir/builder/RawFirBuilder.kt | 10 ++++--- .../rawBuilder/expressions/lambda.txt | 8 ++--- .../testData/rawBuilder/expressions/these.txt | 2 +- .../org/jetbrains/kotlin/fir/FirRenderer.kt | 5 ++++ .../FirLambdaArgumentExpression.kt | 13 ++++++++ .../expressions/FirNamedArgumentExpression.kt | 9 +----- .../FirWrappedArgumentExpression.kt | 24 +++++++++++++++ .../impl/FirLambdaArgumentExpressionImpl.kt | 30 +++++++++++++++++++ .../impl/FirNamedArgumentExpressionImpl.kt | 6 ++++ .../fir/visitors/FirTransformerGenerated.kt | 24 ++++++++++++--- .../fir/visitors/FirVisitorGenerated.kt | 16 +++++++--- .../fir/visitors/FirVisitorVoidGenerated.kt | 24 ++++++++++++--- 13 files changed, 144 insertions(+), 31 deletions(-) create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirLambdaArgumentExpression.kt create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirWrappedArgumentExpression.kt create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirLambdaArgumentExpressionImpl.kt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index b306a3cc033..38d3f1eb24c 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -617,9 +617,9 @@ internal class Fir2IrVisitor( } } - override fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression, data: Any?): IrElement { + override fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression, data: Any?): IrElement { // TODO: change this temporary hack to something correct - return namedArgumentExpression.expression.toIrExpression() + return wrappedArgumentExpression.expression.toIrExpression() } private fun FirQualifiedAccess.toIrExpression(typeRef: FirTypeRef): IrExpression { diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 6115bcf67b8..a5f5a2ceadf 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -312,7 +312,11 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { private fun KtCallElement.extractArgumentsTo(container: FirAbstractCall) { for (argument in this.valueArguments) { - container.arguments += argument.toFirExpression() + val argumentExpression = argument.toFirExpression() + container.arguments += when (argument) { + is KtLambdaArgument -> FirLambdaArgumentExpressionImpl(session, argument, argumentExpression) + else -> argumentExpression + } } } @@ -1244,9 +1248,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { } this.calleeReference = calleeReference firFunctionCalls += this - for (argument in expression.valueArguments) { - arguments += argument.toFirExpression() - } + expression.extractArgumentsTo(this) for (typeArgument in expression.typeArguments) { typeArguments += typeArgument.convert() } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt index 7012a43c720..b87676a4d26 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt @@ -24,7 +24,7 @@ FILE: lambda.kt } - use#(use@fun .(: ): { + use#( = use@fun .(: ): { ^ { lval x: = #.component1() lval y: = #.component2() @@ -33,7 +33,7 @@ FILE: lambda.kt } ) - ^foo use#(use@fun .(): { + ^foo use#( = use@fun .(): { ^ { when () { ==(it#.x#, Int(0)) -> { @@ -50,7 +50,7 @@ FILE: lambda.kt ) } public? final? fun bar(): Int { - ^bar use#(lambda@fun .(): { + ^bar use#( = lambda@fun .(): { ^ { when () { ==(it#.x#, Int(0)) -> { @@ -68,7 +68,7 @@ FILE: lambda.kt } public? final? fun test(list: List): kotlin/Unit { lval map: = mutableMapOf#() - list#.forEach#(forEach@fun .(): { + list#.forEach#( = forEach@fun .(): { ^ { lval : = map#.getOrPut#(it#, getOrPut@fun .(): { ^ { diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt index 0ca10368b3b..9b9a9fd06f8 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt @@ -26,7 +26,7 @@ FILE: these.kt ^extension this#.bar#() } public? final? fun test(some: Some): Int { - ^test with#(some#, with@fun .(): { + ^test with#(some#, = with@fun .(): { ^ { this#.foo#().plus#(this@with.extension#()) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index 30f295355b0..12ef3030ca1 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -630,6 +630,11 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() { namedArgumentExpression.expression.accept(this) } + override fun visitLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression) { + print(" = ") + lambdaArgumentExpression.expression.accept(this) + } + override fun visitCall(call: FirCall) { print("(") call.arguments.renderSeparated() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirLambdaArgumentExpression.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirLambdaArgumentExpression.kt new file mode 100644 index 00000000000..d8b5af6103d --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirLambdaArgumentExpression.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.expressions + +import org.jetbrains.kotlin.fir.visitors.FirVisitor + +interface FirLambdaArgumentExpression : FirWrappedArgumentExpression { + override fun accept(visitor: FirVisitor, data: D): R = + visitor.visitLambdaArgumentExpression(this, data) +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirNamedArgumentExpression.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirNamedArgumentExpression.kt index c7c9f882a36..d8bcbfbe771 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirNamedArgumentExpression.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirNamedArgumentExpression.kt @@ -8,16 +8,9 @@ package org.jetbrains.kotlin.fir.expressions import org.jetbrains.kotlin.fir.visitors.FirVisitor import org.jetbrains.kotlin.name.Name -interface FirNamedArgumentExpression : FirExpression { +interface FirNamedArgumentExpression : FirWrappedArgumentExpression { val name: Name - val expression: FirExpression - override fun accept(visitor: FirVisitor, data: D): R = visitor.visitNamedArgumentExpression(this, data) - - override fun acceptChildren(visitor: FirVisitor, data: D) { - expression.accept(visitor, data) - super.acceptChildren(visitor, data) - } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirWrappedArgumentExpression.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirWrappedArgumentExpression.kt new file mode 100644 index 00000000000..a6669b97e7e --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirWrappedArgumentExpression.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.expressions + +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.visitors.FirVisitor + +interface FirWrappedArgumentExpression : FirExpression { + val expression: FirExpression + + override val typeRef: FirTypeRef + get() = expression.typeRef + + override fun accept(visitor: FirVisitor, data: D): R = + visitor.visitWrappedArgumentExpression(this, data) + + override fun acceptChildren(visitor: FirVisitor, data: D) { + expression.accept(visitor, data) + super.acceptChildren(visitor, data) + } +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirLambdaArgumentExpressionImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirLambdaArgumentExpressionImpl.kt new file mode 100644 index 00000000000..ba2db7c9025 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirLambdaArgumentExpressionImpl.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.expressions.impl + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression +import org.jetbrains.kotlin.fir.transformSingle +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.visitors.FirTransformer + +class FirLambdaArgumentExpressionImpl( + session: FirSession, + psi: PsiElement?, + override var expression: FirExpression +) : FirLambdaArgumentExpression, FirAbstractExpression(session, psi) { + override var typeRef: FirTypeRef + get() = super.typeRef + set(_) {} + + override fun transformChildren(transformer: FirTransformer, data: D): FirElement { + expression = expression.transformSingle(transformer, data) + return super.transformChildren(transformer, data) + } +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirNamedArgumentExpressionImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirNamedArgumentExpressionImpl.kt index ad8b5c7d7b5..6322c9114fd 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirNamedArgumentExpressionImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirNamedArgumentExpressionImpl.kt @@ -9,8 +9,10 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression import org.jetbrains.kotlin.fir.transformSingle +import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.name.Name @@ -20,6 +22,10 @@ class FirNamedArgumentExpressionImpl( override val name: Name, override var expression: FirExpression ) : FirNamedArgumentExpression, FirAbstractExpression(session, psi) { + override var typeRef: FirTypeRef + get() = super.typeRef + set(_) {} + override fun transformChildren(transformer: FirTransformer, data: D): FirElement { expression = expression.transformSingle(transformer, data) return super.transformChildren(transformer, data) diff --git a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirTransformerGenerated.kt b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirTransformerGenerated.kt index 92c7f3ccce7..a7a6b3ffb71 100644 --- a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirTransformerGenerated.kt +++ b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirTransformerGenerated.kt @@ -260,10 +260,6 @@ abstract class FirTransformer : FirVisitor { - return transformExpression(namedArgumentExpression, data) - } - open fun transformThrowExpression(throwExpression: FirThrowExpression, data: D): CompositeTransformResult { return transformExpression(throwExpression, data) } @@ -276,6 +272,18 @@ abstract class FirTransformer : FirVisitor { + return transformExpression(wrappedArgumentExpression, data) + } + + open fun transformLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression, data: D): CompositeTransformResult { + return transformWrappedArgumentExpression(lambdaArgumentExpression, data) + } + + open fun transformNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression, data: D): CompositeTransformResult { + return transformWrappedArgumentExpression(namedArgumentExpression, data) + } + open fun transformLoop(loop: FirLoop, data: D): CompositeTransformResult { return transformStatement(loop, data) } @@ -556,6 +564,10 @@ abstract class FirTransformer : FirVisitor { + return transformLambdaArgumentExpression(lambdaArgumentExpression, data) + } + final override fun visitLoop(loop: FirLoop, data: D): CompositeTransformResult { return transformLoop(loop, data) } @@ -736,6 +748,10 @@ abstract class FirTransformer : FirVisitor { + return transformWrappedArgumentExpression(wrappedArgumentExpression, data) + } + final override fun visitElement(element: FirElement, data: D): CompositeTransformResult { return transformElement(element, data) } diff --git a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorGenerated.kt b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorGenerated.kt index 1c3367aa884..d8cd91a7007 100644 --- a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorGenerated.kt +++ b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorGenerated.kt @@ -260,10 +260,6 @@ abstract class FirVisitor { return visitJump(returnExpression, data) } - open fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression, data: D): R { - return visitExpression(namedArgumentExpression, data) - } - open fun visitThrowExpression(throwExpression: FirThrowExpression, data: D): R { return visitExpression(throwExpression, data) } @@ -276,6 +272,18 @@ abstract class FirVisitor { return visitExpression(whenExpression, data) } + open fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression, data: D): R { + return visitExpression(wrappedArgumentExpression, data) + } + + open fun visitLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression, data: D): R { + return visitWrappedArgumentExpression(lambdaArgumentExpression, data) + } + + open fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression, data: D): R { + return visitWrappedArgumentExpression(namedArgumentExpression, data) + } + open fun visitLoop(loop: FirLoop, data: D): R { return visitStatement(loop, data) } diff --git a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorVoidGenerated.kt b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorVoidGenerated.kt index 659d5b09237..275f77e0688 100644 --- a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorVoidGenerated.kt +++ b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorVoidGenerated.kt @@ -260,10 +260,6 @@ abstract class FirVisitorVoid : FirVisitor() { visitJump(returnExpression, null) } - open fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression) { - visitExpression(namedArgumentExpression, null) - } - open fun visitThrowExpression(throwExpression: FirThrowExpression) { visitExpression(throwExpression, null) } @@ -276,6 +272,18 @@ abstract class FirVisitorVoid : FirVisitor() { visitExpression(whenExpression, null) } + open fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression) { + visitExpression(wrappedArgumentExpression, null) + } + + open fun visitLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression) { + visitWrappedArgumentExpression(lambdaArgumentExpression, null) + } + + open fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression) { + visitWrappedArgumentExpression(namedArgumentExpression, null) + } + open fun visitLoop(loop: FirLoop) { visitStatement(loop, null) } @@ -556,6 +564,10 @@ abstract class FirVisitorVoid : FirVisitor() { visitLabeledElement(labeledElement) } + final override fun visitLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression, data: Nothing?) { + visitLambdaArgumentExpression(lambdaArgumentExpression) + } + final override fun visitLoop(loop: FirLoop, data: Nothing?) { visitLoop(loop) } @@ -736,6 +748,10 @@ abstract class FirVisitorVoid : FirVisitor() { visitWhileLoop(whileLoop) } + final override fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression, data: Nothing?) { + visitWrappedArgumentExpression(wrappedArgumentExpression) + } + final override fun visitElement(element: FirElement, data: Nothing?) { visitElement(element) }