FIR: support WRONG_ANNOTATION_TARGET on expressions

This commit is contained in:
Mikhail Glukhikh
2021-05-13 16:12:02 +03:00
parent 92ab600081
commit d11092ae3c
23 changed files with 103 additions and 44 deletions
@@ -1,17 +1,17 @@
FILE: annotationUsedAsAnnotationArgument.kt FILE: annotationUsedAsAnnotationArgument.kt
public final annotation class Ann : R|kotlin/Annotation| { @R|kotlin/annotation/Target|(vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.EXPRESSION|)) @R|kotlin/annotation/Retention|(Q|kotlin/annotation/AnnotationRetention|.R|kotlin/annotation/AnnotationRetention.SOURCE|) public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|Ann| { public constructor(): R|Ann| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
} }
public final annotation class Ann2 : R|kotlin/Annotation| { @R|kotlin/annotation/Target|(vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.EXPRESSION|)) @R|kotlin/annotation/Retention|(Q|kotlin/annotation/AnnotationRetention|.R|kotlin/annotation/AnnotationRetention.SOURCE|) public final annotation class Ann2 : R|kotlin/Annotation| {
public constructor(): R|Ann2| { public constructor(): R|Ann2| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
} }
public final annotation class Ann3 : R|kotlin/Annotation| { @R|kotlin/annotation/Target|(vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.EXPRESSION|)) @R|kotlin/annotation/Retention|(Q|kotlin/annotation/AnnotationRetention|.R|kotlin/annotation/AnnotationRetention.SOURCE|) public final annotation class Ann3 : R|kotlin/Annotation| {
public constructor(arg: R|kotlin/Int|, s: R|kotlin/String|): R|Ann3| { public constructor(arg: R|kotlin/Int|, s: R|kotlin/String|): R|Ann3| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
@@ -1,7 +1,15 @@
// WITH_RUNTIME
@Target(AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
annotation class Ann annotation class Ann
@Target(AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
annotation class Ann2 annotation class Ann2
@Target(AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
annotation class Ann3(val arg: Int, val s: String) annotation class Ann3(val arg: Int, val s: String)
@Ann3( @Ann3(
@@ -1,5 +1,5 @@
FILE: annotations.kt FILE: annotations.kt
public final annotation class MyAnn : R|kotlin/Annotation| { @R|kotlin/annotation/Retention|(Q|kotlin/annotation/AnnotationRetention|.R|kotlin/annotation/AnnotationRetention.SOURCE|) @R|kotlin/annotation/Target|(vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.EXPRESSION|)) public final annotation class MyAnn : R|kotlin/Annotation| {
public constructor(): R|MyAnn| { public constructor(): R|MyAnn| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
@@ -1,3 +1,7 @@
// WITH_RUNTIME
@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.EXPRESSION)
annotation class MyAnn annotation class MyAnn
fun bar(x: Int) {} fun bar(x: Int) {}
@@ -173,6 +173,9 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val ANNOTATION_ON_SUPERCLASS by error<KtAnnotationEntry>() val ANNOTATION_ON_SUPERCLASS by error<KtAnnotationEntry>()
val RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION by error<PsiElement>() val RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION by error<PsiElement>()
val WRONG_ANNOTATION_TARGET by error<KtAnnotationEntry> {
parameter<String>("actualTarget")
}
} }
val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") { val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") {
@@ -179,6 +179,7 @@ object FirErrors {
val DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val ANNOTATION_ON_SUPERCLASS by error0<KtAnnotationEntry>() val ANNOTATION_ON_SUPERCLASS by error0<KtAnnotationEntry>()
val RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION by error0<PsiElement>() val RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION by error0<PsiElement>()
val WRONG_ANNOTATION_TARGET by error1<KtAnnotationEntry, String>()
// Exposed visibility // Exposed visibility
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME) val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
@@ -9,13 +9,11 @@ import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
import org.jetbrains.kotlin.fir.expressions.argumentMapping
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -30,12 +28,8 @@ fun FirAnnotationCall.getRetention(session: FirSession): AnnotationRetention {
fun FirRegularClass.getRetention(): AnnotationRetention { fun FirRegularClass.getRetention(): AnnotationRetention {
val retentionAnnotation = getRetentionAnnotation() ?: return AnnotationRetention.RUNTIME val retentionAnnotation = getRetentionAnnotation() ?: return AnnotationRetention.RUNTIME
val argumentMapping = retentionAnnotation.argumentMapping ?: return AnnotationRetention.RUNTIME val retentionArgument = retentionAnnotation.findSingleArgumentByName(RETENTION_PARAMETER_NAME) as? FirQualifiedAccessExpression
val retentionArgument = argumentMapping.keys.firstOrNull() as? FirQualifiedAccessExpression
?: return AnnotationRetention.RUNTIME ?: return AnnotationRetention.RUNTIME
if (argumentMapping[retentionArgument]?.name != RETENTION_PARAMETER_NAME) {
return AnnotationRetention.RUNTIME
}
val retentionName = (retentionArgument.calleeReference as? FirResolvedNamedReference)?.name?.asString() val retentionName = (retentionArgument.calleeReference as? FirResolvedNamedReference)?.name?.asString()
?: return AnnotationRetention.RUNTIME ?: return AnnotationRetention.RUNTIME
return AnnotationRetention.values().firstOrNull { it.name == retentionName } ?: AnnotationRetention.RUNTIME return AnnotationRetention.values().firstOrNull { it.name == retentionName } ?: AnnotationRetention.RUNTIME
@@ -54,19 +48,20 @@ private val defaultAnnotationTargets = listOf(
) )
fun FirAnnotationCall.getAllowedAnnotationTargets(session: FirSession): List<AnnotationTarget> { fun FirAnnotationCall.getAllowedAnnotationTargets(session: FirSession): List<AnnotationTarget> {
if (annotationTypeRef is FirErrorTypeRef) return AnnotationTarget.values().toList()
val annotationClass = (this.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.fir as? FirRegularClass val annotationClass = (this.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.fir as? FirRegularClass
return annotationClass?.getAllowedAnnotationTargets() ?: defaultAnnotationTargets return annotationClass?.getAllowedAnnotationTargets() ?: defaultAnnotationTargets
} }
fun FirRegularClass.getAllowedAnnotationTargets(): List<AnnotationTarget> { fun FirRegularClass.getAllowedAnnotationTargets(): List<AnnotationTarget> {
val targetAnnotation = getTargetAnnotation() ?: return defaultAnnotationTargets val targetAnnotation = getTargetAnnotation() ?: return defaultAnnotationTargets
val argumentMapping = targetAnnotation.argumentMapping ?: return defaultAnnotationTargets val arguments = when (val targetArgument = targetAnnotation.findSingleArgumentByName(TARGET_PARAMETER_NAME)) {
val targetArgument = argumentMapping.keys.firstOrNull() as? FirVarargArgumentsExpression is FirVarargArgumentsExpression -> targetArgument.arguments
?: return defaultAnnotationTargets is FirArrayOfCall -> targetArgument.arguments
if (argumentMapping[targetArgument]?.name != TARGET_PARAMETER_NAME) { else -> return defaultAnnotationTargets
return defaultAnnotationTargets
} }
return targetArgument.arguments.mapNotNull { argument ->
return arguments.mapNotNull { argument ->
val targetExpression = argument as? FirQualifiedAccessExpression val targetExpression = argument as? FirQualifiedAccessExpression
val targetName = (targetExpression?.calleeReference as? FirResolvedNamedReference)?.name?.asString() ?: return@mapNotNull null val targetName = (targetExpression?.calleeReference as? FirResolvedNamedReference)?.name?.asString() ?: return@mapNotNull null
AnnotationTarget.values().firstOrNull { target -> target.name == targetName } AnnotationTarget.values().firstOrNull { target -> target.name == targetName }
@@ -87,3 +82,13 @@ fun FirAnnotatedDeclaration.getAnnotationByFqName(fqName: FqName): FirAnnotation
} }
} }
fun FirAnnotationCall.findSingleArgumentByName(name: Name): FirExpression? {
val argumentMapping = argumentMapping
if (argumentMapping != null) {
return argumentMapping.keys.firstOrNull()?.takeIf { argumentMapping[it]?.name == name }
}
// NB: we have to consider both cases, because deserializer does not create argument mapping
val firstArgument = argumentList.arguments.firstOrNull() as? FirNamedArgumentExpression ?: return null
return firstArgument.takeIf { it.name == name }?.expression
}
@@ -5,19 +5,31 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getAllowedAnnotationTargets import org.jetbrains.kotlin.fir.analysis.checkers.getAllowedAnnotationTargets
import org.jetbrains.kotlin.fir.analysis.checkers.getRetention
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
object FirExpressionAnnotationChecker : FirBasicExpressionChecker() { object FirExpressionAnnotationChecker : FirBasicExpressionChecker() {
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
// Declarations are checked separately
// See KT-33658 about annotations on non-expression statements
if (expression is FirDeclaration ||
expression !is FirExpression ||
expression is FirBlock && expression.source?.kind == FirFakeSourceElementKind.DesugaredForLoop
) return
for (annotation in expression.annotations) { for (annotation in expression.annotations) {
withSuppressedDiagnostics(annotation, context) { withSuppressedDiagnostics(annotation, context) {
if (AnnotationTarget.EXPRESSION !in annotation.getAllowedAnnotationTargets(context.session)) {
reporter.reportOn(annotation.source, FirErrors.WRONG_ANNOTATION_TARGET, "expression", context)
}
} }
} }
} }
@@ -328,6 +328,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIANCE_ON_TYPE_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_ANNOTATION_PARAMETER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_ANNOTATION_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_OVERRIDDEN_BY_VAL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_OVERRIDDEN_BY_VAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_ANNOTATION_TARGET
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_GETTER_RETURN_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_GETTER_RETURN_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_INVOCATION_KIND import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_INVOCATION_KIND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TARGET import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TARGET
@@ -476,6 +477,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
"DeprecatedSinceKotlin annotation cannot be used outside 'kotlin' subpackages" "DeprecatedSinceKotlin annotation cannot be used outside 'kotlin' subpackages"
) )
map.put(ANNOTATION_ON_SUPERCLASS, "Annotations on superclass are meaningless") map.put(ANNOTATION_ON_SUPERCLASS, "Annotations on superclass are meaningless")
map.put(WRONG_ANNOTATION_TARGET, "This annotation is not applicable to target ''{0}''", TO_STRING);
// Exposed visibility group // # // Exposed visibility group // #
map.put( map.put(
+1 -1
View File
@@ -18,6 +18,6 @@ fun test() : Unit {
val s = "" as Any val s = "" as Any
("" as String?)?.length ("" as String?)?.length
(data@("" as String?))?.length (data@("" as String?))?.length
(@MustBeDocumented()( "" as String?))?.length (<!WRONG_ANNOTATION_TARGET!>@MustBeDocumented()<!>( "" as String?))?.length
Unit Unit
} }
@@ -33,8 +33,8 @@ fun foo(arg: Int) {
// Function expression too // Function expression too
val f = @FunAnn fun(): Int { return 42 } val f = @FunAnn fun(): Int { return 42 }
// But here, f and gav should be annotated instead // But here, f and gav should be annotated instead
bar(@FunAnn f) bar(<!WRONG_ANNOTATION_TARGET!>@FunAnn<!> f)
bar(@FunAnn ::gav) bar(<!WRONG_ANNOTATION_TARGET!>@FunAnn<!> ::gav)
// Function expression, ok // Function expression, ok
fast(f) fast(f)
} }
@@ -1,13 +0,0 @@
@Target(AnnotationTarget.FUNCTION)
annotation class FunAnn
@Target(AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
annotation class ExprAnn
fun foo(): Int {
var x = 5
@FunAnn ++x
@ExprAnn ++x
return x
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
@Target(AnnotationTarget.FUNCTION) @Target(AnnotationTarget.FUNCTION)
annotation class FunAnn annotation class FunAnn
@@ -18,4 +18,4 @@
return local return local
} }
@empty val z = @empty 0 @empty val z = <!WRONG_ANNOTATION_TARGET!>@empty<!> 0
@@ -4,10 +4,10 @@ annotation class base
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
annotation class special annotation class special
fun transform(i: Int, tr: (Int) -> Int): Int = @base @special tr(@special i) fun transform(i: Int, tr: (Int) -> Int): Int = <!WRONG_ANNOTATION_TARGET!>@base<!> @special tr(@special i)
@base @special fun foo(i: Int): Int { @base @special fun foo(i: Int): Int {
val j = @base @special i + 1 val j = <!WRONG_ANNOTATION_TARGET!>@base<!> @special i + 1
if (j == 1) return foo(@special @base 42) if (j == 1) return foo(@special <!WRONG_ANNOTATION_TARGET!>@base<!> 42)
return transform(@special j, @base @special { @special it * 2 }) return transform(@special j, @base @special { @special it * 2 })
} }
@@ -10,5 +10,5 @@ fun transform(i: Int, tr: (@special Int) -> Int): Int = @special tr(@special i)
fun foo(i: Int): Int { fun foo(i: Int): Int {
val j = @special i + 1 val j = @special i + 1
if (j == 1) return foo(@special 42) if (j == 1) return foo(@special 42)
return transform(@special j, @special { i: @base Int -> @base i * 2 }) return transform(@special j, @special { i: @base Int -> <!WRONG_ANNOTATION_TARGET!>@base<!> i * 2 })
} }
@@ -18,4 +18,4 @@
return local return local
} }
@incorrect val z = @incorrect 0 @incorrect val z = <!WRONG_ANNOTATION_TARGET!>@incorrect<!> 0
@@ -75,7 +75,7 @@ import test.AnnotationTargets.*
): @fieldann @parameter Int { ): @fieldann @parameter Int {
@local @base @multiple @fieldann val j = i + 1 @local @base @multiple @fieldann val j = i + 1
@base @multiple return j <!WRONG_ANNOTATION_TARGET!>@base<!> <!WRONG_ANNOTATION_TARGET!>@multiple<!> return j
} }
@base @method @konstructor constructor(): this(0) @base @method @konstructor constructor(): this(0)
@@ -0,0 +1,17 @@
/*
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
*
* SPEC VERSION: 0.1-313
* PRIMARY LINKS: expressions, when-expression -> paragraph 9 -> sentence 2
* expressions, when-expression -> paragraph 5 -> sentence 1
* expressions, when-expression -> paragraph 6 -> sentence 5
* annotations, annotation-targets -> paragraph 1 -> sentence 1
*/
fun foo(a: Int) {
<!WRONG_ANNOTATION_TARGET!>@ann<!>
when (a) {
1 -> {}
}
}
annotation class ann
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
/* /*
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
* *
@@ -613,6 +613,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token, token,
) )
} }
add(FirErrors.WRONG_ANNOTATION_TARGET) { firDiagnostic ->
WrongAnnotationTargetImpl(
firDiagnostic.a,
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE) { firDiagnostic -> add(FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE) { firDiagnostic ->
ExposedTypealiasExpandedTypeImpl( ExposedTypealiasExpandedTypeImpl(
firDiagnostic.a, firDiagnostic.a,
@@ -438,6 +438,11 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = RestrictedRetentionForExpressionAnnotation::class override val diagnosticClass get() = RestrictedRetentionForExpressionAnnotation::class
} }
abstract class WrongAnnotationTarget : KtFirDiagnostic<KtAnnotationEntry>() {
override val diagnosticClass get() = WrongAnnotationTarget::class
abstract val actualTarget: String
}
abstract class ExposedTypealiasExpandedType : KtFirDiagnostic<KtNamedDeclaration>() { abstract class ExposedTypealiasExpandedType : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = ExposedTypealiasExpandedType::class override val diagnosticClass get() = ExposedTypealiasExpandedType::class
abstract val elementVisibility: EffectiveVisibility abstract val elementVisibility: EffectiveVisibility
@@ -712,6 +712,14 @@ internal class RestrictedRetentionForExpressionAnnotationImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
} }
internal class WrongAnnotationTargetImpl(
override val actualTarget: String,
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.WrongAnnotationTarget(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ExposedTypealiasExpandedTypeImpl( internal class ExposedTypealiasExpandedTypeImpl(
override val elementVisibility: EffectiveVisibility, override val elementVisibility: EffectiveVisibility,
override val restrictingDeclaration: KtSymbol, override val restrictingDeclaration: KtSymbol,