From bcb27f212c12de7e207ea9395f6c068fc08a0704 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 10 Apr 2018 17:32:08 +0300 Subject: [PATCH] FIR: support resolve of implicit Unit types --- .../kotlin/fir/builder/RawFirBuilder.kt | 9 ++++++++- .../fir/resolve/impl/FirTypeResolverImpl.kt | 16 ++++++++++++++++ .../org/jetbrains/kotlin/fir/FirRenderer.kt | 3 ++- .../fir/types/impl/FirImplicitUnitType.kt | 19 +++++++++++++++++++ .../fir/rawBuilder/declarations/enums.txt | 8 ++++---- .../fir/rawBuilder/declarations/simpleFun.txt | 2 +- .../declarations/typeParameterVsNested.txt | 2 +- .../fir/resolve/multifile/Annotations.txt | 4 ++-- .../fir/resolve/stdlib/concurrent.txt | 2 +- .../testData/fir/resolve/stdlib/functionX.txt | 2 +- .../fir/resolve/typeParameterVsNested.txt | 2 +- 11 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitUnitType.kt diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 546455395ff..e4677067ece 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -36,6 +36,8 @@ import org.jetbrains.kotlin.types.Variance class RawFirBuilder(val session: FirSession) { + private val implicitUnitType = FirImplicitUnitType(session, null) + fun buildFirFile(file: KtFile): FirFile { return file.accept(Visitor(), Unit) as FirFile } @@ -356,6 +358,7 @@ class RawFirBuilder(val session: FirSession) { // TODO: what if name is not null but we're in expression position? return FirExpressionStub(session, function) } + val typeReference = function.typeReference val firFunction = FirMemberFunctionImpl( session, function, @@ -370,7 +373,11 @@ class RawFirBuilder(val session: FirSession) { function.hasModifier(KtTokens.TAILREC_KEYWORD), function.hasModifier(KtTokens.EXTERNAL_KEYWORD), function.receiverTypeReference.convertSafe(), - function.typeReference.toFirOrImplicitType(), + if (function.hasBlockBody()) { + typeReference?.toFirOrImplicitType() ?: implicitUnitType + } else { + typeReference.toFirOrImplicitType() + }, function.bodyExpression.toFirBody() ) function.extractAnnotationsTo(firFunction) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt index cfe3a500f7f..fa7a8ea0a05 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.fir.resolve.impl +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver import org.jetbrains.kotlin.fir.resolve.FirTypeResolver import org.jetbrains.kotlin.fir.scopes.FirPosition @@ -54,6 +56,8 @@ class FirTypeResolverImpl : FirTypeResolver { } } + private val implicitUnitTypeSymbols = mutableMapOf() + override fun resolveToSymbol( type: FirType, scope: FirScope, @@ -83,6 +87,15 @@ class FirTypeResolverImpl : FirTypeResolver { // TODO: Imports resolvedSymbol ?: qualifierResolver.resolveSymbol(type.qualifier) } + is FirImplicitUnitType -> implicitUnitTypeSymbols[type.session] ?: run { + var resolvedSymbol: ConeSymbol? = null + scope.processClassifiersByName(KotlinBuiltIns.FQ_NAMES.unit.shortName(), position) { + resolvedSymbol = (it as ConeClassLikeSymbol) + resolvedSymbol == null + } + implicitUnitTypeSymbols[type.session] = resolvedSymbol!! + resolvedSymbol + } else -> null } } @@ -112,6 +125,9 @@ class FirTypeResolverImpl : FirTypeResolver { type.returnType.coneTypeUnsafe() ) } + is FirImplicitUnitType -> { + resolveToSymbol(type, scope, position)!!.toConeKotlinType(emptyList())!! + } is FirDynamicType, is FirImplicitType, is FirDelegatedType -> { ConeKotlinErrorType("Not supported: ${type::class.simpleName}") } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index 06b89a752c7..f412e6affe4 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.ConeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitType import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.types.Variance @@ -410,7 +411,7 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() { } override fun visitImplicitType(implicitType: FirImplicitType) { - print("") + print(if (implicitType is FirImplicitUnitType) "kotlin.Unit" else "") } override fun visitTypeWithNullability(typeWithNullability: FirTypeWithNullability) { diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitUnitType.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitUnitType.kt new file mode 100644 index 00000000000..17a4a977094 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitUnitType.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2018 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.types.impl + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.types.FirImplicitType + +class FirImplicitUnitType( + override val session: FirSession, + override val psi: PsiElement? +) : FirImplicitType { + override val annotations: List + get() = emptyList() +} \ No newline at end of file diff --git a/compiler/testData/fir/rawBuilder/declarations/enums.txt b/compiler/testData/fir/rawBuilder/declarations/enums.txt index 13ea7074567..5c4d76bd40f 100644 --- a/compiler/testData/fir/rawBuilder/declarations/enums.txt +++ b/compiler/testData/fir/rawBuilder/declarations/enums.txt @@ -20,19 +20,19 @@ FILE: enums.kt public? get(): Double public? final enum entry MERCURY : Planet { - public? open? override function sayHello(): { + public? open? override function sayHello(): kotlin.Unit { } } public? final enum entry VENERA : Planet { - public? open? override function sayHello(): { + public? open? override function sayHello(): kotlin.Unit { } } public? final enum entry EARTH : Planet { - public? open? override function sayHello(): { + public? open? override function sayHello(): kotlin.Unit { } } @@ -40,7 +40,7 @@ FILE: enums.kt public? final? property g(val): Double = STUB public? get(): Double - public? abstract function sayHello(): + public? abstract function sayHello(): kotlin.Unit public? final companion object Companion { public? final? const property G(val): = STUB diff --git a/compiler/testData/fir/rawBuilder/declarations/simpleFun.txt b/compiler/testData/fir/rawBuilder/declarations/simpleFun.txt index 03b21587eef..e5f180a6f81 100644 --- a/compiler/testData/fir/rawBuilder/declarations/simpleFun.txt +++ b/compiler/testData/fir/rawBuilder/declarations/simpleFun.txt @@ -1,3 +1,3 @@ FILE: simpleFun.kt - public? final? function foo(): { + public? final? function foo(): kotlin.Unit { } diff --git a/compiler/testData/fir/rawBuilder/declarations/typeParameterVsNested.txt b/compiler/testData/fir/rawBuilder/declarations/typeParameterVsNested.txt index 2669f8216be..dd3c683f940 100644 --- a/compiler/testData/fir/rawBuilder/declarations/typeParameterVsNested.txt +++ b/compiler/testData/fir/rawBuilder/declarations/typeParameterVsNested.txt @@ -8,7 +8,7 @@ FILE: typeParameterVsNested.kt public? abstract property x(val): T public? get(): T - public? abstract function foo(arg: T): + public? abstract function foo(arg: T): kotlin.Unit public? abstract property y(val): My.T public? get(): My.T diff --git a/compiler/testData/fir/resolve/multifile/Annotations.txt b/compiler/testData/fir/resolve/multifile/Annotations.txt index 2d74f57a1d2..eca2b81f360 100644 --- a/compiler/testData/fir/resolve/multifile/Annotations.txt +++ b/compiler/testData/fir/resolve/multifile/Annotations.txt @@ -1,7 +1,7 @@ FILE: Annotations.kt @FILE:R|annotations/Simple|() @R|annotations/WithInt|(STUB) public? abstract class First { - @R|annotations/Simple|() public? abstract function foo(@R|annotations/WithString|(STUB) arg: @R|annotations/Simple|() R|kotlin/Double|): R|error: Not supported: FirImplicitTypeImpl| + @R|annotations/Simple|() public? abstract function foo(@R|annotations/WithString|(STUB) arg: @R|annotations/Simple|() R|kotlin/Double|): R|kotlin/Unit| @R|annotations/Complex|(STUB, STUB) public? abstract property v(val): R|kotlin/String| public? get(): R|kotlin/String| @@ -13,7 +13,7 @@ FILE: Annotations.kt public? final? property y(val): R|kotlin/Char| public? get(): R|kotlin/Char| - public? open? override function foo(arg: R|kotlin/Double|): R|error: Not supported: FirImplicitTypeImpl| { + public? open? override function foo(arg: R|kotlin/Double|): R|kotlin/Unit| { } public? open? override property v(val): R|kotlin/String| diff --git a/compiler/testData/fir/resolve/stdlib/concurrent.txt b/compiler/testData/fir/resolve/stdlib/concurrent.txt index e7d16bf38f5..1bebf1844c3 100644 --- a/compiler/testData/fir/resolve/stdlib/concurrent.txt +++ b/compiler/testData/fir/resolve/stdlib/concurrent.txt @@ -2,5 +2,5 @@ FILE: concurrent.kt @R|kotlin/jvm/Volatile|() public? final? property xx(var): R|kotlin/Int| = STUB public? get(): R|kotlin/Int| public? set(value: R|kotlin/Int|): R|kotlin/Unit| - @R|kotlin/jvm/Synchronized|() public? final? function foo(): R|error: Not supported: FirImplicitTypeImpl| { + @R|kotlin/jvm/Synchronized|() public? final? function foo(): R|kotlin/Unit| { } diff --git a/compiler/testData/fir/resolve/stdlib/functionX.txt b/compiler/testData/fir/resolve/stdlib/functionX.txt index f9dbfd91597..0a3ba057d98 100644 --- a/compiler/testData/fir/resolve/stdlib/functionX.txt +++ b/compiler/testData/fir/resolve/stdlib/functionX.txt @@ -4,7 +4,7 @@ FILE: functionX.kt public? final? property y(val): R|kotlin/Function1| = STUB public? get(): R|kotlin/Function1| public? final class MyFunction : R|kotlin/Function2| { - public? open? override function invoke(p1: R|kotlin/Int|, p2: R|kotlin/String|): R|error: Not supported: FirImplicitTypeImpl| { + public? open? override function invoke(p1: R|kotlin/Int|, p2: R|kotlin/String|): R|kotlin/Unit| { } } diff --git a/compiler/testData/fir/resolve/typeParameterVsNested.txt b/compiler/testData/fir/resolve/typeParameterVsNested.txt index 8d3451a9ad2..5b1489670aa 100644 --- a/compiler/testData/fir/resolve/typeParameterVsNested.txt +++ b/compiler/testData/fir/resolve/typeParameterVsNested.txt @@ -8,7 +8,7 @@ FILE: typeParameterVsNested.kt public? abstract property x(val): R|T| public? get(): R|T| - public? abstract function foo(arg: R|T|): R|error: Not supported: FirImplicitTypeImpl| + public? abstract function foo(arg: R|T|): R|kotlin/Unit| public? abstract property y(val): R|test/My.T| public? get(): R|test/My.T|