feat(repomap): index C#/Godot-Mono (.cs) type symbols
Conservative type-declaration pattern (class/interface/struct/enum/record); no method capture to avoid false positives. (BACKLOG I) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -84,6 +84,12 @@ class RepoMapIndexer(
|
|||||||
"ts" to Regex("""(?m)^\s*(?:export\s+)?(?:default\s+)?(?:async\s+)?(?:function|class|interface|type|enum)\s+(?<name>[A-Za-z_$][A-Za-z0-9_$]*)"""),
|
"ts" to Regex("""(?m)^\s*(?:export\s+)?(?:default\s+)?(?:async\s+)?(?:function|class|interface|type|enum)\s+(?<name>[A-Za-z_$][A-Za-z0-9_$]*)"""),
|
||||||
// GDScript: column-0 declarations only, so indented inner-class members never match.
|
// GDScript: column-0 declarations only, so indented inner-class members never match.
|
||||||
"gd" to Regex("""(?m)^(?:static\s+)?(?:func|class_name|class|signal|enum)\s+(?<name>[A-Za-z_][A-Za-z0-9_]*)"""),
|
"gd" to Regex("""(?m)^(?:static\s+)?(?:func|class_name|class|signal|enum)\s+(?<name>[A-Za-z_][A-Za-z0-9_]*)"""),
|
||||||
|
// C# / Godot Mono: top-level type declarations with leading modifiers, kept conservative
|
||||||
|
// (no method capture — return-type heuristics there are noisy and risk false positives).
|
||||||
|
"cs" to Regex(
|
||||||
|
"""(?m)^\s*(?:public |private |protected |internal |static |sealed |abstract |""" +
|
||||||
|
"""partial )*(?:class|interface|struct|enum|record)\s+(?<name>[A-Za-z_][A-Za-z0-9_]*)""",
|
||||||
|
),
|
||||||
// Markdown: h1–h3 headings as "symbols" — deeper levels are noise relative to retrieval value.
|
// Markdown: h1–h3 headings as "symbols" — deeper levels are noise relative to retrieval value.
|
||||||
"md" to Regex("""(?m)^#{1,3}\s+(?<name>.+?)\s*$"""),
|
"md" to Regex("""(?m)^#{1,3}\s+(?<name>.+?)\s*$"""),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -75,6 +75,42 @@ class RepoMapIndexerTest {
|
|||||||
assertFalse(entry.symbols.contains("help"), "indented inner method must not be matched")
|
assertFalse(entry.symbols.contains("help"), "indented inner method must not be matched")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `extracts C# (Godot Mono) top-level type symbols`(@TempDir root: Path) {
|
||||||
|
root.resolve("Player.cs").writeText(
|
||||||
|
"""
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Game;
|
||||||
|
|
||||||
|
public sealed partial class Player : CharacterBody2D
|
||||||
|
{
|
||||||
|
private int _health = 100;
|
||||||
|
|
||||||
|
public void TakeDamage(int amount)
|
||||||
|
{
|
||||||
|
_health -= amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal interface IDamageable
|
||||||
|
{
|
||||||
|
void TakeDamage(int amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum State { Idle, Running }
|
||||||
|
""".trimIndent(),
|
||||||
|
)
|
||||||
|
|
||||||
|
val entry = RepoMapIndexer().index(root).single()
|
||||||
|
assertEquals("Player.cs", entry.path)
|
||||||
|
assertTrue(
|
||||||
|
entry.symbols.containsAll(listOf("Player", "IDamageable", "State")),
|
||||||
|
"missing symbols in: ${entry.symbols}",
|
||||||
|
)
|
||||||
|
assertFalse(entry.symbols.contains("TakeDamage"), "method/field bodies must not be matched")
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `extracts markdown headings as symbols`(@TempDir root: Path) {
|
fun `extracts markdown headings as symbols`(@TempDir root: Path) {
|
||||||
root.resolve("design.md").writeText(
|
root.resolve("design.md").writeText(
|
||||||
|
|||||||
Reference in New Issue
Block a user