FIR IDE: render unresolved types as qualifiers for member generator

This commit is contained in:
Ilya Kirillov
2021-06-12 16:52:55 +02:00
committed by TeamCityServer
parent cf7870e376
commit 39e2df6916
8 changed files with 36 additions and 16 deletions
@@ -21,19 +21,26 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
class ConeUnresolvedReferenceError(val name: Name? = null) : ConeDiagnostic() { sealed class ConeUnresolvedError : ConeDiagnostic() {
abstract val qualifier: String?
}
class ConeUnresolvedReferenceError(val name: Name? = null) : ConeUnresolvedError() {
override val qualifier: String? get() = name?.asString()
override val reason: String get() = "Unresolved reference" + if (name != null) ": ${name.asString()}" else "" override val reason: String get() = "Unresolved reference" + if (name != null) ": ${name.asString()}" else ""
} }
class ConeUnresolvedSymbolError(val classId: ClassId) : ConeDiagnostic() { class ConeUnresolvedSymbolError(val classId: ClassId) : ConeUnresolvedError() {
override val qualifier: String get() = classId.asSingleFqName().asString()
override val reason: String get() = "Symbol not found for $classId" override val reason: String get() = "Symbol not found for $classId"
} }
class ConeUnresolvedQualifierError(val qualifier: String) : ConeDiagnostic() { class ConeUnresolvedQualifierError(override val qualifier: String) : ConeUnresolvedError() {
override val reason: String get() = "Symbol not found for $qualifier" override val reason: String get() = "Symbol not found for $qualifier"
} }
class ConeUnresolvedNameError(val name: Name) : ConeDiagnostic() { class ConeUnresolvedNameError(val name: Name) : ConeUnresolvedError() {
override val qualifier: String get() = name.asString()
override val reason: String get() = "Unresolved name: $name" override val reason: String get() = "Unresolved name: $name"
} }
@@ -307,6 +307,7 @@ internal abstract class KtGenerateMembersHandler : AbstractGenerateMembersHandle
typeRendererOptions = KtTypeRendererOptions( typeRendererOptions = KtTypeRendererOptions(
shortQualifiedNames = true, shortQualifiedNames = true,
renderFunctionType = true, renderFunctionType = true,
renderUnresolvedTypeAsResolved = true,
) )
) )
} }
@@ -24,6 +24,13 @@ data class KtTypeRendererOptions(
* @sample Function0<Int> returns () -> Int * @sample Function0<Int> returns () -> Int
*/ */
val renderFunctionType: Boolean = true, val renderFunctionType: Boolean = true,
/**
* When met type with unresolved qualifier, render it as it is resolved
* When `true` will render as `UnresolvedQualifier`
* When `false` will render as "ERROR_TYPE <symbol not found for UnresolvedQualifier>"
*/
val renderUnresolvedTypeAsResolved: Boolean = true
) { ) {
companion object { companion object {
val DEFAULT = KtTypeRendererOptions() val DEFAULT = KtTypeRendererOptions()
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.isInner import org.jetbrains.kotlin.fir.declarations.isInner
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedError
import org.jetbrains.kotlin.fir.resolve.inference.* import org.jetbrains.kotlin.fir.resolve.inference.*
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -18,7 +19,9 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.idea.asJava.applyIf import org.jetbrains.kotlin.idea.asJava.applyIf
import org.jetbrains.kotlin.idea.fir.low.level.api.api.collectDesignation import org.jetbrains.kotlin.idea.fir.low.level.api.api.collectDesignation
import org.jetbrains.kotlin.idea.frontend.api.components.KtTypeRendererOptions import org.jetbrains.kotlin.idea.frontend.api.components.KtTypeRendererOptions
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.renderer.render
internal class ConeTypeIdeRenderer( internal class ConeTypeIdeRenderer(
private val session: FirSession, private val session: FirSession,
@@ -48,7 +51,7 @@ internal class ConeTypeIdeRenderer(
when (type) { when (type) {
is ConeKotlinErrorType -> { is ConeKotlinErrorType -> {
appendError(type.diagnostic.reason) renderErrorType(type)
} }
//is Dynamic??? -> append("dynamic") //is Dynamic??? -> append("dynamic")
is ConeClassLikeType -> { is ConeClassLikeType -> {
@@ -83,6 +86,16 @@ internal class ConeTypeIdeRenderer(
} }
} }
private fun StringBuilder.renderErrorType(type: ConeKotlinErrorType) {
val diagnostic = type.diagnostic
if (options.renderUnresolvedTypeAsResolved && diagnostic is ConeUnresolvedError) {
val qualifierRendered = diagnostic.qualifier?.let { FqName(it).render() }.orEmpty()
append(qualifierRendered)
} else {
appendError(diagnostic.reason)
}
}
private fun StringBuilder.renderNullability(type: ConeKotlinType) { private fun StringBuilder.renderNullability(type: ConeKotlinType) {
if (type.nullability == ConeNullability.NULLABLE) { if (type.nullability == ConeNullability.NULLABLE) {
append("?") append("?")
@@ -85,6 +85,6 @@ internal class TypeCreatorTest : KotlinLightCodeInsightFixtureTestCase() {
companion object { companion object {
private val RENDERING_OPTIONS = KtTypeRendererOptions.SHORT_NAMES private val RENDERING_OPTIONS = KtTypeRendererOptions.SHORT_NAMES.copy(renderUnresolvedTypeAsResolved = false)
} }
} }
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// DISABLE-ERRORS // DISABLE-ERRORS
interface A<in TPipeline, out TBuilder : Any, TFeature : Any> { interface A<in TPipeline, out TBuilder : Any, TFeature : Any> {
fun install(pipeline: TPipeline, configure: TBuilder.() -> Unit): TFeature fun install(pipeline: TPipeline, configure: TBuilder.() -> Unit): TFeature
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// DISABLE-ERRORS // DISABLE-ERRORS
interface A<in TPipeline, out TBuilder : Any, TFeature : Any> { interface A<in TPipeline, out TBuilder : Any, TFeature : Any> {
fun install(pipeline: TPipeline, configure: TBuilder.() -> Unit): TFeature fun install(pipeline: TPipeline, configure: TBuilder.() -> Unit): TFeature
@@ -1,10 +0,0 @@
// DISABLE-ERRORS
interface A<in TPipeline, out TBuilder : Any, TFeature : Any> {
fun install(pipeline: TPipeline, configure: TBuilder.() -> Unit): TFeature
}
class X : A<String, UnresolvedType, Unit> {
override fun install(pipeline: String, configure: ERROR_TYPE.() -> Unit) {
<selection><caret>TODO("Not yet implemented")</selection>
}
}