7
7
8
8
package land.sungbin.composeinvestigator.compiler.frontend
9
9
10
- import androidx.compose.compiler.plugins.kotlin.k2.ComposableFunction
11
10
import androidx.compose.compiler.plugins.kotlin.k2.hasComposableAnnotation
11
+ import androidx.compose.compiler.plugins.kotlin.lower.fastForEach
12
12
import land.sungbin.composeinvestigator.compiler.NO_INVESTIGATION_FQN
13
13
import land.sungbin.composeinvestigator.compiler.lower.unsafeLazy
14
14
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
15
15
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
16
+ import org.jetbrains.kotlin.fir.FirElement
16
17
import org.jetbrains.kotlin.fir.FirSession
17
18
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
18
19
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
19
20
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
20
21
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirFileChecker
21
22
import org.jetbrains.kotlin.fir.analysis.extensions.FirAdditionalCheckersExtension
22
23
import org.jetbrains.kotlin.fir.declarations.FirFile
23
- import org.jetbrains.kotlin.fir.declarations.FirFunction
24
24
import org.jetbrains.kotlin.fir.declarations.validate
25
+ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
25
26
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation
26
27
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyAnnotationArgumentMapping
28
+ import org.jetbrains.kotlin.fir.references.toResolvedFunctionSymbol
27
29
import org.jetbrains.kotlin.fir.smartPlus
28
30
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
29
- import org.jetbrains.kotlin.fir.types.coneType
30
31
import org.jetbrains.kotlin.fir.types.constructClassLikeType
31
- import org.jetbrains.kotlin.fir.types.functionTypeKind
32
+ import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
32
33
import org.jetbrains.kotlin.name.ClassId
33
34
34
35
public class InvalidationTraceTableInstantiationValidator (session : FirSession ) : FirAdditionalCheckersExtension(session) {
@@ -45,27 +46,38 @@ private object NoComposableFileChecker : FirFileChecker(MppCheckerKind.Common) {
45
46
}
46
47
47
48
override fun check (declaration : FirFile , context : CheckerContext , reporter : DiagnosticReporter ) {
48
- if (
49
- declaration.declarations.none { element ->
50
- element.hasComposableAnnotation(context.session) ||
51
- (
52
- element is FirFunction &&
53
- element.valueParameters.any { parameter ->
54
- parameter.returnTypeRef.coneType.functionTypeKind(context.session) == = ComposableFunction
55
- }
56
- )
49
+ var hasComposable = false
50
+
51
+ val composableCallVisitor = object : FirDefaultVisitorVoid () {
52
+ override fun visitElement (element : FirElement ) {
53
+ if (hasComposable) return
54
+ element.acceptChildren(this )
57
55
}
58
- ) {
59
- val noInvestigationAnnotation = buildAnnotation {
60
- useSiteTarget = AnnotationUseSiteTarget .FILE
61
- annotationTypeRef = noInvestigationType
62
- argumentMapping = FirEmptyAnnotationArgumentMapping
56
+
57
+ override fun visitFunctionCall (functionCall : FirFunctionCall ) {
58
+ if (functionCall.calleeReference.toResolvedFunctionSymbol()!! .hasComposableAnnotation(context.session))
59
+ hasComposable = true
60
+
61
+ if (hasComposable) return
62
+ super .visitFunctionCall(functionCall)
63
63
}
64
+ }
64
65
65
- declaration.replaceAnnotations(declaration.annotations.smartPlus(listOf (noInvestigationAnnotation)))
66
+ declaration.declarations.fastForEach { element ->
67
+ element.acceptChildren(composableCallVisitor)
68
+ }
69
+
70
+ if (hasComposable) return
66
71
67
- // Validate that the new annotations do not break the file.
68
- declaration.validate()
72
+ val noInvestigationAnnotation = buildAnnotation {
73
+ useSiteTarget = AnnotationUseSiteTarget .FILE
74
+ annotationTypeRef = noInvestigationType
75
+ argumentMapping = FirEmptyAnnotationArgumentMapping
69
76
}
77
+
78
+ declaration.replaceAnnotations(declaration.annotations.smartPlus(listOf (noInvestigationAnnotation)))
79
+
80
+ // Validate that the new annotations do not break the file.
81
+ declaration.validate()
70
82
}
71
83
}
0 commit comments