@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
9
9
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
10
10
import org.jetbrains.kotlin.diagnostics.error1
11
11
import org.jetbrains.kotlin.diagnostics.reportOn
12
+ import org.jetbrains.kotlin.diagnostics.warning1
12
13
import org.jetbrains.kotlin.fir.FirSession
13
14
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
14
15
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.fir.types.coneType
29
30
import org.jetbrains.kotlin.fir.types.isSubtypeOf
30
31
import org.jetbrains.kotlin.fir.types.renderReadable
31
32
import org.jetbrains.kotlin.fir.types.resolvedType
33
+ import org.jetbrains.kotlin.fir.types.toSymbol
32
34
import org.jetbrains.kotlin.fir.types.type
33
35
import org.jetbrains.kotlin.name.CallableId
34
36
import org.jetbrains.kotlin.name.ClassId
@@ -38,6 +40,7 @@ import org.jetbrains.kotlin.psi.KtElement
38
40
import org.jetbrains.kotlinx.dataframe.plugin.impl.PluginDataFrameSchema
39
41
import org.jetbrains.kotlinx.dataframe.plugin.impl.SimpleDataColumn
40
42
import org.jetbrains.kotlinx.dataframe.plugin.impl.type
43
+ import org.jetbrains.kotlinx.dataframe.plugin.utils.Names
41
44
42
45
class ExpressionAnalysisAdditionalChecker (
43
46
session : FirSession ,
@@ -58,6 +61,7 @@ private class Checker(
58
61
companion object {
59
62
val ERROR by error1<KtElement , String >(SourceElementPositioningStrategies .DEFAULT )
60
63
val CAST_ERROR by error1<KtElement , String >(SourceElementPositioningStrategies .CALL_ELEMENT_WITH_DOT )
64
+ val CAST_TARGET_WARNING by warning1<KtElement , String >(SourceElementPositioningStrategies .CALL_ELEMENT_WITH_DOT )
61
65
val CAST_ID = CallableId (FqName .fromSegments(listOf (" org" , " jetbrains" , " kotlinx" , " dataframe" , " api" )), Name .identifier(" cast" ))
62
66
val CHECK = ClassId (FqName (" org.jetbrains.kotlinx.dataframe.annotations" ), Name .identifier(" Check" ))
63
67
}
@@ -87,13 +91,18 @@ private class Checker(
87
91
|| ! calleeReference.resolvedSymbol.hasAnnotation(CHECK , session)) {
88
92
return
89
93
}
94
+ val targetProjection = expression.typeArguments.getOrNull(0 ) as ? FirTypeProjectionWithVariance ? : return
95
+ val targetType = targetProjection.typeRef.coneType as ? ConeClassLikeType ? : return
96
+ val targetSymbol = targetType.toSymbol(session)
97
+ if (targetSymbol != null && ! targetSymbol.hasAnnotation(Names .DATA_SCHEMA_CLASS_ID , session)) {
98
+ val text = " Annotate ${targetType.renderReadable()} with @DataSchema to use generated properties"
99
+ reporter.reportOn(expression.source, CAST_TARGET_WARNING , text, context)
100
+ }
90
101
val coneType = expression.explicitReceiver?.resolvedType
91
102
if (coneType != null ) {
92
103
val sourceType = coneType.fullyExpandedType(session).typeArguments.getOrNull(0 )?.type as ? ConeClassLikeType
93
104
? : return
94
105
val source = pluginDataFrameSchema(sourceType)
95
- val targetProjection = expression.typeArguments.getOrNull(0 ) as ? FirTypeProjectionWithVariance ? : return
96
- val targetType = targetProjection.typeRef.coneType as ? ConeClassLikeType ? : return
97
106
val target = pluginDataFrameSchema(targetType)
98
107
val sourceColumns = source.flatten(includeFrames = true )
99
108
val targetColumns = target.flatten(includeFrames = true )
0 commit comments