Added support for extern declarations and enhanced .lyng.d merging

- Implemented `extern` support for functions, classes, objects, enums, and properties in the `MiniAST`.
- Updated `MiniAST` to include `isExtern` field for applicable nodes.
- Enabled merging of `.lyng.d` declaration files into main `.lyng` scripts.
- Adjusted tests to validate `extern` behavior and documentation handling.
- Minor fixes to parser logic for improved robustness.
This commit is contained in:
sergeych committed 2026-01-06 17:05:03 +01:00
1 parent 44675b976d
commit fdc044d1e0
8 files changed
+310 -95

No files matched your search

@@ -222,4 +222,55 @@ class MiniAstTest {
assertTrue(names.contains("V1"), "Should contain V1")
assertTrue(names.contains("V2"), "Should contain V2")
}
@Test
fun miniAst_captures_extern_docs() = runTest {
val code = """
// Doc1
extern fun f1()
// Doc2
extern class C1 {
// Doc3
fun m1()
}
// Doc4
extern object O1 {
// Doc5
val v1: String
}
// Doc6
extern enum E1 {
V1, V2
}
""".trimIndent()
val (_, sink) = compileWithMini(code)
val mini = sink.build()
assertNotNull(mini)
val f1 = mini.declarations.filterIsInstance<MiniFunDecl>().firstOrNull { it.name == "f1" }
assertNotNull(f1)
assertEquals("Doc1", f1.doc?.summary)
val c1 = mini.declarations.filterIsInstance<MiniClassDecl>().firstOrNull { it.name == "C1" }
assertNotNull(c1)
assertEquals("Doc2", c1.doc?.summary)
val m1 = c1.members.filterIsInstance<MiniMemberFunDecl>().firstOrNull { it.name == "m1" }
assertNotNull(m1)
assertEquals("Doc3", m1.doc?.summary)
val o1 = mini.declarations.filterIsInstance<MiniClassDecl>().firstOrNull { it.name == "O1" }
assertNotNull(o1)
assertTrue(o1.isObject)
assertEquals("Doc4", o1.doc?.summary)
val v1 = o1.members.filterIsInstance<MiniMemberValDecl>().firstOrNull { it.name == "v1" }
assertNotNull(v1)
assertEquals("Doc5", v1.doc?.summary)
val e1 = mini.declarations.filterIsInstance<MiniEnumDecl>().firstOrNull { it.name == "E1" }
assertNotNull(e1)
assertEquals("Doc6", e1.doc?.summary)
}
}
+25 -23
View File
@@ -3043,32 +3043,34 @@ class ScriptTest {
}
@Test
fun testMapWithNonStringKeys() = runTest {
fun testExternDeclarations() = runTest {
eval(
"""
val map = Map( 1 => "one", 2 => "two" )
assertEquals( "one", map[1] )
assertEquals( "two", map[2] )
assertEquals( null, map[3] )
map[3] = "three"
assertEquals( "three", map[3] )
map += (4 => "four")
assertEquals( "four", map[4] )
extern fun hostFunction(a: Int, b: String): String
extern class HostClass(name: String) {
fun doSomething(): Int
val status: String
}
extern object HostObject {
fun getInstance(): HostClass
}
extern enum HostEnum {
VALUE1, VALUE2
}
// Test toMap()
val map2 = [1 => "a", 2 => "b"].toMap()
assertEquals("a", map2[1])
assertEquals("b", map2[2])
// Test Map constructor with mixed entries and arrays
val map3 = Map( 1 => "a", [2, "b"] )
assertEquals("a", map3[1])
assertEquals("b", map3[2])
// Test plus
val map4 = map3 + (3 => "c")
assertEquals("c", map4[3])
assertEquals("a", map4[1])
// These should not throw errors during compilation
// and should be registered in the scope (though they won't have implementations here)
// In this test environment, they might fail at runtime if called, but we just check compilation.
""".trimIndent()
)
}
@Test
fun testExternExtension() = runTest {
eval(
"""
extern fun String.pretty(): String
// Compiles without error
""".trimIndent()
)
}