Lambda expressions (no closures yet).
This commit is contained in:
committed by
Dmitry Petrov
parent
0b647ac358
commit
83c3bdd788
+5
@@ -236,6 +236,11 @@
|
||||
<scope name="idea openapi" level="WARNING" enabled="true" />
|
||||
<scope name="runtime.classes" level="ERROR" enabled="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
|
||||
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
|
||||
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="LoopToCallChain" enabled="false" level="INFO" enabled_by_default="false" />
|
||||
<inspection_tool class="MethodMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="m_onlyPrivateOrFinal" value="false" />
|
||||
<option name="m_ignoreEmptyMethods" value="true" />
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||
import org.jetbrains.kotlin.psi.KtLoopExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
@@ -30,8 +32,6 @@ class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: Ge
|
||||
private val loopTable = HashMap<KtLoopExpression, IrLoop>()
|
||||
|
||||
fun generateFunctionBody(ktBody: KtExpression): IrBody {
|
||||
resetInternalContext()
|
||||
|
||||
val statementGenerator = createStatementGenerator()
|
||||
|
||||
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
||||
@@ -42,21 +42,17 @@ class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: Ge
|
||||
}
|
||||
else {
|
||||
val irBodyExpression = statementGenerator.generateExpression(ktBody)
|
||||
val irReturn = IrReturnImpl(ktBody.startOffset, ktBody.endOffset, context.builtIns.nothingType, scopeOwner, irBodyExpression)
|
||||
irBlockBody.addStatement(irReturn)
|
||||
irBlockBody.addStatement(irBodyExpression.wrapWithReturn())
|
||||
}
|
||||
|
||||
postprocessFunctionBody()
|
||||
|
||||
return irBlockBody
|
||||
}
|
||||
|
||||
private fun resetInternalContext() {
|
||||
loopTable.clear()
|
||||
}
|
||||
|
||||
private fun postprocessFunctionBody() {
|
||||
}
|
||||
private fun IrExpression.wrapWithReturn() =
|
||||
if (KotlinBuiltIns.isNothing(type))
|
||||
this
|
||||
else
|
||||
IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, scopeOwner, this)
|
||||
|
||||
fun generatePropertyInitializerBody(ktInitializer: KtExpression): IrBody =
|
||||
IrExpressionBodyImpl(ktInitializer.startOffset, ktInitializer.endOffset,
|
||||
@@ -71,5 +67,24 @@ class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: Ge
|
||||
|
||||
fun getLoop(expression: KtExpression): IrLoop? =
|
||||
loopTable[expression]
|
||||
|
||||
fun generateLambdaBody(ktFun: KtFunctionLiteral): IrBody {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
|
||||
val ktBody = ktFun.bodyExpression!!
|
||||
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
||||
if (ktBody is KtBlockExpression) {
|
||||
for (ktStatement in ktBody.statements.subList(0, ktBody.statements.size - 1)) {
|
||||
irBlockBody.addStatement(statementGenerator.generateStatement(ktStatement))
|
||||
}
|
||||
val ktReturnedValue = ktBody.statements.last()
|
||||
irBlockBody.addStatement(statementGenerator.generateExpression(ktReturnedValue).wrapWithReturn())
|
||||
}
|
||||
else {
|
||||
irBlockBody.addStatement(statementGenerator.generateExpression(ktBody).wrapWithReturn())
|
||||
}
|
||||
|
||||
return irBlockBody
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class LocalFunctionGenerator(val statementGenerator: StatementGenerator) : GeneratorWithScope {
|
||||
override val scope: Scope get() = statementGenerator.scope
|
||||
override val context: GeneratorContext get() = statementGenerator.context
|
||||
|
||||
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
|
||||
val ktFun = ktLambda.functionLiteral
|
||||
val lambdaExpressionType = getInferredTypeWithSmartcastsOrFail(ktLambda)
|
||||
val lambdaDescriptor = getOrFail(BindingContext.FUNCTION, ktFun)
|
||||
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrOperator.LAMBDA)
|
||||
|
||||
val irFun = IrFunctionImpl(ktFun.startOffset, ktFun.endOffset, IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA, lambdaDescriptor)
|
||||
irFun.body = BodyGenerator(lambdaDescriptor, statementGenerator.context).generateLambdaBody(ktFun)
|
||||
irBlock.addStatement(irFun)
|
||||
|
||||
irBlock.addStatement(IrCallableReferenceImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, lambdaDescriptor))
|
||||
|
||||
return irBlock
|
||||
}
|
||||
|
||||
}
|
||||
+9
-3
@@ -26,7 +26,9 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.*
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.IntermediateValue
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.createRematerializableOrTemporary
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -40,10 +42,11 @@ import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import java.lang.AssertionError
|
||||
|
||||
class StatementGenerator(
|
||||
override val context: GeneratorContext,
|
||||
val scopeOwner: DeclarationDescriptor,
|
||||
val scopeOwner: CallableDescriptor,
|
||||
val bodyGenerator: BodyGenerator,
|
||||
override val scope: Scope
|
||||
) : KtVisitor<IrStatement, Nothing?>(), GeneratorWithScope {
|
||||
@@ -316,4 +319,7 @@ class StatementGenerator(
|
||||
override fun visitTryExpression(expression: KtTryExpression, data: Nothing?): IrStatement =
|
||||
TryCatchExpressionGenerator(this).generateTryCatch(expression)
|
||||
|
||||
}
|
||||
override fun visitLambdaExpression(expression: KtLambdaExpression, data: Nothing?): IrStatement =
|
||||
LocalFunctionGenerator(this).generateLambda(expression)
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ enum class IrDeclarationKind {
|
||||
|
||||
enum class IrDeclarationOrigin {
|
||||
DEFINED,
|
||||
LOCAL_FUNCTION_FOR_LAMBDA,
|
||||
IR_TEMPORARY_VARIABLE,
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
interface IrCallableReference : IrDeclarationReference {
|
||||
override val descriptor: CallableDescriptor
|
||||
|
||||
// TODO closure
|
||||
}
|
||||
|
||||
class IrCallableReferenceImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
descriptor: CallableDescriptor
|
||||
) : IrDeclarationReferenceBase<CallableDescriptor>(startOffset, endOffset, type, descriptor), IrCallableReference {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitCallableReference(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? {
|
||||
// TODO
|
||||
return null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
@@ -85,6 +85,9 @@ interface IrOperator {
|
||||
object FOR_LOOP_HAS_NEXT : IrOperatorImpl("FOR_LOOP_HAS_NEXT")
|
||||
object FOR_LOOP_NEXT : IrOperatorImpl("FOR_LOOP_NEXT")
|
||||
|
||||
object LAMBDA : IrOperatorImpl("LAMBDA")
|
||||
|
||||
|
||||
data class COMPONENT_N private constructor(val index: Int) : IrOperatorImpl("COMPONENT_$index") {
|
||||
companion object {
|
||||
private val precreatedComponents = Array(32) { i -> COMPONENT_N(i + 1) }
|
||||
@@ -97,8 +100,6 @@ interface IrOperator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun IrOperator.isAssignmentOperatorWithResult() =
|
||||
|
||||
@@ -67,10 +67,10 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
"BLOCK_BODY"
|
||||
|
||||
override fun visitExpression(expression: IrExpression, data: Nothing?): String =
|
||||
"? ${expression.javaClass.simpleName} type=${expression.renderType()}"
|
||||
"? ${expression.javaClass.simpleName} type=${expression.type.render()}"
|
||||
|
||||
override fun <T> visitConst(expression: IrConst<T>, data: Nothing?): String =
|
||||
"CONST ${expression.kind} type=${expression.renderType()} value='${expression.value}'"
|
||||
"CONST ${expression.kind} type=${expression.type.render()} value='${expression.value}'"
|
||||
|
||||
override fun visitVararg(expression: IrVararg, data: Nothing?): String =
|
||||
"VARARG type=${expression.type} varargElementType=${expression.varargElementType}"
|
||||
@@ -79,35 +79,35 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
"SPREAD_ELEMENT"
|
||||
|
||||
override fun visitBlock(expression: IrBlock, data: Nothing?): String =
|
||||
"BLOCK type=${expression.renderType()} operator=${expression.operator}"
|
||||
"BLOCK type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitReturn(expression: IrReturn, data: Nothing?): String =
|
||||
"RETURN type=${expression.renderType()}"
|
||||
"RETURN type=${expression.type.render()}"
|
||||
|
||||
override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: Nothing?): String =
|
||||
"\$RECEIVER of: ${expression.descriptor.containingDeclaration.name} type=${expression.renderType()}"
|
||||
"\$RECEIVER of: ${expression.descriptor.containingDeclaration.name} type=${expression.type.render()}"
|
||||
|
||||
override fun visitThisReference(expression: IrThisReference, data: Nothing?): String =
|
||||
"THIS ${expression.classDescriptor.render()} type=${expression.renderType()}"
|
||||
"THIS ${expression.classDescriptor.render()} type=${expression.type.render()}"
|
||||
|
||||
override fun visitCall(expression: IrCall, data: Nothing?): String =
|
||||
"CALL .${expression.descriptor.name} " +
|
||||
"type=${expression.renderType()} operator=${expression.operator}"
|
||||
"type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitGetVariable(expression: IrGetVariable, data: Nothing?): String =
|
||||
"GET_VAR ${expression.descriptor.name} type=${expression.renderType()} operator=${expression.operator}"
|
||||
"GET_VAR ${expression.descriptor.name} type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?): String =
|
||||
"SET_VAR ${expression.descriptor.name} type=${expression.renderType()} operator=${expression.operator}"
|
||||
"SET_VAR ${expression.descriptor.name} type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue, data: Nothing?): String =
|
||||
"GET_OBJECT ${expression.descriptor.name} type=${expression.renderType()}"
|
||||
"GET_OBJECT ${expression.descriptor.name} type=${expression.type.render()}"
|
||||
|
||||
override fun visitGetEnumValue(expression: IrGetEnumValue, data: Nothing?): String =
|
||||
"GET_ENUM_VALUE ${expression.descriptor.name} type=${expression.renderType()}"
|
||||
"GET_ENUM_VALUE ${expression.descriptor.name} type=${expression.type.render()}"
|
||||
|
||||
override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?): String =
|
||||
"STRING_CONCATENATION type=${expression.renderType()}"
|
||||
"STRING_CONCATENATION type=${expression.type.render()}"
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: Nothing?): String =
|
||||
"TYPE_OP operator=${expression.operator} typeOperand=${expression.typeOperand.render()}"
|
||||
@@ -128,16 +128,19 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
"CONTINUE label=${jump.label} depth=${jump.getDepth()}"
|
||||
|
||||
override fun visitThrow(expression: IrThrow, data: Nothing?): String =
|
||||
"THROW type=${expression.renderType()}"
|
||||
"THROW type=${expression.type.render()}"
|
||||
|
||||
override fun visitCallableReference(expression: IrCallableReference, data: Nothing?): String =
|
||||
"CALLABLE_REFERENCE ${expression.descriptor.render()} type=${expression.type.render()}"
|
||||
|
||||
override fun visitTryCatch(tryCatch: IrTryCatch, data: Nothing?): String =
|
||||
"TRY_CATCH type=${tryCatch.renderType()}"
|
||||
"TRY_CATCH type=${tryCatch.type.render()}"
|
||||
|
||||
override fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: Nothing?): String =
|
||||
"DUMMY ${declaration.descriptor.javaClass.simpleName} ${declaration.descriptor.name}"
|
||||
|
||||
override fun visitDummyExpression(expression: IrDummyExpression, data: Nothing?): String =
|
||||
"DUMMY ${expression.description} type=${expression.renderType()}"
|
||||
"DUMMY ${expression.description} type=${expression.type.render()}"
|
||||
|
||||
companion object {
|
||||
private val DESCRIPTOR_RENDERER = DescriptorRenderer.withOptions {
|
||||
@@ -155,9 +158,6 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
internal fun DeclarationDescriptor?.render(): String =
|
||||
this?.let { DESCRIPTOR_RENDERER.render(it) } ?: "<none>"
|
||||
|
||||
internal fun IrExpression.renderType(): String =
|
||||
type.render()
|
||||
|
||||
internal fun KotlinType?.render(): String =
|
||||
this?.let { DESCRIPTOR_RENDERER.renderType(it) } ?: "<no-type>"
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitSetVariable(expression: IrSetVariable, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitCall(expression: IrCall, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitCallableReference(expression: IrCallableReference, data: D) = visitDeclarationReference(expression, data)
|
||||
|
||||
fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data)
|
||||
|
||||
|
||||
@@ -2,7 +2,12 @@ FILE /variableAsFunctionCall.kt
|
||||
FUN public fun kotlin.String.k(): () -> kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
DUMMY KtLambdaExpression type=() -> kotlin.String
|
||||
BLOCK type=() -> kotlin.String operator=LAMBDA
|
||||
FUN local final fun <anonymous>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
$RECEIVER of: k type=kotlin.String
|
||||
CALLABLE_REFERENCE local final fun <anonymous>(): kotlin.String type=() -> kotlin.String
|
||||
FUN public fun test1(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
fun test1() = "42".run { length }
|
||||
@@ -0,0 +1,13 @@
|
||||
FILE /extensionLambda.kt
|
||||
FUN public fun test1(): kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
CALL .run type=kotlin.Int operator=null
|
||||
$receiver: CONST String type=kotlin.String value='42'
|
||||
block: BLOCK type=kotlin.String.() -> kotlin.Int operator=LAMBDA
|
||||
FUN local final fun kotlin.String.<anonymous>(): kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
CALL .<get-length> type=kotlin.Int operator=GET_PROPERTY
|
||||
$this: $RECEIVER of: <anonymous> type=kotlin.String
|
||||
CALLABLE_REFERENCE local final fun kotlin.String.<anonymous>(): kotlin.Int type=kotlin.String.() -> kotlin.Int
|
||||
@@ -0,0 +1 @@
|
||||
val lambda = { 42 }
|
||||
@@ -0,0 +1,9 @@
|
||||
FILE /justLambda.kt
|
||||
PROPERTY public val lambda: () -> kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
BLOCK type=() -> kotlin.Int operator=LAMBDA
|
||||
FUN local final fun <anonymous>(): kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
CONST Int type=kotlin.Int value='42'
|
||||
CALLABLE_REFERENCE local final fun <anonymous>(): kotlin.Int type=() -> kotlin.Int
|
||||
@@ -0,0 +1,20 @@
|
||||
object A
|
||||
object B
|
||||
|
||||
interface IFoo {
|
||||
val A.foo: B get() = B
|
||||
}
|
||||
|
||||
interface IInvoke {
|
||||
operator fun B.invoke() = 42
|
||||
}
|
||||
|
||||
fun test(fooImpl: IFoo, invokeImpl: IInvoke) {
|
||||
with(A) {
|
||||
with(fooImpl) {
|
||||
with(invokeImpl) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
FILE /multipleImplicitReceivers.kt
|
||||
CLASS OBJECT A
|
||||
CLASS OBJECT B
|
||||
CLASS INTERFACE IFoo
|
||||
PROPERTY public open val A.foo: B getter=<get-foo> setter=null
|
||||
PROPERTY_GETTER public open fun A.<get-foo>(): B property=foo
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
GET_OBJECT B type=B
|
||||
CLASS INTERFACE IInvoke
|
||||
FUN public open operator fun B.invoke(): kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
CONST Int type=kotlin.Int value='42'
|
||||
FUN public fun test(/*0*/ fooImpl: IFoo, /*1*/ invokeImpl: IInvoke): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
CALL .with type=kotlin.Int operator=null
|
||||
receiver: GET_OBJECT A type=A
|
||||
block: BLOCK type=A.() -> kotlin.Int operator=LAMBDA
|
||||
FUN local final fun A.<anonymous>(): kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
CALL .with type=kotlin.Int operator=null
|
||||
receiver: GET_VAR fooImpl type=IFoo operator=null
|
||||
block: BLOCK type=IFoo.() -> kotlin.Int operator=LAMBDA
|
||||
FUN local final fun IFoo.<anonymous>(): kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
CALL .with type=kotlin.Int operator=null
|
||||
receiver: GET_VAR invokeImpl type=IInvoke operator=null
|
||||
block: BLOCK type=IInvoke.() -> kotlin.Int operator=LAMBDA
|
||||
FUN local final fun IInvoke.<anonymous>(): kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing
|
||||
CALL .invoke type=kotlin.Int operator=INVOKE
|
||||
$this: $RECEIVER of: <anonymous> type=IInvoke
|
||||
$receiver: CALL .<get-foo> type=B operator=GET_PROPERTY
|
||||
$this: $RECEIVER of: <anonymous> type=IFoo
|
||||
$receiver: $RECEIVER of: <anonymous> type=A
|
||||
CALLABLE_REFERENCE local final fun IInvoke.<anonymous>(): kotlin.Int type=IInvoke.() -> kotlin.Int
|
||||
CALLABLE_REFERENCE local final fun IFoo.<anonymous>(): kotlin.Int type=IFoo.() -> kotlin.Int
|
||||
CALLABLE_REFERENCE local final fun A.<anonymous>(): kotlin.Int type=A.() -> kotlin.Int
|
||||
@@ -352,4 +352,31 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/ir/irText/lambdas")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Lambdas extends AbstractIrTextTestCase {
|
||||
public void testAllFilesPresentInLambdas() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/lambdas"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("extensionLambda.kt")
|
||||
public void testExtensionLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/lambdas/extensionLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("justLambda.kt")
|
||||
public void testJustLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/lambdas/justLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multipleImplicitReceivers.kt")
|
||||
public void testMultipleImplicitReceivers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/lambdas/multipleImplicitReceivers.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user