[FIR] Add ability to specify that diagnostic collector should visit nodes with specific fake kind

This commit is contained in:
Dmitriy Novozhilov
2023-02-01 12:46:57 +02:00
committed by Space Team
parent f784628ebf
commit ad3ae0ff69
3 changed files with 18 additions and 12 deletions
@@ -44,6 +44,7 @@ object FirProjectionRelationChecker : FirBasicDeclarationChecker() {
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
if (typeRef.source?.kind?.shouldSkipErrorTypeReporting != false) return
val type = typeRef.coneTypeSafe<ConeClassLikeType>() val type = typeRef.coneTypeSafe<ConeClassLikeType>()
val fullyExpandedType = type?.fullyExpandedType(context.session) ?: return val fullyExpandedType = type?.fullyExpandedType(context.session) ?: return
val declaration = fullyExpandedType.toSymbol(context.session) as? FirRegularClassSymbol ?: return val declaration = fullyExpandedType.toSymbol(context.session) as? FirRegularClassSymbol ?: return
@@ -182,7 +182,7 @@ abstract class AbstractDiagnosticCollectorVisitor(
} }
override fun visitTypeRef(typeRef: FirTypeRef, data: Nothing?) { override fun visitTypeRef(typeRef: FirTypeRef, data: Nothing?) {
if (typeRef.source != null && typeRef.source?.kind !is KtFakeSourceElementKind) { if (typeRef.source?.kind?.shouldSkipErrorTypeReporting == false) {
withTypeRefAnnotationContainer(typeRef) { withTypeRefAnnotationContainer(typeRef) {
checkElement(typeRef) checkElement(typeRef)
visitNestedElements(typeRef) visitNestedElements(typeRef)
@@ -200,9 +200,9 @@ abstract class AbstractDiagnosticCollectorVisitor(
// collected twice: once through resolvedTypeRef's children and another through resolvedTypeRef.delegatedTypeRef's children. // collected twice: once through resolvedTypeRef's children and another through resolvedTypeRef.delegatedTypeRef's children.
val resolvedTypeRefType = resolvedTypeRef.type val resolvedTypeRefType = resolvedTypeRef.type
if (resolvedTypeRefType is ConeErrorType) { if (resolvedTypeRefType is ConeErrorType) {
super.visitResolvedTypeRef(resolvedTypeRef, data) visitTypeRef(resolvedTypeRef, data)
} }
if (resolvedTypeRef.source?.kind is KtFakeSourceElementKind) return if (resolvedTypeRef.source?.kind?.shouldSkipErrorTypeReporting != false) return
// Even though we don't visit the children of the resolvedTypeRef we still add it as an annotation container // Even though we don't visit the children of the resolvedTypeRef we still add it as an annotation container
// and take care not to add the corresponding delegatedTypeRef. This is so that diagnostics will have access to // and take care not to add the corresponding delegatedTypeRef. This is so that diagnostics will have access to
@@ -15,15 +15,20 @@ import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import com.intellij.util.diff.FlyweightCapableTreeStructure import com.intellij.util.diff.FlyweightCapableTreeStructure
sealed class KtSourceElementKind sealed class KtSourceElementKind {
abstract val shouldSkipErrorTypeReporting: Boolean
}
object KtRealSourceElementKind : KtSourceElementKind() object KtRealSourceElementKind : KtSourceElementKind() {
override val shouldSkipErrorTypeReporting: Boolean
get() = false
}
sealed class KtFakeSourceElementKind : KtSourceElementKind() { sealed class KtFakeSourceElementKind(final override val shouldSkipErrorTypeReporting: Boolean = false) : KtSourceElementKind() {
// for some fir expression implicit return typeRef is generated // for some fir expression implicit return typeRef is generated
// some of them are: break, continue, return, throw, string concat, // some of them are: break, continue, return, throw, string concat,
// destruction parameters, function literals, explicitly boolean expressions // destruction parameters, function literals, explicitly boolean expressions
object ImplicitTypeRef : KtFakeSourceElementKind() object ImplicitTypeRef : KtFakeSourceElementKind(shouldSkipErrorTypeReporting = true)
// for each class special class self type ref is created // for each class special class self type ref is created
// and have a fake source referencing it // and have a fake source referencing it
@@ -35,7 +40,7 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
// for properties without accessors default getter & setter are generated // for properties without accessors default getter & setter are generated
// they have a fake source which refers to property // they have a fake source which refers to property
object DefaultAccessor : KtFakeSourceElementKind() object DefaultAccessor : KtFakeSourceElementKind(shouldSkipErrorTypeReporting = true)
// for delegated properties, getter & setter calls to the delegate // for delegated properties, getter & setter calls to the delegate
// they have a fake source which refers to the call that creates the delegate // they have a fake source which refers to the call that creates the delegate
@@ -107,7 +112,7 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
// for primary constructor parameter the corresponding class property is generated // for primary constructor parameter the corresponding class property is generated
// with a fake sources which refers to this the corresponding parameter // with a fake sources which refers to this the corresponding parameter
object PropertyFromParameter : KtFakeSourceElementKind() object PropertyFromParameter : KtFakeSourceElementKind(shouldSkipErrorTypeReporting = true)
// if (true) 1 --> if(true) { 1 } // if (true) 1 --> if(true) { 1 }
// with a fake sources for the block which refers to the wrapped expression // with a fake sources for the block which refers to the wrapped expression
@@ -132,7 +137,7 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
// for data classes fir generates componentN() & copy() functions // for data classes fir generates componentN() & copy() functions
// for componentN() functions the source will refer to the corresponding param and will be marked as a fake one // for componentN() functions the source will refer to the corresponding param and will be marked as a fake one
// for copy() functions the source will refer class to the param and will be marked as a fake one // for copy() functions the source will refer class to the param and will be marked as a fake one
object DataClassGeneratedMembers : KtFakeSourceElementKind() object DataClassGeneratedMembers : KtFakeSourceElementKind(shouldSkipErrorTypeReporting = true)
// (vararg x: Int) --> (x: Array<out Int>) where array type ref has a fake source kind // (vararg x: Int) --> (x: Array<out Int>) where array type ref has a fake source kind
object ArrayTypeFromVarargParameter : KtFakeSourceElementKind() object ArrayTypeFromVarargParameter : KtFakeSourceElementKind()
@@ -143,7 +148,7 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
// when smart casts applied to the expression, it is wrapped into FirSmartCastExpression // when smart casts applied to the expression, it is wrapped into FirSmartCastExpression
// which type reference will have a fake source refer to a original source element of it // which type reference will have a fake source refer to a original source element of it
object SmartCastedTypeRef : KtFakeSourceElementKind() object SmartCastedTypeRef : KtFakeSourceElementKind(shouldSkipErrorTypeReporting = true)
// when smart casts applied to the expression, it is wrapped into FirSmartCastExpression // when smart casts applied to the expression, it is wrapped into FirSmartCastExpression
// this kind used for such FirSmartCastExpressions itself // this kind used for such FirSmartCastExpressions itself
@@ -181,7 +186,7 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
// Consider `super<Supertype>.foo()`. The source PSI `Supertype` is referenced by both the qualified access expression // Consider `super<Supertype>.foo()`. The source PSI `Supertype` is referenced by both the qualified access expression
// `super<Supertype>` and the calleeExpression `super<Supertype>`. To avoid having two FIR elements sharing the same source, this fake // `super<Supertype>` and the calleeExpression `super<Supertype>`. To avoid having two FIR elements sharing the same source, this fake
// source is assigned to the qualified access expression. // source is assigned to the qualified access expression.
object SuperCallExplicitType : KtFakeSourceElementKind() object SuperCallExplicitType : KtFakeSourceElementKind(shouldSkipErrorTypeReporting = true)
// fun foo(vararg args: Int) {} // fun foo(vararg args: Int) {}
// fun bar(1, 2, 3) --> [resolved] fun bar(VarargArgument(1, 2, 3)) // fun bar(1, 2, 3) --> [resolved] fun bar(VarargArgument(1, 2, 3))