Raw FIR: implement expression trees & conversions from PSI
Testing: total kotlin test controls no stubs in FIR in non-stub-mode #KT-29002 Fixed
This commit is contained in:
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* 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.builder
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.FirReference
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirNamedDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirVariableImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirExplicitThisReference
|
||||
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.types.FirType
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.*
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
internal fun String.parseCharacter(): Char? {
|
||||
// Strip the quotes
|
||||
if (length < 2 || this[0] != '\'' || this[length - 1] != '\'') {
|
||||
return null
|
||||
}
|
||||
val text = substring(1, length - 1) // now there're no quotes
|
||||
|
||||
if (text.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
return if (text[0] != '\\') {
|
||||
// No escape
|
||||
if (text.length == 1) {
|
||||
text[0]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
escapedStringToCharacter(text)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun escapedStringToCharacter(text: String): Char? {
|
||||
assert(text.isNotEmpty() && text[0] == '\\') {
|
||||
"Only escaped sequences must be passed to this routine: $text"
|
||||
}
|
||||
|
||||
// Escape
|
||||
val escape = text.substring(1) // strip the slash
|
||||
when (escape.length) {
|
||||
0 -> {
|
||||
// bare slash
|
||||
return null
|
||||
}
|
||||
1 -> {
|
||||
// one-char escape
|
||||
return translateEscape(escape[0]) ?: return null
|
||||
}
|
||||
5 -> {
|
||||
// unicode escape
|
||||
if (escape[0] == 'u') {
|
||||
try {
|
||||
val intValue = Integer.valueOf(escape.substring(1), 16)
|
||||
return intValue.toInt().toChar()
|
||||
} catch (e: NumberFormatException) {
|
||||
// Will be reported below
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal fun translateEscape(c: Char): Char? =
|
||||
when (c) {
|
||||
't' -> '\t'
|
||||
'b' -> '\b'
|
||||
'n' -> '\n'
|
||||
'r' -> '\r'
|
||||
'\'' -> '\''
|
||||
'\"' -> '\"'
|
||||
'\\' -> '\\'
|
||||
'$' -> '$'
|
||||
else -> null
|
||||
}
|
||||
|
||||
internal fun generateConstantExpressionByLiteral(session: FirSession, expression: KtConstantExpression): FirExpression {
|
||||
val type = expression.node.elementType
|
||||
val text: String = expression.text
|
||||
val convertedText: Any? = when (type) {
|
||||
KtNodeTypes.INTEGER_CONSTANT, KtNodeTypes.FLOAT_CONSTANT -> parseNumericLiteral(text, type)
|
||||
KtNodeTypes.BOOLEAN_CONSTANT -> parseBoolean(text)
|
||||
else -> null
|
||||
}
|
||||
return when (type) {
|
||||
KtNodeTypes.INTEGER_CONSTANT ->
|
||||
if (convertedText is Long &&
|
||||
(hasLongSuffix(text) || hasUnsignedLongSuffix(text) || hasUnsignedSuffix(text) ||
|
||||
convertedText > Int.MAX_VALUE || convertedText < Int.MIN_VALUE)
|
||||
) {
|
||||
FirConstExpressionImpl(
|
||||
session, expression, IrConstKind.Long, convertedText, "Incorrect long: $text"
|
||||
)
|
||||
} else {
|
||||
// TODO: support byte / short
|
||||
FirConstExpressionImpl(session, expression, IrConstKind.Int, (convertedText as Number).toInt(), "Incorrect int: $text")
|
||||
}
|
||||
KtNodeTypes.FLOAT_CONSTANT ->
|
||||
if (convertedText is Float) {
|
||||
FirConstExpressionImpl(
|
||||
session, expression, IrConstKind.Float, convertedText, "Incorrect float: $text"
|
||||
)
|
||||
} else {
|
||||
FirConstExpressionImpl(
|
||||
session, expression, IrConstKind.Double, convertedText as Double, "Incorrect double: $text"
|
||||
)
|
||||
}
|
||||
KtNodeTypes.CHARACTER_CONSTANT ->
|
||||
FirConstExpressionImpl(
|
||||
session, expression, IrConstKind.Char, text.parseCharacter(), "Incorrect character: $text"
|
||||
)
|
||||
KtNodeTypes.BOOLEAN_CONSTANT ->
|
||||
FirConstExpressionImpl(session, expression, IrConstKind.Boolean, convertedText as Boolean)
|
||||
KtNodeTypes.NULL ->
|
||||
FirConstExpressionImpl(session, expression, IrConstKind.Null, null)
|
||||
else ->
|
||||
throw AssertionError("Unknown literal type: $type, $text")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun IElementType.toBinaryName(): Name? {
|
||||
return OperatorConventions.BINARY_OPERATION_NAMES[this]
|
||||
}
|
||||
|
||||
internal fun IElementType.toUnaryName(): Name? {
|
||||
return OperatorConventions.UNARY_OPERATION_NAMES[this]
|
||||
}
|
||||
|
||||
internal fun IElementType.toFirOperation(): FirOperation =
|
||||
when (this) {
|
||||
KtTokens.LT -> FirOperation.LT
|
||||
KtTokens.GT -> FirOperation.GT
|
||||
KtTokens.LTEQ -> FirOperation.LT_EQ
|
||||
KtTokens.GTEQ -> FirOperation.GT_EQ
|
||||
KtTokens.EQEQ -> FirOperation.EQ
|
||||
KtTokens.EXCLEQ -> FirOperation.NOT_EQ
|
||||
KtTokens.EQEQEQ -> FirOperation.IDENTITY
|
||||
KtTokens.EXCLEQEQEQ -> FirOperation.NOT_IDENTITY
|
||||
KtTokens.ANDAND -> FirOperation.AND
|
||||
KtTokens.OROR -> FirOperation.OR
|
||||
KtTokens.IN_KEYWORD -> FirOperation.IN
|
||||
KtTokens.NOT_IN -> FirOperation.NOT_IN
|
||||
KtTokens.RANGE -> FirOperation.RANGE
|
||||
|
||||
KtTokens.EQ -> FirOperation.ASSIGN
|
||||
KtTokens.PLUSEQ -> FirOperation.PLUS_ASSIGN
|
||||
KtTokens.MINUSEQ -> FirOperation.MINUS_ASSIGN
|
||||
KtTokens.MULTEQ -> FirOperation.TIMES_ASSIGN
|
||||
KtTokens.DIVEQ -> FirOperation.DIV_ASSIGN
|
||||
KtTokens.PERCEQ -> FirOperation.REM_ASSIGN
|
||||
|
||||
KtTokens.AS_KEYWORD -> FirOperation.AS
|
||||
KtTokens.AS_SAFE -> FirOperation.SAFE_AS
|
||||
|
||||
else -> throw AssertionError(this.toString())
|
||||
}
|
||||
|
||||
internal fun FirExpression.generateNotNullOrOther(other: FirExpression, caseId: String, basePsi: KtElement): FirWhenExpression {
|
||||
val subjectName = Name.special("<$caseId>")
|
||||
val subjectVariable = generateTemporaryVariable(session, psi, subjectName, this)
|
||||
val subjectExpression = FirWhenSubjectExpression(session, psi)
|
||||
return FirWhenExpressionImpl(
|
||||
session, basePsi, this, subjectVariable
|
||||
).apply {
|
||||
branches += FirWhenBranchImpl(
|
||||
session, psi,
|
||||
FirOperatorCallImpl(session, psi, FirOperation.NOT_EQ).apply {
|
||||
arguments += subjectExpression
|
||||
arguments += FirConstExpressionImpl(session, psi, IrConstKind.Null, null)
|
||||
},
|
||||
FirSingleExpressionBlock(
|
||||
session,
|
||||
generateAccessExpression(session, psi, subjectName)
|
||||
)
|
||||
)
|
||||
branches += FirWhenBranchImpl(
|
||||
session, other.psi, FirElseIfTrueCondition(session, psi),
|
||||
FirSingleExpressionBlock(session, other)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun generateIncrementOrDecrementBlock(
|
||||
session: FirSession,
|
||||
baseExpression: KtUnaryExpression,
|
||||
argument: KtExpression?,
|
||||
callName: Name,
|
||||
prefix: Boolean,
|
||||
convert: KtExpression.() -> FirExpression
|
||||
): FirExpression {
|
||||
if (argument == null) {
|
||||
return FirErrorExpressionImpl(session, argument, "Inc/dec without operand")
|
||||
}
|
||||
return FirBlockImpl(session, baseExpression).apply {
|
||||
val tempName = Name.special("<unary>")
|
||||
statements += generateTemporaryVariable(session, baseExpression, tempName, argument.convert())
|
||||
val resultName = Name.special("<unary-result>")
|
||||
val resultInitializer = FirFunctionCallImpl(session, baseExpression).apply {
|
||||
this.calleeReference = FirSimpleNamedReference(session, baseExpression.operationReference, callName)
|
||||
this.arguments += generateAccessExpression(session, baseExpression, tempName)
|
||||
}
|
||||
val resultVar = generateTemporaryVariable(session, baseExpression, resultName, resultInitializer)
|
||||
val assignment = argument.generateAssignment(
|
||||
session, baseExpression,
|
||||
if (prefix && argument !is KtSimpleNameExpression)
|
||||
generateAccessExpression(session, baseExpression, resultName)
|
||||
else
|
||||
resultInitializer,
|
||||
FirOperation.ASSIGN, convert
|
||||
)
|
||||
|
||||
fun appendAssignment() {
|
||||
if (assignment is FirBlock) {
|
||||
statements += assignment.statements
|
||||
} else {
|
||||
statements += assignment
|
||||
}
|
||||
}
|
||||
|
||||
if (prefix) {
|
||||
if (argument !is KtSimpleNameExpression) {
|
||||
statements += resultVar
|
||||
appendAssignment()
|
||||
statements += generateAccessExpression(session, baseExpression, resultName)
|
||||
} else {
|
||||
appendAssignment()
|
||||
statements += generateAccessExpression(session, baseExpression, argument.getReferencedNameAsName())
|
||||
}
|
||||
} else {
|
||||
appendAssignment()
|
||||
statements += generateAccessExpression(session, baseExpression, tempName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun generateAccessExpression(session: FirSession, psi: PsiElement?, name: Name): FirAccessExpression =
|
||||
FirAccessExpressionImpl(session, psi).apply {
|
||||
calleeReference = FirSimpleNamedReference(session, psi, name)
|
||||
}
|
||||
|
||||
internal fun generateDestructuringBlock(
|
||||
session: FirSession,
|
||||
multiDeclaration: KtDestructuringDeclaration,
|
||||
container: FirNamedDeclaration,
|
||||
extractAnnotationsTo: KtAnnotated.(FirAbstractAnnotatedElement) -> Unit,
|
||||
toFirOrImplicitType: KtTypeReference?.() -> FirType
|
||||
): FirExpression {
|
||||
return FirBlockImpl(session, multiDeclaration).apply {
|
||||
if (container is FirVariable) {
|
||||
statements += container
|
||||
}
|
||||
val isVar = multiDeclaration.isVar
|
||||
for ((index, entry) in multiDeclaration.entries.withIndex()) {
|
||||
statements += FirVariableImpl(
|
||||
session, entry, entry.nameAsSafeName,
|
||||
entry.typeReference.toFirOrImplicitType(), isVar,
|
||||
FirComponentCallImpl(session, entry, index + 1).apply {
|
||||
arguments += generateAccessExpression(session, entry, container.name)
|
||||
}
|
||||
).apply {
|
||||
entry.extractAnnotationsTo(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun generateTemporaryVariable(
|
||||
session: FirSession, psi: PsiElement?, name: Name, initializer: FirExpression
|
||||
): FirVariable = FirVariableImpl(session, psi, name, FirImplicitTypeImpl(session, psi), false, initializer)
|
||||
|
||||
internal fun generateTemporaryVariable(
|
||||
session: FirSession, psi: PsiElement?, specialName: String, initializer: FirExpression
|
||||
): FirVariable = generateTemporaryVariable(session, psi, Name.special("<$specialName>"), initializer)
|
||||
|
||||
private fun FirModifiableAccess.initializeLValue(
|
||||
session: FirSession,
|
||||
left: KtExpression?,
|
||||
convertQualified: KtQualifiedExpression.() -> FirAccess?
|
||||
): FirReference {
|
||||
return when (left) {
|
||||
is KtSimpleNameExpression -> {
|
||||
FirSimpleNamedReference(session, left, left.getReferencedNameAsName())
|
||||
}
|
||||
is KtThisExpression -> {
|
||||
FirExplicitThisReference(session, left, left.getLabelName())
|
||||
}
|
||||
is KtQualifiedExpression -> {
|
||||
val firMemberAccess = left.convertQualified()
|
||||
if (firMemberAccess != null) {
|
||||
explicitReceiver = firMemberAccess.explicitReceiver
|
||||
safe = firMemberAccess.safe
|
||||
firMemberAccess.calleeReference
|
||||
} else {
|
||||
FirErrorNamedReference(session, left, "Unsupported qualified LValue: ${left.text}")
|
||||
}
|
||||
}
|
||||
is KtParenthesizedExpression -> {
|
||||
initializeLValue(session, left.expression, convertQualified)
|
||||
}
|
||||
else -> {
|
||||
FirErrorNamedReference(session, left, "Unsupported LValue: ${left?.javaClass}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun KtExpression?.generateAssignment(
|
||||
session: FirSession,
|
||||
psi: PsiElement?,
|
||||
value: FirExpression,
|
||||
operation: FirOperation,
|
||||
convert: KtExpression.() -> FirExpression
|
||||
): FirStatement {
|
||||
if (this is KtParenthesizedExpression) {
|
||||
return expression.generateAssignment(session, psi, value, operation, convert)
|
||||
}
|
||||
if (this is KtArrayAccessExpression) {
|
||||
val arrayExpression = this.arrayExpression
|
||||
val arraySet = FirArraySetCallImpl(session, psi, value, operation).apply {
|
||||
for (indexExpression in indexExpressions) {
|
||||
arguments += indexExpression.convert()
|
||||
}
|
||||
}
|
||||
if (arrayExpression is KtSimpleNameExpression) {
|
||||
return arraySet.apply {
|
||||
calleeReference = initializeLValue(session, arrayExpression) { convert() as? FirAccess }
|
||||
}
|
||||
}
|
||||
return FirBlockImpl(session, arrayExpression).apply {
|
||||
val name = Name.special("<array-set>")
|
||||
statements += generateTemporaryVariable(
|
||||
session, this@generateAssignment, name,
|
||||
arrayExpression?.convert() ?: FirErrorExpressionImpl(session, arrayExpression, "No array expression")
|
||||
)
|
||||
statements += arraySet.apply { calleeReference = FirSimpleNamedReference(session, arrayExpression, name) }
|
||||
}
|
||||
}
|
||||
if (operation != FirOperation.ASSIGN &&
|
||||
this !is KtSimpleNameExpression && this !is KtThisExpression &&
|
||||
(this !is KtQualifiedExpression || selectorExpression !is KtSimpleNameExpression)
|
||||
) {
|
||||
return FirBlockImpl(session, this).apply {
|
||||
val name = Name.special("<complex-set>")
|
||||
statements += generateTemporaryVariable(
|
||||
session, this@generateAssignment, name,
|
||||
this@generateAssignment?.convert() ?: FirErrorExpressionImpl(session, this@generateAssignment, "No LValue in assignment")
|
||||
)
|
||||
statements += FirPropertyAssignmentImpl(session, psi, value, operation).apply {
|
||||
calleeReference = FirSimpleNamedReference(session, this@generateAssignment, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
return FirPropertyAssignmentImpl(session, psi, value, operation).apply {
|
||||
calleeReference = initializeLValue(session, this@generateAssignment) { convert() as? FirAccess }
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,9 +7,9 @@ FILE: derivedClass.kt
|
||||
|
||||
}
|
||||
<T : Any> public? final? class Derived : Base<T> {
|
||||
public? constructor(x: T): super<Base<T>>()
|
||||
public? constructor(x: T): super<Base<T>>(x#)
|
||||
|
||||
}
|
||||
<T : Any> public? final? function create(x: T): Derived<T> {
|
||||
STUB
|
||||
return@@@create Derived#(x#)
|
||||
}
|
||||
|
||||
@@ -28,30 +28,33 @@ FILE: enums.kt
|
||||
internal get(): Double
|
||||
|
||||
public? final enum entry MERCURY : Planet {
|
||||
public? constructor(): super<Planet>()
|
||||
public? constructor(): super<Planet>(Double(1.0), Double(2.0))
|
||||
|
||||
public? open? override function sayHello(): kotlin.Unit {
|
||||
println#(String(Hello!!!))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public? final enum entry VENERA : Planet {
|
||||
public? constructor(): super<Planet>()
|
||||
public? constructor(): super<Planet>(Double(3.0), Double(4.0))
|
||||
|
||||
public? open? override function sayHello(): kotlin.Unit {
|
||||
println#(String(Ola!!!))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public? final enum entry EARTH : Planet {
|
||||
public? constructor(): super<Planet>()
|
||||
public? constructor(): super<Planet>(Double(5.0), Double(6.0))
|
||||
|
||||
public? open? override function sayHello(): kotlin.Unit {
|
||||
println#(String(Privet!!!))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public? final? property g(val): Double = STUB
|
||||
public? final? property g(val): Double = div#(times#(G#, m#), times#(r#, r#))
|
||||
public? get(): Double
|
||||
|
||||
public? abstract function sayHello(): kotlin.Unit
|
||||
@@ -59,7 +62,7 @@ FILE: enums.kt
|
||||
public? final? companion object Companion {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
public? final? const property G(val): <implicit> = STUB
|
||||
public? final? const property G(val): <implicit> = Double(6.67E-11)
|
||||
public? get(): <implicit>
|
||||
|
||||
}
|
||||
|
||||
@@ -16,19 +16,19 @@ FILE: enums2.kt
|
||||
public? get(): Some
|
||||
|
||||
public? final enum entry FIRST : SomeEnum {
|
||||
public? constructor(): super<SomeEnum>()
|
||||
public? constructor(): super<SomeEnum>(O1#)
|
||||
|
||||
public? open? override function check(y: Some): Boolean {
|
||||
STUB
|
||||
return@@@check Boolean(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public? final enum entry SECOND : SomeEnum {
|
||||
public? constructor(): super<SomeEnum>()
|
||||
public? constructor(): super<SomeEnum>(O2#)
|
||||
|
||||
public? open? override function check(y: Some): Boolean {
|
||||
STUB
|
||||
return@@@check ==(y#, O2#)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ FILE: expectActual.kt
|
||||
|
||||
}
|
||||
public? final? actual function foo(): <implicit> {
|
||||
STUB
|
||||
return@@@foo String(Hello)
|
||||
}
|
||||
public? final? actual property x(val): <implicit> = STUB
|
||||
public? final? actual property x(val): <implicit> = Int(42)
|
||||
public? get(): <implicit>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
FILE: functionTypes.kt
|
||||
<T> public? final? function simpleRun(f: ( (T) -> Unit )): Unit {
|
||||
STUB
|
||||
return@@@simpleRun f#()
|
||||
}
|
||||
<T, R> public? final? function simpleMap List<T>.(f: ( (T) -> R )): R {
|
||||
}
|
||||
<T> public? final? function simpleWith(t: T, f: ( T.() -> Unit )): Unit {
|
||||
STUB
|
||||
return@@@simpleWith t#.f#()
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ FILE: genericFunctions.kt
|
||||
public? final? interface Any {
|
||||
}
|
||||
<reified T : Any> public? final? inline function safeAs Any.(): T? {
|
||||
STUB
|
||||
return@@@safeAs as?/T(this#)
|
||||
}
|
||||
public? abstract class Summator {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
@@ -10,12 +10,12 @@ FILE: nestedClass.kt
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
public? final? class Derived : Base {
|
||||
public? constructor(s: String): super<Base>()
|
||||
public? constructor(s: String): super<Base>(s#)
|
||||
|
||||
}
|
||||
|
||||
public? final? object Obj : Base {
|
||||
public? constructor(): super<Base>()
|
||||
public? constructor(): super<Base>(String())
|
||||
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -4,8 +4,9 @@ FILE: noPrimaryConstructor.kt
|
||||
public? get(): String
|
||||
|
||||
public? constructor(x: String): super<kotlin.Any>() {
|
||||
this#.x# = x#
|
||||
}
|
||||
|
||||
public? constructor(): this<NoPrimary>()
|
||||
public? constructor(): this<NoPrimary>(String())
|
||||
|
||||
}
|
||||
|
||||
@@ -9,15 +9,16 @@ FILE: simpleClass.kt
|
||||
public? final? class SomeClass : SomeInterface {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
private final? property baz(val): <implicit> = STUB
|
||||
private final? property baz(val): <implicit> = Int(42)
|
||||
private get(): <implicit>
|
||||
|
||||
public? open? override function foo(x: Int, y: String): String {
|
||||
return@@@foo plus#(plus#(y#, x#), baz#)
|
||||
}
|
||||
|
||||
public? open? override property bar(var): Boolean
|
||||
public? get(): Boolean {
|
||||
STUB
|
||||
return Boolean(true)
|
||||
}
|
||||
public? set(value: Boolean): kotlin.Unit {
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ FILE: typeParameters.kt
|
||||
public? constructor(): super<AbstractList<Int>>()
|
||||
|
||||
public? open? override function get(index: Int): Int {
|
||||
STUB
|
||||
return@@@get Int(42)
|
||||
}
|
||||
|
||||
public? open? override function concat(other: List<Int>): List<Int> {
|
||||
STUB
|
||||
return@@@concat this#
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
interface A
|
||||
interface B
|
||||
|
||||
class C<T> where T : A, T : B {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
FILE: where.kt
|
||||
public? final? interface A {
|
||||
}
|
||||
public? final? interface B {
|
||||
}
|
||||
<T : A, B> public? final? class C {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
@Target(AnnotationTarget.EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Ann
|
||||
|
||||
fun foo(arg: Int): Int {
|
||||
if (@Ann arg == 0) {
|
||||
@Ann return 1
|
||||
}
|
||||
@Ann if (arg == 1) {
|
||||
return (@Ann 1)
|
||||
}
|
||||
return 42
|
||||
}
|
||||
|
||||
data class Two(x: Int, y: Int)
|
||||
|
||||
fun bar(two: Two) {
|
||||
val (@Ann x, @Ann y) = two
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
FILE: annotated.kt
|
||||
@Target(AnnotationTarget#.EXPRESSION#) @Retention(AnnotationRetention#.SOURCE#) public? final? annotation class Ann {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
}
|
||||
public? final? function foo(arg: Int): Int {
|
||||
when () {
|
||||
==(@Ann() arg#, Int(0)) -> {
|
||||
@Ann() return@@@foo Int(1)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
||||
@Ann() when () {
|
||||
==(arg#, Int(1)) -> {
|
||||
return@@@foo @Ann() Int(1)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
||||
return@@@foo Int(42)
|
||||
}
|
||||
public? final? data class Two {
|
||||
public? constructor(x: Int, y: Int): super<kotlin.Any>()
|
||||
|
||||
}
|
||||
public? final? function bar(two: Two): kotlin.Unit {
|
||||
val <destruct>: <implicit> = two#
|
||||
@Ann() val x: <implicit> = component1(<destruct>#)
|
||||
@Ann() val y: <implicit> = component2(<destruct>#)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
val p = 0
|
||||
fun foo() = 1
|
||||
|
||||
class Wrapper(val v: IntArray)
|
||||
|
||||
fun test(a: IntArray, w: Wrapper) = a[0] + a[p] + a[foo()] + w.v[0]
|
||||
@@ -0,0 +1,16 @@
|
||||
FILE: arrayAccess.kt
|
||||
public? final? property p(val): <implicit> = Int(0)
|
||||
public? get(): <implicit>
|
||||
public? final? function foo(): <implicit> {
|
||||
return@@@foo Int(1)
|
||||
}
|
||||
public? final? class Wrapper {
|
||||
public? constructor(v: IntArray): super<kotlin.Any>()
|
||||
|
||||
public? final? property v(val): IntArray
|
||||
public? get(): IntArray
|
||||
|
||||
}
|
||||
public? final? function test(a: IntArray, w: Wrapper): <implicit> {
|
||||
return@@@test plus#(plus#(plus#(a#[Int(0)], a#[p#]), a#[foo#()]), w#.v#[Int(0)])
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fun test() {
|
||||
val x = intArrayOf(1, 2, 3)
|
||||
x[1] = 0
|
||||
}
|
||||
|
||||
fun foo() = 1
|
||||
|
||||
fun test2() {
|
||||
intArrayOf(1, 2, 3)[foo()] = 1
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
FILE: arrayAssignment.kt
|
||||
public? final? function test(): kotlin.Unit {
|
||||
val x: <implicit> = intArrayOf#(Int(1), Int(2), Int(3))
|
||||
x#[Int(1)] = Int(0)
|
||||
}
|
||||
public? final? function foo(): <implicit> {
|
||||
return@@@foo Int(1)
|
||||
}
|
||||
public? final? function test2(): kotlin.Unit {
|
||||
val <array-set>: <implicit> = intArrayOf#(Int(1), Int(2), Int(3))
|
||||
<array-set>#[foo#()] = Int(1)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
fun foo(a: Int, b: Int) = if (a > b) a else b
|
||||
|
||||
fun bar(a: Double, b: Double): Double {
|
||||
if (a > b) {
|
||||
println(a)
|
||||
return a
|
||||
} else {
|
||||
println(b)
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
fun baz(a: Long, b: Long): Long {
|
||||
when {
|
||||
a > b -> {
|
||||
println(a)
|
||||
return a
|
||||
}
|
||||
else -> return b
|
||||
}
|
||||
}
|
||||
|
||||
fun grade(g: Int): String {
|
||||
return when (g) {
|
||||
6, 7 -> "Outstanding"
|
||||
5 -> "Excellent"
|
||||
4 -> "Good"
|
||||
3 -> "Mediocre"
|
||||
in 1..2 -> "Fail"
|
||||
is Number -> "Number"
|
||||
else -> "Unknown"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
FILE: branches.kt
|
||||
public? final? function foo(a: Int, b: Int): <implicit> {
|
||||
return@@@foo when () {
|
||||
>(a#, b#) -> {
|
||||
a#
|
||||
}
|
||||
else -> {
|
||||
b#
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public? final? function bar(a: Double, b: Double): Double {
|
||||
when () {
|
||||
>(a#, b#) -> {
|
||||
println#(a#)
|
||||
return@@@bar a#
|
||||
}
|
||||
else -> {
|
||||
println#(b#)
|
||||
return@@@bar b#
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public? final? function baz(a: Long, b: Long): Long {
|
||||
when () {
|
||||
>(a#, b#) -> {
|
||||
println#(a#)
|
||||
return@@@baz a#
|
||||
}
|
||||
else -> {
|
||||
return@@@baz b#
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public? final? function grade(g: Int): String {
|
||||
return@@@grade when (g#) {
|
||||
||(==($subj$, Int(6)), ==($subj$, Int(7))) -> {
|
||||
String(Outstanding)
|
||||
}
|
||||
==($subj$, Int(5)) -> {
|
||||
String(Excellent)
|
||||
}
|
||||
==($subj$, Int(4)) -> {
|
||||
String(Good)
|
||||
}
|
||||
==($subj$, Int(3)) -> {
|
||||
String(Mediocre)
|
||||
}
|
||||
in($subj$, rangeTo#(Int(1), Int(2))) -> {
|
||||
String(Fail)
|
||||
}
|
||||
is/Number($subj$) -> {
|
||||
String(Number)
|
||||
}
|
||||
else -> {
|
||||
String(Unknown)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
class A {
|
||||
fun foo() {}
|
||||
val bar = 0
|
||||
}
|
||||
|
||||
fun A.qux() {}
|
||||
|
||||
fun baz() {}
|
||||
|
||||
val test1 = A()::foo
|
||||
|
||||
val test2 = A()::bar
|
||||
|
||||
val test3 = A()::qux
|
||||
|
||||
val test4 = A::foo
|
||||
|
||||
val test5 = A::bar
|
||||
|
||||
val test6 = A::qux
|
||||
|
||||
val test7 = ::baz
|
||||
@@ -0,0 +1,29 @@
|
||||
FILE: callableReferences.kt
|
||||
public? final? class A {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
public? final? function foo(): kotlin.Unit {
|
||||
}
|
||||
|
||||
public? final? property bar(val): <implicit> = Int(0)
|
||||
public? get(): <implicit>
|
||||
|
||||
}
|
||||
public? final? function qux A.(): kotlin.Unit {
|
||||
}
|
||||
public? final? function baz(): kotlin.Unit {
|
||||
}
|
||||
public? final? property test1(val): <implicit> = A#()::foo#
|
||||
public? get(): <implicit>
|
||||
public? final? property test2(val): <implicit> = A#()::bar#
|
||||
public? get(): <implicit>
|
||||
public? final? property test3(val): <implicit> = A#()::qux#
|
||||
public? get(): <implicit>
|
||||
public? final? property test4(val): <implicit> = A#::foo#
|
||||
public? get(): <implicit>
|
||||
public? final? property test5(val): <implicit> = A#::bar#
|
||||
public? get(): <implicit>
|
||||
public? final? property test6(val): <implicit> = A#::qux#
|
||||
public? get(): <implicit>
|
||||
public? final? property test7(val): <implicit> = ::baz#
|
||||
public? get(): <implicit>
|
||||
@@ -0,0 +1,24 @@
|
||||
infix fun distance(x: Int, y: Int) = x + y
|
||||
|
||||
fun test(): Int = 3 distance 4
|
||||
|
||||
fun testRegular(): Int = distance(3, 4)
|
||||
|
||||
class My(var x: Int) {
|
||||
operator fun invoke() = x
|
||||
|
||||
fun foo() {}
|
||||
|
||||
fun copy() = My(x)
|
||||
}
|
||||
|
||||
fun testInvoke(): Int = My(13)()
|
||||
|
||||
fun testQualified(first: My, second: My?) {
|
||||
println(first.x)
|
||||
println(second?.x)
|
||||
first.foo()
|
||||
second?.foo()
|
||||
first.copy().foo()
|
||||
first.x = 42
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
FILE: calls.kt
|
||||
public? final? infix function distance(x: Int, y: Int): <implicit> {
|
||||
return@@@distance plus#(x#, y#)
|
||||
}
|
||||
public? final? function test(): Int {
|
||||
return@@@test distance#(Int(3), Int(4))
|
||||
}
|
||||
public? final? function testRegular(): Int {
|
||||
return@@@testRegular distance#(Int(3), Int(4))
|
||||
}
|
||||
public? final? class My {
|
||||
public? constructor(x: Int): super<kotlin.Any>()
|
||||
|
||||
public? final? property x(var): Int
|
||||
public? get(): Int
|
||||
public? set(value: Int): kotlin.Unit
|
||||
|
||||
public? final? operator function invoke(): <implicit> {
|
||||
return@@@invoke x#
|
||||
}
|
||||
|
||||
public? final? function foo(): kotlin.Unit {
|
||||
}
|
||||
|
||||
public? final? function copy(): <implicit> {
|
||||
return@@@copy My#(x#)
|
||||
}
|
||||
|
||||
}
|
||||
public? final? function testInvoke(): Int {
|
||||
return@@@testInvoke invoke#(My#(Int(13)))
|
||||
}
|
||||
public? final? function testQualified(first: My, second: My?): kotlin.Unit {
|
||||
println#(first#.x#)
|
||||
println#(second#?.x#)
|
||||
first#.foo#()
|
||||
second#?.foo#()
|
||||
first#.copy#().foo#()
|
||||
first#.x# = Int(42)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//WITH_RUNTIME
|
||||
package test
|
||||
|
||||
class A
|
||||
|
||||
fun test() {
|
||||
A::class
|
||||
test.A::class
|
||||
A()::class
|
||||
|
||||
A::class.java
|
||||
test.A::class.java
|
||||
A()::class.java
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
FILE: classReference.kt
|
||||
public? final? class A {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
}
|
||||
public? final? function test(): kotlin.Unit {
|
||||
<getClass>(A#)
|
||||
<getClass>(test#.A#)
|
||||
<getClass>(A#())
|
||||
<getClass>(A#).java#
|
||||
<getClass>(test#.A#).java#
|
||||
<getClass>(A#()).java#
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
annotation class Ann1(val arr: IntArray)
|
||||
|
||||
annotation class Ann2(val arr: DoubleArray)
|
||||
|
||||
annotation class Ann3(val arr: Array<String>)
|
||||
|
||||
@Ann1([])
|
||||
@Ann2([])
|
||||
@Ann3([])
|
||||
class Zero
|
||||
|
||||
@Ann1([1, 2])
|
||||
class First
|
||||
|
||||
@Ann2([3.14])
|
||||
class Second
|
||||
|
||||
@Ann3(["Alpha", "Omega"])
|
||||
class Third
|
||||
@@ -0,0 +1,38 @@
|
||||
FILE: collectionLiterals.kt
|
||||
public? final? annotation class Ann1 {
|
||||
public? constructor(arr: IntArray): super<kotlin.Any>()
|
||||
|
||||
public? final? property arr(val): IntArray
|
||||
public? get(): IntArray
|
||||
|
||||
}
|
||||
public? final? annotation class Ann2 {
|
||||
public? constructor(arr: DoubleArray): super<kotlin.Any>()
|
||||
|
||||
public? final? property arr(val): DoubleArray
|
||||
public? get(): DoubleArray
|
||||
|
||||
}
|
||||
public? final? annotation class Ann3 {
|
||||
public? constructor(arr: Array<String>): super<kotlin.Any>()
|
||||
|
||||
public? final? property arr(val): Array<String>
|
||||
public? get(): Array<String>
|
||||
|
||||
}
|
||||
@Ann1(<implicitArrayOf>()) @Ann2(<implicitArrayOf>()) @Ann3(<implicitArrayOf>()) public? final? class Zero {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
}
|
||||
@Ann1(<implicitArrayOf>(Int(1), Int(2))) public? final? class First {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
}
|
||||
@Ann2(<implicitArrayOf>(Double(3.14))) public? final? class Second {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
}
|
||||
@Ann3(<implicitArrayOf>(String(Alpha), String(Omega))) public? final? class Third {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
data class Some(val first: Int, val second: Double, val third: String)
|
||||
|
||||
fun foo(some: Some) {
|
||||
var (x, y, z: String) = some
|
||||
|
||||
x++
|
||||
y *= 2.0
|
||||
z = ""
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
FILE: destructuring.kt
|
||||
public? final? data class Some {
|
||||
public? constructor(first: Int, second: Double, third: String): super<kotlin.Any>()
|
||||
|
||||
public? final? property first(val): Int
|
||||
public? get(): Int
|
||||
|
||||
public? final? property second(val): Double
|
||||
public? get(): Double
|
||||
|
||||
public? final? property third(val): String
|
||||
public? get(): String
|
||||
|
||||
}
|
||||
public? final? function foo(some: Some): kotlin.Unit {
|
||||
val <destruct>: <implicit> = some#
|
||||
var x: <implicit> = component1(<destruct>#)
|
||||
var y: <implicit> = component2(<destruct>#)
|
||||
var z: String = component3(<destruct>#)
|
||||
val <unary>: <implicit> = x#
|
||||
x# = inc#(<unary>#)
|
||||
<unary>#
|
||||
y# *= Double(2.0)
|
||||
z# = String()
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
fun foo() {
|
||||
for (i in 1..10) {
|
||||
println(i)
|
||||
}
|
||||
}
|
||||
|
||||
fun bar(list: List<String>) {
|
||||
for (element in list.subList(0, 10)) {
|
||||
println(element)
|
||||
}
|
||||
for (element in list.subList(10, 20)) println(element)
|
||||
}
|
||||
|
||||
data class Some(val x: Int, val y: Int)
|
||||
|
||||
fun baz(set: Set<Some>) {
|
||||
for ((x, y) in set) {
|
||||
println("x = $x y = $y")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
FILE: for.kt
|
||||
public? final? function foo(): kotlin.Unit {
|
||||
val <range>: <implicit> = rangeTo#(Int(1), Int(10))
|
||||
val <iterator>: <implicit> = <range>#.iterator#()
|
||||
while(<iterator>#.hasNext#()) {
|
||||
val i: <implicit> = <iterator>#.next#()
|
||||
println#(i#)
|
||||
}
|
||||
|
||||
}
|
||||
public? final? function bar(list: List<String>): kotlin.Unit {
|
||||
val <range>: <implicit> = list#.subList#(Int(0), Int(10))
|
||||
val <iterator>: <implicit> = <range>#.iterator#()
|
||||
while(<iterator>#.hasNext#()) {
|
||||
val element: <implicit> = <iterator>#.next#()
|
||||
println#(element#)
|
||||
}
|
||||
|
||||
val <range>: <implicit> = list#.subList#(Int(10), Int(20))
|
||||
val <iterator>: <implicit> = <range>#.iterator#()
|
||||
while(<iterator>#.hasNext#()) {
|
||||
val element: <implicit> = <iterator>#.next#()
|
||||
println#(element#)
|
||||
}
|
||||
|
||||
}
|
||||
public? final? data class Some {
|
||||
public? constructor(x: Int, y: Int): super<kotlin.Any>()
|
||||
|
||||
public? final? property x(val): Int
|
||||
public? get(): Int
|
||||
|
||||
public? final? property y(val): Int
|
||||
public? get(): Int
|
||||
|
||||
}
|
||||
public? final? function baz(set: Set<Some>): kotlin.Unit {
|
||||
val <range>: <implicit> = set#
|
||||
val <iterator>: <implicit> = <range>#.iterator#()
|
||||
while(<iterator>#.hasNext#()) {
|
||||
val <destruct>: <implicit> = <iterator>#.next#()
|
||||
val x: <implicit> = component1(<destruct>#)
|
||||
val y: <implicit> = component2(<destruct>#)
|
||||
println#(plus#(String(x = ), x#, String( y = ), y#))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fun <T> nullableValue(): T? = null
|
||||
|
||||
fun test() {
|
||||
val n = nullableValue<Int>()
|
||||
val x = nullableValue<Double>()
|
||||
val s = nullableValue<String>()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
FILE: genericCalls.kt
|
||||
<T> public? final? function nullableValue(): T? {
|
||||
return@@@nullableValue Null(null)
|
||||
}
|
||||
public? final? function test(): kotlin.Unit {
|
||||
val n: <implicit> = nullableValue#<Int>()
|
||||
val x: <implicit> = nullableValue#<Double>()
|
||||
val s: <implicit> = nullableValue#<String>()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class WithInit(x: Int) {
|
||||
val x: Int
|
||||
|
||||
init {
|
||||
this.x = x
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
FILE: init.kt
|
||||
public? final? class WithInit {
|
||||
public? constructor(x: Int): super<kotlin.Any>()
|
||||
|
||||
public? final? property x(val): Int
|
||||
public? get(): Int
|
||||
|
||||
init {
|
||||
this#.x# = x#
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
data class Tuple(val x: Int, val y: Int)
|
||||
|
||||
inline fun use(f: (Tuple) -> Int) = f(Tuple(1, 2))
|
||||
|
||||
fun foo(): Int {
|
||||
val l1 = { t: Tuple ->
|
||||
val x = t.x
|
||||
val y = t.y
|
||||
x + y
|
||||
}
|
||||
use { (x, y) -> x + y }
|
||||
|
||||
return use {
|
||||
if (it.x == 0) return@foo 0
|
||||
return@use it.y
|
||||
}
|
||||
}
|
||||
|
||||
fun bar(): Int {
|
||||
return use lambda@{
|
||||
if (it.x == 0) return@bar 0
|
||||
return@lambda it.y
|
||||
}
|
||||
}
|
||||
|
||||
fun test(list: List<Int>) {
|
||||
val map = mutableMapOf<Int, String>()
|
||||
list.forEach { map.getOrPut(it, { mutableListOf() }) += "" }
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
FILE: lambda.kt
|
||||
public? final? data class Tuple {
|
||||
public? constructor(x: Int, y: Int): super<kotlin.Any>()
|
||||
|
||||
public? final? property x(val): Int
|
||||
public? get(): Int
|
||||
|
||||
public? final? property y(val): Int
|
||||
public? get(): Int
|
||||
|
||||
}
|
||||
public? final? inline function use(f: ( (Tuple) -> Int )): <implicit> {
|
||||
return@@@use f#(Tuple#(Int(1), Int(2)))
|
||||
}
|
||||
public? final? function foo(): Int {
|
||||
val l1: <implicit> = function <implicit>.<anonymous>(t: Tuple): <implicit> {
|
||||
return {
|
||||
val x: <implicit> = t#.x#
|
||||
val y: <implicit> = t#.y#
|
||||
plus#(x#, y#)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
use#(use@function <implicit>.<anonymous>(<destruct>: <implicit>): <implicit> {
|
||||
return {
|
||||
val x: <implicit> = component1(<destruct>#)
|
||||
val y: <implicit> = component2(<destruct>#)
|
||||
plus#(x#, y#)
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
return@@@foo use#(use@function <implicit>.<anonymous>(): <implicit> {
|
||||
return {
|
||||
when () {
|
||||
==(it#.x#, Int(0)) -> {
|
||||
return@@@foo Int(0)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
||||
return@@@use it#.y#
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
public? final? function bar(): Int {
|
||||
return@@@bar use#(lambda@function <implicit>.<anonymous>(): <implicit> {
|
||||
return {
|
||||
when () {
|
||||
==(it#.x#, Int(0)) -> {
|
||||
return@@@bar Int(0)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
||||
return@@@lambda it#.y#
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
public? final? function test(list: List<Int>): kotlin.Unit {
|
||||
val map: <implicit> = mutableMapOf#<Int, String>()
|
||||
list#.forEach#(forEach@function <implicit>.<anonymous>(): <implicit> {
|
||||
return {
|
||||
val <complex-set>: <implicit> = map#.getOrPut#(it#, getOrPut@function <implicit>.<anonymous>(): <implicit> {
|
||||
return {
|
||||
mutableListOf#()
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
<complex-set># += String()
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
fun withLocals(p: Int): Int {
|
||||
class Local(val pp: Int) {
|
||||
fun diff() = pp - p
|
||||
}
|
||||
|
||||
val x = Local(42).diff()
|
||||
|
||||
fun sum(y: Int, z: Int, f: (Int, Int) -> Int): Int {
|
||||
return x + f(y + z)
|
||||
}
|
||||
|
||||
val code = (object : Any() {
|
||||
fun foo() = hashCode()
|
||||
}).foo()
|
||||
|
||||
return sum(code, Local(1).diff(), fun(x: Int, y: Int) = x + y)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
FILE: locals.kt
|
||||
public? final? function withLocals(p: Int): Int {
|
||||
public? final? class Local {
|
||||
public? constructor(pp: Int): super<kotlin.Any>()
|
||||
|
||||
public? final? property pp(val): Int
|
||||
public? get(): Int
|
||||
|
||||
public? final? function diff(): <implicit> {
|
||||
return@@@diff minus#(pp#, p#)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val x: <implicit> = Local#(Int(42)).diff#()
|
||||
public? final? function sum(y: Int, z: Int, f: ( (Int, Int) -> Int )): Int {
|
||||
return@@@sum plus#(x#, f#(plus#(y#, z#)))
|
||||
}
|
||||
|
||||
val code: <implicit> = object : Any {
|
||||
public? constructor(): super<Any>()
|
||||
|
||||
public? final? function foo(): <implicit> {
|
||||
return@@@foo hashCode#()
|
||||
}
|
||||
|
||||
}
|
||||
.foo#()
|
||||
return@@@withLocals sum#(code#, Local#(Int(1)).diff#(), function <anonymous>(x: Int, y: Int): <implicit> {
|
||||
return plus#(x#, y#)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fun simple() {
|
||||
var x = 10
|
||||
x += 20
|
||||
x -= 5
|
||||
x /= 5
|
||||
x *= 10
|
||||
}
|
||||
|
||||
fun List<String>.modify() {
|
||||
this += "Alpha"
|
||||
this += "Omega"
|
||||
}
|
||||
|
||||
fun Any.modify() {
|
||||
(this as List<Int>) += 42
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
FILE: modifications.kt
|
||||
public? final? function simple(): kotlin.Unit {
|
||||
var x: <implicit> = Int(10)
|
||||
x# += Int(20)
|
||||
x# -= Int(5)
|
||||
x# /= Int(5)
|
||||
x# *= Int(10)
|
||||
}
|
||||
public? final? function modify List<String>.(): kotlin.Unit {
|
||||
this# += String(Alpha)
|
||||
this# += String(Omega)
|
||||
}
|
||||
public? final? function modify Any.(): kotlin.Unit {
|
||||
val <complex-set>: <implicit> = as/List<Int>(this#)
|
||||
<complex-set># += Int(42)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun orFourtyTwo(arg: Int?) = arg ?: 42
|
||||
|
||||
fun bang(arg: Int?) = arg!!
|
||||
@@ -0,0 +1,23 @@
|
||||
FILE: nullability.kt
|
||||
public? final? function orFourtyTwo(arg: Int?): <implicit> {
|
||||
return@@@orFourtyTwo when (val <elvis>: <implicit> = arg#) {
|
||||
!=($subj$, Null(null)) -> {
|
||||
<elvis>#
|
||||
}
|
||||
else -> {
|
||||
Int(42)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public? final? function bang(arg: Int?): <implicit> {
|
||||
return@@@bang when (val <bangbang>: <implicit> = arg#) {
|
||||
!=($subj$, Null(null)) -> {
|
||||
<bangbang>#
|
||||
}
|
||||
else -> {
|
||||
throw KotlinNullPointerException#()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo() {
|
||||
return
|
||||
}
|
||||
|
||||
fun bar(): String {
|
||||
return "Hello"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
FILE: simpleReturns.kt
|
||||
public? final? function foo(): kotlin.Unit {
|
||||
return@@@foo Unit
|
||||
}
|
||||
public? final? function bar(): String {
|
||||
return@@@bar String(Hello)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
interface A {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
interface B {
|
||||
fun foo() {}
|
||||
fun bar() {}
|
||||
}
|
||||
|
||||
class C : A, B {
|
||||
override fun bar() {
|
||||
super.bar()
|
||||
}
|
||||
|
||||
override fun foo() {
|
||||
super<A>.foo()
|
||||
super<B>.foo()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
FILE: super.kt
|
||||
public? final? interface A {
|
||||
public? final? function foo(): kotlin.Unit {
|
||||
}
|
||||
|
||||
}
|
||||
public? final? interface B {
|
||||
public? final? function foo(): kotlin.Unit {
|
||||
}
|
||||
|
||||
public? final? function bar(): kotlin.Unit {
|
||||
}
|
||||
|
||||
}
|
||||
public? final? class C : A, B {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
public? open? override function bar(): kotlin.Unit {
|
||||
super<<implicit>>.bar#()
|
||||
}
|
||||
|
||||
public? open? override function foo(): kotlin.Unit {
|
||||
super<A>.foo#()
|
||||
super<B>.foo#()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
class Some {
|
||||
fun foo(): Int = 1
|
||||
|
||||
fun bar(): Int {
|
||||
return this.foo()
|
||||
}
|
||||
|
||||
val instance: Some
|
||||
get() = this@Some
|
||||
|
||||
fun String.extension(): Int {
|
||||
return this@Some.bar() + this.length
|
||||
}
|
||||
}
|
||||
|
||||
fun Some.extension() = this.bar()
|
||||
|
||||
fun test(some: Some): Int {
|
||||
return with(some) {
|
||||
this.foo() + this@with.extension()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
FILE: these.kt
|
||||
public? final? class Some {
|
||||
public? constructor(): super<kotlin.Any>()
|
||||
|
||||
public? final? function foo(): Int {
|
||||
return@@@foo Int(1)
|
||||
}
|
||||
|
||||
public? final? function bar(): Int {
|
||||
return@@@bar this#.foo#()
|
||||
}
|
||||
|
||||
public? final? property instance(val): Some
|
||||
public? get(): Some {
|
||||
return this@Some
|
||||
}
|
||||
|
||||
public? final? function extension String.(): Int {
|
||||
return@@@extension plus#(this@Some.bar#(), this#.length#)
|
||||
}
|
||||
|
||||
}
|
||||
public? final? function extension Some.(): <implicit> {
|
||||
return@@@extension this#.bar#()
|
||||
}
|
||||
public? final? function test(some: Some): Int {
|
||||
return@@@test with#(some#, with@function <implicit>.<anonymous>(): <implicit> {
|
||||
return {
|
||||
plus#(this#.foo#(), this@with.extension#())
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fun some() {
|
||||
try {
|
||||
throw KotlinNullPointerException()
|
||||
} catch (e: RuntimeException) {
|
||||
println("Runtime exception")
|
||||
} catch (e: Exception) {
|
||||
println("Some exception")
|
||||
} finally {
|
||||
println("finally")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
FILE: try.kt
|
||||
public? final? function some(): kotlin.Unit {
|
||||
try {
|
||||
throw KotlinNullPointerException#()
|
||||
}
|
||||
catch (e: RuntimeException) {
|
||||
println#(String(Runtime exception))
|
||||
}
|
||||
catch (e: Exception) {
|
||||
println#(String(Some exception))
|
||||
}
|
||||
finally {
|
||||
println#(String(finally))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
interface IThing
|
||||
|
||||
fun test1(x: Any) = x is IThing
|
||||
fun test2(x: Any) = x !is IThing
|
||||
fun test3(x: Any) = x as IThing
|
||||
fun test4(x: Any) = x as? IThing
|
||||
@@ -0,0 +1,15 @@
|
||||
FILE: typeOperators.kt
|
||||
public? final? interface IThing {
|
||||
}
|
||||
public? final? function test1(x: Any): <implicit> {
|
||||
return@@@test1 is/IThing(x#)
|
||||
}
|
||||
public? final? function test2(x: Any): <implicit> {
|
||||
return@@@test2 !is/IThing(x#)
|
||||
}
|
||||
public? final? function test3(x: Any): <implicit> {
|
||||
return@@@test3 as/IThing(x#)
|
||||
}
|
||||
public? final? function test4(x: Any): <implicit> {
|
||||
return@@@test4 as?/IThing(x#)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
fun test() {
|
||||
var x = 0
|
||||
val x1 = x++
|
||||
val x2 = ++x
|
||||
val x3 = --x
|
||||
val x4 = x--
|
||||
if (!(x == 0)) {
|
||||
println("000")
|
||||
}
|
||||
}
|
||||
|
||||
class X(val i: Int)
|
||||
|
||||
fun test2(x: X) {
|
||||
val x1 = x.i++
|
||||
val x2 = ++x.i
|
||||
}
|
||||
|
||||
fun test3(arr: Array<Int>) {
|
||||
val x1 = arr[0]++
|
||||
val x2 = ++arr[1]
|
||||
}
|
||||
|
||||
class Y(val arr: Array<Int>)
|
||||
|
||||
fun test4(y: Y) {
|
||||
val x1 = y.arr[0]++
|
||||
val x2 = ++y.arr[1]
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
FILE: unary.kt
|
||||
public? final? function test(): kotlin.Unit {
|
||||
var x: <implicit> = Int(0)
|
||||
val x1: <implicit> = {
|
||||
val <unary>: <implicit> = x#
|
||||
x# = inc#(<unary>#)
|
||||
<unary>#
|
||||
}
|
||||
|
||||
val x2: <implicit> = {
|
||||
val <unary>: <implicit> = x#
|
||||
x# = inc#(<unary>#)
|
||||
x#
|
||||
}
|
||||
|
||||
val x3: <implicit> = {
|
||||
val <unary>: <implicit> = x#
|
||||
x# = dec#(<unary>#)
|
||||
x#
|
||||
}
|
||||
|
||||
val x4: <implicit> = {
|
||||
val <unary>: <implicit> = x#
|
||||
x# = dec#(<unary>#)
|
||||
<unary>#
|
||||
}
|
||||
|
||||
when () {
|
||||
not#(==(x#, Int(0))) -> {
|
||||
println#(String(000))
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public? final? class X {
|
||||
public? constructor(i: Int): super<kotlin.Any>()
|
||||
|
||||
public? final? property i(val): Int
|
||||
public? get(): Int
|
||||
|
||||
}
|
||||
public? final? function test2(x: X): kotlin.Unit {
|
||||
val x1: <implicit> = {
|
||||
val <unary>: <implicit> = x#.i#
|
||||
x#.i# = inc#(<unary>#)
|
||||
<unary>#
|
||||
}
|
||||
|
||||
val x2: <implicit> = {
|
||||
val <unary>: <implicit> = x#.i#
|
||||
val <unary-result>: <implicit> = inc#(<unary>#)
|
||||
x#.i# = <unary-result>#
|
||||
<unary-result>#
|
||||
}
|
||||
|
||||
}
|
||||
public? final? function test3(arr: Array<Int>): kotlin.Unit {
|
||||
val x1: <implicit> = {
|
||||
val <unary>: <implicit> = arr#[Int(0)]
|
||||
arr#[Int(0)] = inc#(<unary>#)
|
||||
<unary>#
|
||||
}
|
||||
|
||||
val x2: <implicit> = {
|
||||
val <unary>: <implicit> = arr#[Int(1)]
|
||||
val <unary-result>: <implicit> = inc#(<unary>#)
|
||||
arr#[Int(1)] = <unary-result>#
|
||||
<unary-result>#
|
||||
}
|
||||
|
||||
}
|
||||
public? final? class Y {
|
||||
public? constructor(arr: Array<Int>): super<kotlin.Any>()
|
||||
|
||||
public? final? property arr(val): Array<Int>
|
||||
public? get(): Array<Int>
|
||||
|
||||
}
|
||||
public? final? function test4(y: Y): kotlin.Unit {
|
||||
val x1: <implicit> = {
|
||||
val <unary>: <implicit> = y#.arr#[Int(0)]
|
||||
val <array-set>: <implicit> = y#.arr#
|
||||
<array-set>#[Int(0)] = inc#(<unary>#)
|
||||
<unary>#
|
||||
}
|
||||
|
||||
val x2: <implicit> = {
|
||||
val <unary>: <implicit> = y#.arr#[Int(1)]
|
||||
val <unary-result>: <implicit> = inc#(<unary>#)
|
||||
val <array-set>: <implicit> = y#.arr#
|
||||
<array-set>#[Int(1)] = <unary-result>#
|
||||
<unary-result>#
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fun foo() {
|
||||
val x = 1
|
||||
var y = x + 1
|
||||
val z = y * 2
|
||||
y = y + z
|
||||
val w = y - x
|
||||
return w
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
FILE: variables.kt
|
||||
public? final? function foo(): kotlin.Unit {
|
||||
val x: <implicit> = Int(1)
|
||||
var y: <implicit> = plus#(x#, Int(1))
|
||||
val z: <implicit> = times#(y#, Int(2))
|
||||
y# = plus#(y#, z#)
|
||||
val w: <implicit> = minus#(y#, x#)
|
||||
return@@@foo w#
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
fun foo(limit: Int) {
|
||||
var k = 0
|
||||
some@ while (k < limit) {
|
||||
k++
|
||||
println(k)
|
||||
while (k == 13) {
|
||||
k++
|
||||
if (k < limit) break@some
|
||||
if (k > limit) continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun bar(limit: Int) {
|
||||
var k = limit
|
||||
do {
|
||||
k--
|
||||
println(k)
|
||||
} while (k >= 0)
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
FILE: while.kt
|
||||
public? final? function foo(limit: Int): kotlin.Unit {
|
||||
var k: <implicit> = Int(0)
|
||||
some@while(<(k#, limit#)) {
|
||||
val <unary>: <implicit> = k#
|
||||
k# = inc#(<unary>#)
|
||||
<unary>#
|
||||
println#(k#)
|
||||
while(==(k#, Int(13))) {
|
||||
val <unary>: <implicit> = k#
|
||||
k# = inc#(<unary>#)
|
||||
<unary>#
|
||||
when () {
|
||||
<(k#, limit#) -> {
|
||||
break@@@[<(k#, limit#)]
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
>(k#, limit#) -> {
|
||||
continue@@@[==(k#, Int(13))]
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public? final? function bar(limit: Int): kotlin.Unit {
|
||||
var k: <implicit> = limit#
|
||||
do {
|
||||
val <unary>: <implicit> = k#
|
||||
k# = dec#(<unary>#)
|
||||
<unary>#
|
||||
println#(k#)
|
||||
}
|
||||
while(>=(k#, Int(0)))
|
||||
}
|
||||
+3
-3
@@ -58,7 +58,7 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
|
||||
protected fun doRawFirTest(filePath: String) {
|
||||
val file = createKtFile(filePath)
|
||||
val firFile = file.toFirFile()
|
||||
val firFile = file.toFirFile(stubMode = false)
|
||||
val firFileDump = StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
|
||||
val expectedPath = filePath.replace(".kt", ".txt")
|
||||
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
|
||||
@@ -71,8 +71,8 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
}
|
||||
}
|
||||
|
||||
protected fun KtFile.toFirFile(): FirFile =
|
||||
RawFirBuilder(object : FirSessionBase() {}).buildFirFile(this)
|
||||
protected fun KtFile.toFirFile(stubMode: Boolean): FirFile =
|
||||
RawFirBuilder(object : FirSessionBase() {}, stubMode).buildFirFile(this)
|
||||
|
||||
private fun FirElement.traverseChildren(result: MutableSet<FirElement> = hashSetOf()): MutableSet<FirElement> {
|
||||
if (!result.add(this)) {
|
||||
|
||||
Generated
+138
@@ -130,5 +130,143 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
|
||||
public void testTypeParameters() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("where.kt")
|
||||
public void testWhere() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/where.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/psi2fir/testData/rawBuilder/expressions")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Expressions extends AbstractRawFirBuilderTestCase {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doRawFirTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInExpressions() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/psi2fir/testData/rawBuilder/expressions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotated.kt")
|
||||
public void testAnnotated() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/annotated.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("arrayAccess.kt")
|
||||
public void testArrayAccess() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("arrayAssignment.kt")
|
||||
public void testArrayAssignment() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAssignment.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("branches.kt")
|
||||
public void testBranches() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/branches.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("callableReferences.kt")
|
||||
public void testCallableReferences() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/callableReferences.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("calls.kt")
|
||||
public void testCalls() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/calls.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classReference.kt")
|
||||
public void testClassReference() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/classReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("collectionLiterals.kt")
|
||||
public void testCollectionLiterals() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("destructuring.kt")
|
||||
public void testDestructuring() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/destructuring.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("for.kt")
|
||||
public void testFor() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/for.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericCalls.kt")
|
||||
public void testGenericCalls() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/genericCalls.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("init.kt")
|
||||
public void testInit() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/init.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambda.kt")
|
||||
public void testLambda() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("locals.kt")
|
||||
public void testLocals() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/locals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("modifications.kt")
|
||||
public void testModifications() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/modifications.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullability.kt")
|
||||
public void testNullability() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/nullability.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleReturns.kt")
|
||||
public void testSimpleReturns() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/simpleReturns.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("super.kt")
|
||||
public void testSuper() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/super.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("these.kt")
|
||||
public void testThese() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/these.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("try.kt")
|
||||
public void testTry() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/try.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeOperators.kt")
|
||||
public void testTypeOperators() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/typeOperators.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unary.kt")
|
||||
public void testUnary() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/unary.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variables.kt")
|
||||
public void testVariables() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/variables.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("while.kt")
|
||||
public void testWhile() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/while.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+100
-5
@@ -6,8 +6,19 @@
|
||||
package org.jetbrains.kotlin.fir.builder
|
||||
|
||||
import com.intellij.testFramework.TestDataPath
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAccess
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
|
||||
import org.junit.runner.RunWith
|
||||
import java.io.File
|
||||
@@ -17,11 +28,19 @@ import kotlin.system.measureNanoTime
|
||||
@RunWith(JUnit3RunnerWithInners::class)
|
||||
class RawFirBuilderTotalKotlinTestCase : AbstractRawFirBuilderTestCase() {
|
||||
|
||||
fun testTotalKotlin() {
|
||||
private fun testTotalKotlinWithGivenMode(stubMode: Boolean) {
|
||||
val root = File(testDataPath)
|
||||
var counter = 0
|
||||
var time = 0L
|
||||
var totalLength = 0
|
||||
var expressionStubs = 0
|
||||
var errorExpressions = 0
|
||||
var normalExpressions = 0
|
||||
var normalStatements = 0
|
||||
var errorDeclarations = 0
|
||||
var normalDeclarations = 0
|
||||
var errorReferences = 0
|
||||
var normalReferences = 0
|
||||
println("BASE PATH: $testDataPath")
|
||||
for (file in root.walkTopDown()) {
|
||||
if (file.isDirectory) continue
|
||||
@@ -31,12 +50,66 @@ class RawFirBuilderTotalKotlinTestCase : AbstractRawFirBuilderTestCase() {
|
||||
val ktFile = createKtFile(file.toRelativeString(root))
|
||||
var firFile: FirFile? = null
|
||||
time += measureNanoTime {
|
||||
firFile = ktFile.toFirFile()
|
||||
firFile = ktFile.toFirFile(stubMode)
|
||||
}
|
||||
totalLength += StringBuilder().also { FirRenderer(it).visitFile(firFile!!) }.length
|
||||
counter++
|
||||
firFile?.accept(object : FirVisitorVoid() {
|
||||
override fun visitElement(element: FirElement) {
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
|
||||
override fun visitErrorExpression(errorExpression: FirErrorExpression) {
|
||||
errorExpressions++
|
||||
println(errorExpression.render())
|
||||
errorExpression.psi?.let { println(it) }
|
||||
}
|
||||
|
||||
override fun visitAccess(access: FirAccess) {
|
||||
val calleeReference = access.calleeReference
|
||||
if (calleeReference is FirErrorNamedReference) {
|
||||
errorReferences++
|
||||
println(calleeReference.errorReason)
|
||||
} else {
|
||||
normalReferences++
|
||||
}
|
||||
super.visitAccess(access)
|
||||
}
|
||||
|
||||
override fun visitExpression(expression: FirExpression) {
|
||||
when (expression) {
|
||||
is FirExpressionStub -> {
|
||||
expressionStubs++
|
||||
if (!stubMode) {
|
||||
println(expression.psi?.text)
|
||||
}
|
||||
}
|
||||
else -> normalExpressions++
|
||||
}
|
||||
expression.acceptChildren(this)
|
||||
}
|
||||
|
||||
override fun visitStatement(statement: FirStatement) {
|
||||
normalStatements++
|
||||
statement.acceptChildren(this)
|
||||
}
|
||||
|
||||
override fun visitErrorDeclaration(errorDeclaration: FirErrorDeclaration) {
|
||||
errorDeclarations++
|
||||
println(errorDeclaration.render())
|
||||
errorDeclaration.psi?.let { println(it) }
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: FirDeclaration) {
|
||||
normalDeclarations++
|
||||
declaration.acceptChildren(this)
|
||||
}
|
||||
})
|
||||
|
||||
} catch (e: Exception) {
|
||||
println("TIME PER FILE: ${(time / counter) * 1e-6} ms, COUNTER: $counter")
|
||||
if (counter > 0) {
|
||||
println("TIME PER FILE: ${(time / counter) * 1e-6} ms, COUNTER: $counter")
|
||||
}
|
||||
println("EXCEPTION in: " + file.toRelativeString(root))
|
||||
throw e
|
||||
}
|
||||
@@ -44,6 +117,28 @@ class RawFirBuilderTotalKotlinTestCase : AbstractRawFirBuilderTestCase() {
|
||||
println("SUCCESS!")
|
||||
println("TOTAL LENGTH: $totalLength")
|
||||
println("TIME PER FILE: ${(time / counter) * 1e-6} ms, COUNTER: $counter")
|
||||
println("EXPRESSION STUBS: $expressionStubs")
|
||||
println("ERROR EXPRESSIONS: $errorExpressions")
|
||||
println("NORMAL EXPRESSIONS: $normalExpressions")
|
||||
println("NORMAL STATEMENTS: $normalStatements")
|
||||
println("ERROR DECLARATIONS: $errorDeclarations")
|
||||
println("NORMAL DECLARATIONS: $normalDeclarations")
|
||||
println("ERROR REFERENCES: $errorReferences")
|
||||
println("NORMAL REFERENCES: $normalReferences")
|
||||
if (!stubMode) {
|
||||
assertEquals(0, expressionStubs)
|
||||
}
|
||||
assertEquals(0, errorExpressions)
|
||||
assertEquals(0, errorDeclarations)
|
||||
assertEquals(0, errorReferences)
|
||||
}
|
||||
|
||||
fun testTotalKotlinWithExpressionTrees() {
|
||||
testTotalKotlinWithGivenMode(stubMode = false)
|
||||
}
|
||||
|
||||
fun testTotalKotlinWithDeclarationsOnly() {
|
||||
testTotalKotlinWithGivenMode(stubMode = true)
|
||||
}
|
||||
|
||||
fun testVisitConsistency() {
|
||||
@@ -53,7 +148,7 @@ class RawFirBuilderTotalKotlinTestCase : AbstractRawFirBuilderTestCase() {
|
||||
if (file.path.contains("testData") || file.path.contains("resources")) continue
|
||||
if (file.extension != "kt") continue
|
||||
val ktFile = createKtFile(file.toRelativeString(root))
|
||||
val firFile = ktFile.toFirFile()
|
||||
val firFile = ktFile.toFirFile(stubMode = false)
|
||||
try {
|
||||
firFile.checkChildren()
|
||||
} catch (e: Throwable) {
|
||||
@@ -70,7 +165,7 @@ class RawFirBuilderTotalKotlinTestCase : AbstractRawFirBuilderTestCase() {
|
||||
if (file.path.contains("testData") || file.path.contains("resources")) continue
|
||||
if (file.extension != "kt") continue
|
||||
val ktFile = createKtFile(file.toRelativeString(root))
|
||||
val firFile = ktFile.toFirFile()
|
||||
val firFile = ktFile.toFirFile(stubMode = false)
|
||||
try {
|
||||
firFile.checkTransformedChildren()
|
||||
} catch (e: Throwable) {
|
||||
|
||||
@@ -44,14 +44,14 @@ class FirProviderImpl(val session: FirSession) : FirProvider {
|
||||
|
||||
var containerFqName: FqName = FqName.ROOT
|
||||
|
||||
override fun visitClass(klass: FirClass) {
|
||||
val fqName = containerFqName.child(klass.name)
|
||||
override fun visitRegularClass(regularClass: FirRegularClass) {
|
||||
val fqName = containerFqName.child(regularClass.name)
|
||||
val classId = ClassId(packageName, fqName, false)
|
||||
classifierMap[classId] = klass
|
||||
classifierMap[classId] = regularClass
|
||||
classifierContainerFileMap[classId] = file
|
||||
|
||||
containerFqName = fqName
|
||||
klass.acceptChildren(this)
|
||||
regularClass.acceptChildren(this)
|
||||
containerFqName = fqName.parent()
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -24,7 +24,7 @@ class FirStatusResolveTransformer : FirTransformer<Nothing?>() {
|
||||
|
||||
private val declarationsWithStatuses = mutableListOf<FirDeclaration>()
|
||||
|
||||
private val classes = mutableListOf<FirClass>()
|
||||
private val classes = mutableListOf<FirRegularClass>()
|
||||
|
||||
private fun FirDeclaration.resolveVisibility(): Visibility {
|
||||
if (this is FirConstructor) {
|
||||
@@ -39,7 +39,7 @@ class FirStatusResolveTransformer : FirTransformer<Nothing?>() {
|
||||
private fun FirDeclaration.resolveModality(): Modality {
|
||||
return when (this) {
|
||||
is FirEnumEntry -> Modality.FINAL
|
||||
is FirClass -> if (classKind == ClassKind.INTERFACE) Modality.ABSTRACT else Modality.FINAL
|
||||
is FirRegularClass -> if (classKind == ClassKind.INTERFACE) Modality.ABSTRACT else Modality.FINAL
|
||||
is FirCallableMember -> {
|
||||
val containingClass = classes.lastOrNull()
|
||||
when {
|
||||
@@ -94,7 +94,7 @@ class FirStatusResolveTransformer : FirTransformer<Nothing?>() {
|
||||
}
|
||||
|
||||
private inline fun storeClass(
|
||||
klass: FirClass,
|
||||
klass: FirRegularClass,
|
||||
computeResult: () -> CompositeTransformResult<FirDeclaration>
|
||||
): CompositeTransformResult<FirDeclaration> {
|
||||
classes += klass
|
||||
@@ -103,9 +103,9 @@ class FirStatusResolveTransformer : FirTransformer<Nothing?>() {
|
||||
return result
|
||||
}
|
||||
|
||||
override fun transformClass(klass: FirClass, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
return storeClass(klass) {
|
||||
super.transformClass(klass, data)
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
return storeClass(regularClass) {
|
||||
super.transformRegularClass(regularClass, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -50,7 +50,7 @@ open class FirTypeResolveTransformer(
|
||||
return super.transformFile(file, data)
|
||||
}
|
||||
|
||||
private fun lookupSuperTypes(klass: FirClass): List<ConeClassLikeType> {
|
||||
private fun lookupSuperTypes(klass: FirRegularClass): List<ConeClassLikeType> {
|
||||
return mutableListOf<ConeClassLikeType>().also { klass.symbol.collectSuperTypes(it) }
|
||||
}
|
||||
|
||||
@@ -63,28 +63,28 @@ open class FirTypeResolveTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformClass(klass: FirClass, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
return withScopeCleanup {
|
||||
klass.withTypeParametersScope {
|
||||
resolveSuperTypesAndExpansions(klass)
|
||||
regularClass.withTypeParametersScope {
|
||||
resolveSuperTypesAndExpansions(regularClass)
|
||||
|
||||
val firProvider = FirProvider.getInstance(klass.session)
|
||||
val classId = klass.symbol.classId
|
||||
val firProvider = FirProvider.getInstance(regularClass.session)
|
||||
val classId = regularClass.symbol.classId
|
||||
scope.scopes += FirNestedClassifierScope(classId, firProvider)
|
||||
val companionObjects = klass.declarations.filterIsInstance<FirClass>().filter { it.isCompanion }
|
||||
val companionObjects = regularClass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
|
||||
for (companionObject in companionObjects) {
|
||||
scope.scopes += FirNestedClassifierScope(companionObject.symbol.classId, firProvider)
|
||||
}
|
||||
|
||||
lookupSuperTypes(klass).mapTo(scope.scopes) {
|
||||
lookupSuperTypes(regularClass).mapTo(scope.scopes) {
|
||||
val symbol = it.symbol
|
||||
if (symbol is FirBasedSymbol<*>) {
|
||||
FirNestedClassifierScope(symbol.classId, FirProvider.getInstance(symbol.fir.session))
|
||||
} else {
|
||||
FirNestedClassifierScope(symbol.classId, FirSymbolProvider.getInstance(klass.session))
|
||||
FirNestedClassifierScope(symbol.classId, FirSymbolProvider.getInstance(regularClass.session))
|
||||
}
|
||||
}
|
||||
super.transformClass(klass, data)
|
||||
super.transformRegularClass(regularClass, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ FILE: lists.kt
|
||||
|
||||
}
|
||||
public final function convert R|kotlin/collections/List<kotlin/String>|.(): R|MyStringList| {
|
||||
STUB
|
||||
return@@@convert STUB
|
||||
}
|
||||
public final function ret(l: R|kotlin/collections/MutableList<kotlin/String>|): R|MyMutableStringList| {
|
||||
STUB
|
||||
return@@@ret STUB
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,5 +11,5 @@ FILE: derivedClass.kt
|
||||
|
||||
}
|
||||
<T : R|kotlin/Any|> public final function create(x: R|T|): R|Derived<T>| {
|
||||
STUB
|
||||
return@@@create STUB
|
||||
}
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ FILE: enum.kt
|
||||
public constructor(): super<R|SomeEnum|>()
|
||||
|
||||
public final override function check(y: R|Some|): R|kotlin/Boolean| {
|
||||
STUB
|
||||
return@@@check STUB
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,7 +28,7 @@ FILE: enum.kt
|
||||
public constructor(): super<R|SomeEnum|>()
|
||||
|
||||
public final override function check(y: R|Some|): R|kotlin/Boolean| {
|
||||
STUB
|
||||
return@@@check STUB
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ FILE: enums.kt
|
||||
public constructor(): super<R|Planet|>()
|
||||
|
||||
public final override function sayHello(): R|kotlin/Unit| {
|
||||
return@@@sayHello STUB
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +40,7 @@ FILE: enums.kt
|
||||
public constructor(): super<R|Planet|>()
|
||||
|
||||
public final override function sayHello(): R|kotlin/Unit| {
|
||||
return@@@sayHello STUB
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,6 +49,7 @@ FILE: enums.kt
|
||||
public constructor(): super<R|Planet|>()
|
||||
|
||||
public final override function sayHello(): R|kotlin/Unit| {
|
||||
return@@@sayHello STUB
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ FILE: noPrimaryConstructor.kt
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public constructor(x: R|kotlin/String|): super<R|kotlin/Any|>() {
|
||||
return STUB
|
||||
}
|
||||
|
||||
public constructor(): this<R|NoPrimary|>()
|
||||
|
||||
@@ -13,13 +13,15 @@ FILE: simpleClass.kt
|
||||
private get(): R|error: Not supported: FirImplicitTypeImpl|
|
||||
|
||||
public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
|
||||
return@@@foo STUB
|
||||
}
|
||||
|
||||
public final override property bar(var): R|kotlin/Boolean|
|
||||
public get(): R|kotlin/Boolean| {
|
||||
STUB
|
||||
return STUB
|
||||
}
|
||||
public set(value: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
return STUB
|
||||
}
|
||||
|
||||
public final lateinit property fau(var): R|kotlin/Double|
|
||||
|
||||
@@ -15,11 +15,11 @@ FILE: typeParameters.kt
|
||||
public constructor(): super<R|AbstractList<kotlin/Int>|>()
|
||||
|
||||
public final override function get(index: R|kotlin/Int|): R|kotlin/Int| {
|
||||
STUB
|
||||
return@@@get STUB
|
||||
}
|
||||
|
||||
public final override function concat(other: R|List<kotlin/Int>|): R|List<kotlin/Int>| {
|
||||
STUB
|
||||
return@@@concat STUB
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,11 +1,12 @@
|
||||
FILE: functionTypes.kt
|
||||
<T> public final function simpleRun(f: R|(T) -> kotlin/Unit|): R|kotlin/Unit| {
|
||||
STUB
|
||||
return@@@simpleRun STUB
|
||||
}
|
||||
<T, R> public final function simpleMap R|kotlin/collections/List<T>|.(f: R|(T) -> R|): R|R| {
|
||||
return@@@simpleMap STUB
|
||||
}
|
||||
<T> public final function simpleWith(t: R|T|, f: R|T.() -> kotlin/Unit|): R|kotlin/Unit| {
|
||||
STUB
|
||||
return@@@simpleWith STUB
|
||||
}
|
||||
<T, R> public abstract interface KMutableProperty1 : R|KProperty1<T, R>|, R|KMutableProperty<R>| {
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ FILE: genericFunctions.kt
|
||||
public abstract interface Any {
|
||||
}
|
||||
<reified T : R|Any|> public final inline function safeAs R|Any|.(): R|T| {
|
||||
STUB
|
||||
return@@@safeAs STUB
|
||||
}
|
||||
public abstract class Summator {
|
||||
public constructor(): super<R|Any|>()
|
||||
|
||||
@@ -16,11 +16,12 @@ FILE: Annotations.kt
|
||||
public get(): R|kotlin/Char|
|
||||
|
||||
public final override function foo(arg: R|kotlin/Double|): R|kotlin/Unit| {
|
||||
return@@@foo STUB
|
||||
}
|
||||
|
||||
public final override property v(val): R|kotlin/String|
|
||||
@R|annotations/Simple|() public get(): R|kotlin/String| {
|
||||
STUB
|
||||
return STUB
|
||||
}
|
||||
|
||||
@R|annotations/WithString|(String(constructor)) public constructor(): this<R|test/Second|>()
|
||||
|
||||
+3
-1
@@ -13,13 +13,15 @@ FILE: simpleClass.kt
|
||||
private get(): R|error: Not supported: FirImplicitTypeImpl|
|
||||
|
||||
public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
|
||||
return@@@foo STUB
|
||||
}
|
||||
|
||||
public final override property bar(var): R|kotlin/Boolean|
|
||||
public get(): R|kotlin/Boolean| {
|
||||
STUB
|
||||
return STUB
|
||||
}
|
||||
public set(value: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
return STUB
|
||||
}
|
||||
|
||||
public final property fau(var): R|kotlin/Double|
|
||||
|
||||
@@ -3,4 +3,5 @@ FILE: concurrent.kt
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
@R|kotlin/jvm/Synchronized|() public final function foo(): R|kotlin/Unit| {
|
||||
return@@@foo STUB
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ FILE: functionX.kt
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public final override function invoke(p1: R|kotlin/Int|, p2: R|kotlin/String|): R|kotlin/Unit| {
|
||||
return@@@invoke STUB
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FILE: typeParameterInPropertyReceiver.kt
|
||||
<T : R|kotlin/Any|> public final property self R|T|.(val): R|T|
|
||||
public get(): R|T| {
|
||||
STUB
|
||||
return STUB
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ abstract class AbstractFirResolveTestCase : AbstractFirResolveWithSessionTestCas
|
||||
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
|
||||
val session = createSession(scope)
|
||||
|
||||
val builder = RawFirBuilder(session)
|
||||
val builder = RawFirBuilder(session, stubMode = true)
|
||||
|
||||
val transformer = FirTotalResolveTransformer()
|
||||
return ktFiles.map {
|
||||
|
||||
@@ -65,7 +65,7 @@ class FirResolveTestTotalKotlin : AbstractFirResolveWithSessionTestCase() {
|
||||
|
||||
val scope = ProjectScope.getContentScope(project)
|
||||
val session = createSession(scope)
|
||||
val builder = RawFirBuilder(session)
|
||||
val builder = RawFirBuilder(session, stubMode = true)
|
||||
|
||||
val totalTransformer = FirTotalResolveTransformer()
|
||||
val firFiles = ktFiles.map {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
|
||||
abstract class FirAbstractElement(
|
||||
final override val session: FirSession,
|
||||
final override val psi: PsiElement?
|
||||
) : FirElement
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
abstract class FirAbstractTarget<E : FirTargetElement>(
|
||||
override val labelName: String?
|
||||
) : FirTarget<E> {
|
||||
override lateinit var labeledElement: E
|
||||
|
||||
override fun bind(element: E) {
|
||||
labeledElement = element
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
|
||||
class FirFunctionTarget(
|
||||
labelName: String?
|
||||
) : FirAbstractTarget<FirFunction>(labelName)
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
interface FirLabel : FirElement {
|
||||
val name: String
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitLabel(this, data)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
// Target element which may have label
|
||||
interface FirLabeledElement : FirTargetElement {
|
||||
val label: FirLabel? get() = null
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitLabeledElement(this, data)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
label?.accept(visitor, data)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.expressions.FirLoop
|
||||
|
||||
class FirLoopTarget(
|
||||
labelName: String?
|
||||
) : FirAbstractTarget<FirLoop>(labelName)
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
interface FirNamedReference : FirReference {
|
||||
val name: Name
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitNamedReference(this, data)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
interface FirReference : FirElement {
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitReference(this, data)
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
@@ -141,7 +142,7 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
if (memberDeclaration is FirCallableMember && memberDeclaration.isOverride) {
|
||||
print("override ")
|
||||
}
|
||||
if (memberDeclaration is FirClass) {
|
||||
if (memberDeclaration is FirRegularClass) {
|
||||
if (memberDeclaration.isInner) {
|
||||
print("inner ")
|
||||
}
|
||||
@@ -193,35 +194,62 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
override fun visitDeclaration(declaration: FirDeclaration) {
|
||||
print(
|
||||
when (declaration) {
|
||||
is FirClass -> declaration.classKind.name.toLowerCase().replace("_", " ")
|
||||
is FirRegularClass -> declaration.classKind.name.toLowerCase().replace("_", " ")
|
||||
is FirTypeAlias -> "typealias"
|
||||
is FirNamedFunction -> "function"
|
||||
is FirProperty -> "property"
|
||||
is FirVariable -> if (declaration.isVal) "val" else "var"
|
||||
else -> "unknown"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitEnumEntry(enumEntry: FirEnumEntry) {
|
||||
visitClass(enumEntry)
|
||||
visitRegularClass(enumEntry)
|
||||
}
|
||||
|
||||
override fun visitClass(klass: FirClass) {
|
||||
visitMemberDeclaration(klass)
|
||||
if (klass.superTypes.isNotEmpty()) {
|
||||
print(" : ")
|
||||
klass.superTypes.renderSeparated()
|
||||
}
|
||||
private fun FirDeclarationContainer.renderDeclarations() {
|
||||
println(" {")
|
||||
pushIndent()
|
||||
for (declaration in klass.declarations) {
|
||||
declaration.accept(this)
|
||||
for (declaration in declarations) {
|
||||
declaration.accept(this@FirRenderer)
|
||||
println()
|
||||
}
|
||||
popIndent()
|
||||
println("}")
|
||||
}
|
||||
|
||||
override fun visitRegularClass(regularClass: FirRegularClass) {
|
||||
visitMemberDeclaration(regularClass)
|
||||
if (regularClass.superTypes.isNotEmpty()) {
|
||||
print(" : ")
|
||||
regularClass.superTypes.renderSeparated()
|
||||
}
|
||||
regularClass.renderDeclarations()
|
||||
}
|
||||
|
||||
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject) {
|
||||
anonymousObject.annotations.renderAnnotations()
|
||||
print("object : ")
|
||||
anonymousObject.superTypes.renderSeparated()
|
||||
anonymousObject.renderDeclarations()
|
||||
}
|
||||
|
||||
override fun visitVariable(variable: FirVariable) {
|
||||
variable.annotations.renderAnnotations()
|
||||
visitNamedDeclaration(variable)
|
||||
print(": ")
|
||||
variable.returnType.accept(this)
|
||||
variable.initializer?.let {
|
||||
print(" = ")
|
||||
it.accept(this)
|
||||
}
|
||||
variable.delegate?.let {
|
||||
print("by ")
|
||||
it.accept(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitProperty(property: FirProperty) {
|
||||
visitCallableMember(property)
|
||||
property.initializer?.let {
|
||||
@@ -276,6 +304,26 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
propertyAccessor.body?.accept(this)
|
||||
}
|
||||
|
||||
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction) {
|
||||
anonymousFunction.annotations.renderAnnotations()
|
||||
val label = anonymousFunction.label
|
||||
if (label != null) {
|
||||
print("${label.name}@")
|
||||
}
|
||||
print("function ")
|
||||
val receiverType = anonymousFunction.receiverType
|
||||
if (receiverType != null) {
|
||||
print(" ")
|
||||
receiverType.accept(this)
|
||||
print(".")
|
||||
}
|
||||
print("<anonymous>")
|
||||
anonymousFunction.valueParameters.renderParameters()
|
||||
print(": ")
|
||||
anonymousFunction.returnType.accept(this)
|
||||
anonymousFunction.body?.accept(this)
|
||||
}
|
||||
|
||||
override fun visitFunction(function: FirFunction) {
|
||||
function.valueParameters.renderParameters()
|
||||
visitDeclarationWithBody(function)
|
||||
@@ -291,10 +339,10 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
declarationWithBody.body?.accept(this)
|
||||
}
|
||||
|
||||
override fun visitBody(body: FirBody) {
|
||||
override fun visitBlock(block: FirBlock) {
|
||||
println(" {")
|
||||
pushIndent()
|
||||
for (statement in body.statements) {
|
||||
for (statement in block.statements) {
|
||||
statement.accept(this)
|
||||
println()
|
||||
}
|
||||
@@ -348,10 +396,6 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitVariable(variable: FirVariable) {
|
||||
visitDeclaration(variable)
|
||||
}
|
||||
|
||||
override fun visitImport(import: FirImport) {
|
||||
visitElement(import)
|
||||
}
|
||||
@@ -360,11 +404,128 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
visitElement(statement)
|
||||
}
|
||||
|
||||
override fun visitReturnExpression(returnExpression: FirReturnExpression) {
|
||||
returnExpression.annotations.renderAnnotations()
|
||||
print("return")
|
||||
val target = returnExpression.target
|
||||
val labeledElement = target.labeledElement
|
||||
if (labeledElement is FirNamedFunction) {
|
||||
print("@@@${labeledElement.name}")
|
||||
} else {
|
||||
val labelName = target.labelName
|
||||
if (labelName != null) {
|
||||
if (labeledElement is FirAnonymousFunction) {
|
||||
print("@@")
|
||||
}
|
||||
print("@$labelName")
|
||||
}
|
||||
}
|
||||
print(" ")
|
||||
returnExpression.result.accept(this)
|
||||
}
|
||||
|
||||
override fun visitWhenBranch(whenBranch: FirWhenBranch) {
|
||||
val condition = whenBranch.condition
|
||||
if (condition is FirElseIfTrueCondition) {
|
||||
print("else")
|
||||
} else {
|
||||
condition.accept(this)
|
||||
}
|
||||
print(" -> ")
|
||||
whenBranch.result.accept(this)
|
||||
}
|
||||
|
||||
override fun visitWhenExpression(whenExpression: FirWhenExpression) {
|
||||
whenExpression.annotations.renderAnnotations()
|
||||
print("when (")
|
||||
val subjectVariable = whenExpression.subjectVariable
|
||||
if (subjectVariable != null) {
|
||||
subjectVariable.accept(this)
|
||||
} else {
|
||||
whenExpression.subject?.accept(this)
|
||||
}
|
||||
println(") {")
|
||||
pushIndent()
|
||||
for (branch in whenExpression.branches) {
|
||||
branch.accept(this)
|
||||
}
|
||||
popIndent()
|
||||
println("}")
|
||||
}
|
||||
|
||||
override fun visitTryExpression(tryExpression: FirTryExpression) {
|
||||
tryExpression.annotations.renderAnnotations()
|
||||
print("try")
|
||||
tryExpression.tryBlock.accept(this)
|
||||
for (catchClause in tryExpression.catches) {
|
||||
print("catch (")
|
||||
catchClause.parameter.accept(this)
|
||||
print(")")
|
||||
catchClause.block.accept(this)
|
||||
}
|
||||
val finallyBlock = tryExpression.finallyBlock ?: return
|
||||
print("finally")
|
||||
finallyBlock.accept(this)
|
||||
}
|
||||
|
||||
override fun visitDoWhileLoop(doWhileLoop: FirDoWhileLoop) {
|
||||
val label = doWhileLoop.label
|
||||
if (label != null) {
|
||||
print("${label.name}@")
|
||||
}
|
||||
print("do")
|
||||
doWhileLoop.block.accept(this)
|
||||
print("while(")
|
||||
doWhileLoop.condition.accept(this)
|
||||
print(")")
|
||||
}
|
||||
|
||||
override fun visitWhileLoop(whileLoop: FirWhileLoop) {
|
||||
val label = whileLoop.label
|
||||
if (label != null) {
|
||||
print("${label.name}@")
|
||||
}
|
||||
print("while(")
|
||||
whileLoop.condition.accept(this)
|
||||
print(")")
|
||||
whileLoop.block.accept(this)
|
||||
}
|
||||
|
||||
private fun visitLoopJump(jump: FirJump<FirLoop>) {
|
||||
val target = jump.target
|
||||
val labeledElement = target.labeledElement
|
||||
print("@@@[")
|
||||
labeledElement.condition.accept(this)
|
||||
print("] ")
|
||||
}
|
||||
|
||||
override fun visitBreakExpression(breakExpression: FirBreakExpression) {
|
||||
breakExpression.annotations.renderAnnotations()
|
||||
print("break")
|
||||
visitLoopJump(breakExpression)
|
||||
}
|
||||
|
||||
override fun visitContinueExpression(continueExpression: FirContinueExpression) {
|
||||
continueExpression.annotations.renderAnnotations()
|
||||
print("continue")
|
||||
visitLoopJump(continueExpression)
|
||||
}
|
||||
|
||||
override fun visitExpression(expression: FirExpression) {
|
||||
print("STUB")
|
||||
expression.annotations.renderAnnotations()
|
||||
print(
|
||||
when (expression) {
|
||||
is FirExpressionStub -> "STUB"
|
||||
is FirUnitExpression -> "Unit"
|
||||
is FirWhenSubjectExpression -> "\$subj\$"
|
||||
is FirElseIfTrueCondition -> "else"
|
||||
else -> "??? ${expression.javaClass}"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun <T> visitConstExpression(constExpression: FirConstExpression<T>) {
|
||||
constExpression.annotations.renderAnnotations()
|
||||
print("${constExpression.kind}(${constExpression.value})")
|
||||
}
|
||||
|
||||
@@ -406,7 +567,7 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
}
|
||||
|
||||
override fun visitDelegatedType(delegatedType: FirDelegatedType) {
|
||||
delegatedType.accept(this)
|
||||
delegatedType.type.accept(this)
|
||||
print(" by ")
|
||||
delegatedType.delegate?.accept(this)
|
||||
}
|
||||
@@ -460,7 +621,7 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
val sb = StringBuilder()
|
||||
sb.append(symbol.classId.asString())
|
||||
if (typeArguments.isNotEmpty()) {
|
||||
sb.append(typeArguments.joinToString(prefix = "<", postfix = ">") { it ->
|
||||
sb.append(typeArguments.joinToString(prefix = "<", postfix = ">") {
|
||||
when (it) {
|
||||
StarProjection -> "*"
|
||||
is ConeKotlinTypeProjectionIn -> "in ${it.type.asString()}"
|
||||
@@ -530,4 +691,130 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
print("*")
|
||||
}
|
||||
|
||||
override fun visitNamedReference(namedReference: FirNamedReference) {
|
||||
print("${namedReference.name}#")
|
||||
}
|
||||
|
||||
override fun visitThisReference(thisReference: FirThisReference) {
|
||||
print("this")
|
||||
val labelName = thisReference.labelName
|
||||
if (labelName != null) {
|
||||
print("@$labelName")
|
||||
} else {
|
||||
print("#")
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitSuperReference(superReference: FirSuperReference) {
|
||||
print("super<")
|
||||
superReference.superType.accept(this)
|
||||
print(">")
|
||||
}
|
||||
|
||||
override fun visitAccess(access: FirAccess) {
|
||||
val explicitReceiver = access.explicitReceiver
|
||||
if (explicitReceiver != null) {
|
||||
explicitReceiver.accept(this)
|
||||
if (access.safe) {
|
||||
print("?.")
|
||||
} else {
|
||||
print(".")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess) {
|
||||
callableReferenceAccess.annotations.renderAnnotations()
|
||||
callableReferenceAccess.explicitReceiver?.accept(this)
|
||||
print("::")
|
||||
callableReferenceAccess.calleeReference.accept(this)
|
||||
}
|
||||
|
||||
override fun visitAccessExpression(accessExpression: FirAccessExpression) {
|
||||
accessExpression.annotations.renderAnnotations()
|
||||
visitAccess(accessExpression)
|
||||
accessExpression.calleeReference.accept(this)
|
||||
}
|
||||
|
||||
override fun visitAssignment(assignment: FirAssignment) {
|
||||
print(assignment.operation.operator)
|
||||
print(" ")
|
||||
assignment.value.accept(this)
|
||||
}
|
||||
|
||||
override fun visitPropertyAssignment(propertyAssignment: FirPropertyAssignment) {
|
||||
propertyAssignment.annotations.renderAnnotations()
|
||||
visitAccess(propertyAssignment)
|
||||
propertyAssignment.calleeReference.accept(this)
|
||||
print(" ")
|
||||
visitAssignment(propertyAssignment)
|
||||
}
|
||||
|
||||
override fun visitArraySetCall(arraySetCall: FirArraySetCall) {
|
||||
arraySetCall.annotations.renderAnnotations()
|
||||
visitAccess(arraySetCall)
|
||||
arraySetCall.calleeReference.accept(this)
|
||||
print("[")
|
||||
arraySetCall.arguments.renderSeparated()
|
||||
print("] ")
|
||||
visitAssignment(arraySetCall)
|
||||
}
|
||||
|
||||
override fun visitFunctionCall(functionCall: FirFunctionCall) {
|
||||
functionCall.annotations.renderAnnotations()
|
||||
visitAccess(functionCall)
|
||||
functionCall.calleeReference.accept(this)
|
||||
if (functionCall.typeArguments.isNotEmpty()) {
|
||||
print("<")
|
||||
functionCall.typeArguments.renderSeparated()
|
||||
print(">")
|
||||
}
|
||||
visitCall(functionCall)
|
||||
}
|
||||
|
||||
override fun visitOperatorCall(operatorCall: FirOperatorCall) {
|
||||
operatorCall.annotations.renderAnnotations()
|
||||
print(operatorCall.operation.operator)
|
||||
if (operatorCall is FirTypeOperatorCall) {
|
||||
print("/")
|
||||
operatorCall.type.accept(this)
|
||||
}
|
||||
visitCall(operatorCall)
|
||||
}
|
||||
|
||||
override fun visitArrayGetCall(arrayGetCall: FirArrayGetCall) {
|
||||
arrayGetCall.annotations.renderAnnotations()
|
||||
arrayGetCall.array.accept(this)
|
||||
print("[")
|
||||
arrayGetCall.arguments.renderSeparated()
|
||||
print("]")
|
||||
}
|
||||
|
||||
override fun visitComponentCall(componentCall: FirComponentCall) {
|
||||
componentCall.annotations.renderAnnotations()
|
||||
print("component${componentCall.componentIndex}")
|
||||
visitCall(componentCall)
|
||||
}
|
||||
|
||||
override fun visitGetClassCall(getClassCall: FirGetClassCall) {
|
||||
getClassCall.annotations.renderAnnotations()
|
||||
print("<getClass>")
|
||||
visitCall(getClassCall)
|
||||
}
|
||||
|
||||
override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall) {
|
||||
arrayOfCall.annotations.renderAnnotations()
|
||||
print("<implicitArrayOf>")
|
||||
visitCall(arrayOfCall)
|
||||
}
|
||||
|
||||
override fun visitThrowExpression(throwExpression: FirThrowExpression) {
|
||||
throwExpression.annotations.renderAnnotations()
|
||||
print("throw ")
|
||||
throwExpression.exception.accept(this)
|
||||
}
|
||||
|
||||
override fun visitErrorExpression(errorExpression: FirErrorExpression) {
|
||||
print("ERROR_EXPR(${errorExpression.reason})")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.types.FirType
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
interface FirSuperReference : FirReference {
|
||||
val superType: FirType
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitSuperReference(this, data)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
superType.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
// Reference to some label
|
||||
interface FirTarget<E : FirTargetElement> {
|
||||
val labelName: String?
|
||||
|
||||
val labeledElement: E
|
||||
|
||||
fun bind(element: E)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
// Any target of return / break / continue (some targets may have labels, some never have them)
|
||||
interface FirTargetElement : FirElement
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
interface FirThisReference : FirReference {
|
||||
val labelName: String?
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitThisReference(this, data)
|
||||
}
|
||||
@@ -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.declarations
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirLabeledElement
|
||||
import org.jetbrains.kotlin.fir.VisitedSupertype
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.types.FirType
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
interface FirAnonymousFunction : @VisitedSupertype FirFunction, FirExpression, FirTypedDeclaration, FirLabeledElement {
|
||||
val receiverType: FirType?
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitAnonymousFunction(this, data)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
super<FirTypedDeclaration>.acceptChildren(visitor, data)
|
||||
super<FirLabeledElement>.acceptChildren(visitor, data)
|
||||
receiverType?.accept(visitor, data)
|
||||
for (parameter in valueParameters) {
|
||||
parameter.accept(visitor, data)
|
||||
}
|
||||
body?.accept(visitor, data)
|
||||
// Don't call super<FirExpression>.acceptChildren (annotations are already processed)
|
||||
}
|
||||
}
|
||||
@@ -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.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.VisitedSupertype
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
interface FirAnonymousObject : @VisitedSupertype FirClass, FirExpression {
|
||||
override val classKind: ClassKind
|
||||
get() = ClassKind.OBJECT
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitAnonymousObject(this, data)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
super<FirClass>.acceptChildren(visitor, data)
|
||||
super<FirExpression>.acceptChildren(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -1,41 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* 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.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.BaseTransformedType
|
||||
import org.jetbrains.kotlin.fir.symbols.FirSymbolOwner
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.types.FirType
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
// May be all containers should be properties and not base classes
|
||||
// About descriptors: introduce something like FirDescriptor which is FirUnresolved at the beginning and FirSymbol(descriptor) at the end
|
||||
@BaseTransformedType
|
||||
interface FirClass : FirDeclarationContainer, FirMemberDeclaration, FirSymbolOwner<FirClass> {
|
||||
interface FirClass : FirDeclarationContainer, FirStatement, FirAnnotationContainer {
|
||||
// including delegated types
|
||||
val superTypes: List<FirType>
|
||||
|
||||
val classKind: ClassKind
|
||||
|
||||
val isInner: Boolean get() = status.isInner
|
||||
|
||||
val isCompanion: Boolean get() = status.isCompanion
|
||||
|
||||
val isData: Boolean get() = status.isData
|
||||
|
||||
val isInline: Boolean get() = status.isInline
|
||||
|
||||
override val symbol: FirClassSymbol
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitClass(this, data)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
super.acceptChildren(visitor, data)
|
||||
for (superType in superTypes) {
|
||||
superType.accept(visitor, data)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user