Preliminary work on loops.
This commit is contained in:
committed by
Dmitry Petrov
parent
de5181d642
commit
8500f5ddb2
+1
-7
@@ -22,11 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||
|
||||
class DeclarationGenerator(override val context: GeneratorContext) : IrGenerator {
|
||||
fun generateAnnotationEntries(annotationEntries: List<KtAnnotationEntry>) {
|
||||
@@ -140,9 +136,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : IrGenerator
|
||||
}
|
||||
|
||||
private fun generateExpressionWithinContext(ktExpression: KtExpression, scopeOwner: DeclarationDescriptor): IrExpression =
|
||||
StatementGenerator(context, scopeOwner, TemporaryVariableFactory(scopeOwner))
|
||||
.generateExpression(ktExpression)
|
||||
.toExpectedType(getExpectedTypeForLastInferredCall(ktExpression))
|
||||
FunctionBodyGenerator(context).generateFunctionBody(scopeOwner, ktExpression)
|
||||
|
||||
private fun generateFunctionBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody {
|
||||
val irRhs = generateExpressionWithinContext(ktBody, scopeOwner)
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||
|
||||
class FunctionBodyGenerator(override val context: GeneratorContext): IrGenerator {
|
||||
fun generateFunctionBody(scopeOwner: DeclarationDescriptor, ktExpression: KtExpression): IrExpression {
|
||||
resetInternalContext()
|
||||
val irExpression = StatementGenerator(context, scopeOwner, this)
|
||||
.generateExpression(ktExpression)
|
||||
.toExpectedType(getExpectedTypeForLastInferredCall(ktExpression))
|
||||
postprocessFunctionBody()
|
||||
return irExpression
|
||||
}
|
||||
|
||||
private fun resetInternalContext() {
|
||||
}
|
||||
|
||||
private fun postprocessFunctionBody() {
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -44,8 +44,9 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
class StatementGenerator(
|
||||
override val context: GeneratorContext,
|
||||
val scopeOwner: DeclarationDescriptor,
|
||||
val temporaryVariableFactory: TemporaryVariableFactory
|
||||
val functionBodyGenerator: FunctionBodyGenerator
|
||||
) : KtVisitor<IrStatement, Nothing?>(), IrGenerator {
|
||||
val temporaryVariableFactory: TemporaryVariableFactory = TemporaryVariableFactory(scopeOwner)
|
||||
|
||||
fun generateExpression(ktExpression: KtExpression): IrExpression =
|
||||
ktExpression.genExpr()
|
||||
@@ -292,4 +293,6 @@ class StatementGenerator(
|
||||
|
||||
override fun visitWhenExpression(expression: KtWhenExpression, data: Nothing?): IrStatement =
|
||||
WhenExpressionGenerator(this).generate(expression)
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -27,4 +27,6 @@ const val MODULE_SLOT = 0
|
||||
const val INITIALIZER_SLOT = 0
|
||||
const val WHEN_SUBJECT_VARIABLE_SLOT = -1
|
||||
const val WHEN_ELSE_EXPRESSION_SLOT = -2
|
||||
const val BRANCH_RESULT_SLOT = -1
|
||||
const val BRANCH_RESULT_SLOT = -1
|
||||
const val LOOP_BODY_SLOT = -1
|
||||
const val LOOP_CONDITION_SLOT = -2
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrLoopExpression : IrExpression {
|
||||
var body: IrExpression
|
||||
}
|
||||
|
||||
interface IrConditionalLoopExpression : IrLoopExpression {
|
||||
var condition: IrExpression
|
||||
}
|
||||
|
||||
interface IrWhileLoopExpression : IrConditionalLoopExpression
|
||||
|
||||
interface IrDoWhileLoopExpression : IrConditionalLoopExpression
|
||||
|
||||
abstract class IrLoopExpressionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int
|
||||
) : IrExpressionBase(startOffset, endOffset, null), IrLoopExpression {
|
||||
|
||||
|
||||
private var bodyImpl: IrExpression? = null
|
||||
override var body: IrExpression
|
||||
get() = bodyImpl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
bodyImpl?.detach()
|
||||
bodyImpl = value
|
||||
value.setTreeLocation(this, LOOP_BODY_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
LOOP_BODY_SLOT -> body
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
LOOP_BODY_SLOT -> body = newChild.assertCast()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class IrConditionalLoopExpressionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int
|
||||
) : IrLoopExpressionBase(startOffset, endOffset), IrConditionalLoopExpression {
|
||||
private var conditionImpl: IrExpression? = null
|
||||
override var condition: IrExpression
|
||||
get() = conditionImpl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
conditionImpl?.detach()
|
||||
conditionImpl = value
|
||||
value.setTreeLocation(this, LOOP_CONDITION_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
LOOP_CONDITION_SLOT -> condition
|
||||
else -> super.getChild(slot)
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
LOOP_CONDITION_SLOT -> condition = newChild.assertCast()
|
||||
else -> super.replaceChild(slot, newChild)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IrWhileLoopExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int
|
||||
) : IrConditionalLoopExpressionBase(startOffset, endOffset), IrWhileLoopExpression {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
condition: IrExpression,
|
||||
body: IrExpression
|
||||
) : this(startOffset, endOffset) {
|
||||
this.condition = condition
|
||||
this.body = body
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitWhileLoop(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
condition.accept(visitor, data)
|
||||
body.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
class IrDoWhileLoopExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int
|
||||
) : IrConditionalLoopExpressionBase(startOffset, endOffset), IrDoWhileLoopExpression {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
body: IrExpression,
|
||||
condition: IrExpression
|
||||
) : this(startOffset, endOffset) {
|
||||
this.condition = condition
|
||||
this.body = body
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitDoWhileLoop(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
body.accept(visitor, data)
|
||||
condition.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,12 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitWhenExpression(expression: IrWhenExpression, data: D) = visitExpression(expression, data)
|
||||
fun visitBranch(branch: IrBranch, data: D): R = visitElement(branch, data)
|
||||
|
||||
fun visitLoop(loop: IrLoopExpression, data: D) = visitExpression(loop, data)
|
||||
fun visitWhileLoop(loop: IrWhileLoopExpression, data: D) = visitLoop(loop, data)
|
||||
fun visitDoWhileLoop(loop: IrDoWhileLoopExpression, data: D) = visitLoop(loop, data)
|
||||
|
||||
// NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered
|
||||
fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: D) = visitDeclaration(declaration, data)
|
||||
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user