Skip to content

Commit

Permalink
[Compiler plugin] Add warning to avoid confusion with missing extensi…
Browse files Browse the repository at this point in the history
…on properties
  • Loading branch information
koperagen committed Nov 29, 2024
1 parent 3f054ab commit a9b1851
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
import org.jetbrains.kotlin.diagnostics.error1
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.diagnostics.warning1
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
Expand All @@ -29,6 +30,7 @@ import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isSubtypeOf
import org.jetbrains.kotlin.fir.types.renderReadable
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.fir.types.type
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
Expand All @@ -38,6 +40,7 @@ import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlinx.dataframe.plugin.impl.PluginDataFrameSchema
import org.jetbrains.kotlinx.dataframe.plugin.impl.SimpleDataColumn
import org.jetbrains.kotlinx.dataframe.plugin.impl.type
import org.jetbrains.kotlinx.dataframe.plugin.utils.Names

class ExpressionAnalysisAdditionalChecker(
session: FirSession,
Expand All @@ -58,6 +61,7 @@ private class Checker(
companion object {
val ERROR by error1<KtElement, String>(SourceElementPositioningStrategies.DEFAULT)
val CAST_ERROR by error1<KtElement, String>(SourceElementPositioningStrategies.CALL_ELEMENT_WITH_DOT)
val CAST_TARGET_WARNING by warning1<KtElement, String>(SourceElementPositioningStrategies.CALL_ELEMENT_WITH_DOT)
val CAST_ID = CallableId(FqName.fromSegments(listOf("org", "jetbrains", "kotlinx", "dataframe", "api")), Name.identifier("cast"))
val CHECK = ClassId(FqName("org.jetbrains.kotlinx.dataframe.annotations"), Name.identifier("Check"))
}
Expand Down Expand Up @@ -87,13 +91,18 @@ private class Checker(
|| !calleeReference.resolvedSymbol.hasAnnotation(CHECK, session)) {
return
}
val targetProjection = expression.typeArguments.getOrNull(0) as? FirTypeProjectionWithVariance ?: return
val targetType = targetProjection.typeRef.coneType as? ConeClassLikeType ?: return
val targetSymbol = targetType.toSymbol(session)
if (targetSymbol != null && !targetSymbol.hasAnnotation(Names.DATA_SCHEMA_CLASS_ID, session)) {
val text = "Annotate ${targetType.renderReadable()} with @DataSchema to use generated properties"
reporter.reportOn(expression.source, CAST_TARGET_WARNING, text, context)
}
val coneType = expression.explicitReceiver?.resolvedType
if (coneType != null) {
val sourceType = coneType.fullyExpandedType(session).typeArguments.getOrNull(0)?.type as? ConeClassLikeType
?: return
val source = pluginDataFrameSchema(sourceType)
val targetProjection = expression.typeArguments.getOrNull(0) as? FirTypeProjectionWithVariance ?: return
val targetType = targetProjection.typeRef.coneType as? ConeClassLikeType ?: return
val target = pluginDataFrameSchema(targetType)
val sourceColumns = source.flatten(includeFrames = true)
val targetColumns = target.flatten(includeFrames = true)
Expand Down
6 changes: 5 additions & 1 deletion plugins/kotlin-dataframe/testData/box/playground.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import org.jetbrains.kotlinx.dataframe.annotations.*
import org.jetbrains.kotlinx.dataframe.api.*
import org.jetbrains.kotlinx.dataframe.io.*

interface MySchema {
val a: String
}
fun box(): String {

val df = DataFrame.Empty
<!CAST_TARGET_WARNING!>df.cast<MySchema>()<!>
return "OK"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FILE: targetOfCastIsNotDataSchema.kt
public abstract interface MySchema : R|kotlin/Any| {
public abstract val a: R|kotlin/String|
public get(): R|kotlin/String|

}
public final fun box(): R|kotlin/String| {
lval df: R|{org/jetbrains/kotlinx/dataframe/AnyFrame=} org/jetbrains/kotlinx/dataframe/DataFrame<*>| = Q|org/jetbrains/kotlinx/dataframe/DataFrame|.R|org/jetbrains/kotlinx/dataframe/DataFrame.Companion.Empty|
R|<local>/df|.R|org/jetbrains/kotlinx/dataframe/api/cast|<R|MySchema|>()
^box String(OK)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import org.jetbrains.kotlinx.dataframe.*
import org.jetbrains.kotlinx.dataframe.annotations.*
import org.jetbrains.kotlinx.dataframe.api.*
import org.jetbrains.kotlinx.dataframe.io.*

interface MySchema {
val a: String
}
fun box(): String {
val df = DataFrame.Empty
<!CAST_TARGET_WARNING!>df.cast<MySchema>()<!>
return "OK"
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ public void testStructuralCast() {
runTest("testData/diagnostics/structuralCast.kt");
}

@Test
@TestMetadata("targetOfCastIsNotDataSchema.kt")
public void testTargetOfCastIsNotDataSchema() {
runTest("testData/diagnostics/targetOfCastIsNotDataSchema.kt");
}

@Test
@TestMetadata("toDataFrame_java.kt")
public void testToDataFrame_java() {
Expand Down

0 comments on commit a9b1851

Please sign in to comment.