Improve extern member diagnostics and cover extern generic class test

This commit is contained in:
Sergey Chernov 2026-03-15 04:09:24 +03:00
parent 979e6ea9b7
commit 2b13fe8053
2 changed files with 37 additions and 2 deletions

View File

@ -7762,7 +7762,11 @@ class Compiler(
nameStartPos = t.pos
}
if (parentClassCtx?.isExtern == true && !isExtern) {
throw ScriptError(nameStartPos, "members of extern classes/objects must be marked extern")
val owner = parentClassCtx.name
throw ScriptError(
nameStartPos,
"member '$name' in extern class/object '$owner' must be declared extern (use `extern fun $name(...)`)"
)
}
val extensionWrapperName = extTypeName?.let { extensionCallableName(it, name) }
val classCtx = codeContexts.asReversed().firstOrNull { it is CodeContext.ClassBody } as? CodeContext.ClassBody
@ -8788,7 +8792,12 @@ class Compiler(
}
val parentClassCtx = codeContexts.lastOrNull() as? CodeContext.ClassBody
if (parentClassCtx?.isExtern == true && !isExtern) {
throw ScriptError(nameStartPos, "members of extern classes/objects must be marked extern")
val owner = parentClassCtx.name
val kind = if (isMutable) "var" else "val"
throw ScriptError(
nameStartPos,
"member '$name' in extern class/object '$owner' must be declared extern (use `extern $kind $name: ...`)"
)
}
val receiverNormalization = normalizeReceiverTypeDecl(receiverTypeDecl, emptySet())

View File

@ -615,6 +615,32 @@ class TypesTest {
""".trimIndent())
}
@Test
fun testExternGenerics() = runTest {
eval("""
extern fun f<T>(x: T): T
extern class Cell<T> {
extern var value: T
}
""")
}
@Test
fun testExternClassMemberMustBeExternMessage() = runTest {
val e = assertFailsWith<ScriptError> {
eval(
"""
extern class Cell<T> {
var value: T
}
""".trimIndent()
)
}
assertTrue(e.message?.contains("must be declared extern") == true)
assertTrue(e.message?.contains("extern var value") == true)
}
// @Test fun nonTrivialOperatorsTest() = runTest {
// val s = Script.newScope()
// s.eval("""