Skip to content

Commit 05e68e6

Browse files
committed
Add zed-netcoredbg to csharp extension, add runnables
- Use extension from https://github.com/qwadrox/zed-netcoredbg to have basic debug functionality with DAP and download netcoredbg for the running platform. - Add runnables and tasks to debug from test files. Captures for nunit, xunit, vstest. Not strict, purely functional (does not pair keywords) to test framework. - Currently unable to fully attach to runnable, but starts the vstest process so that it can be easily attached with PID listed in console
1 parent 9ac1752 commit 05e68e6

10 files changed

Lines changed: 900 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ crate-type = ["cdylib"]
1111

1212
[dependencies]
1313
zed_extension_api = "0.7.0"
14+
serde = { version = "1.0", features = ["derive"] }
15+
fs_extra = "1.3.0"
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "Zed NetCoreDbg Debug Adapter Protocol Configuration",
4+
"description": "JSON schema for netcoredbg debug adapter protocol launch and attach configurations",
5+
"type": "object",
6+
"properties": {
7+
"request": {
8+
"type": "string",
9+
"enum": [
10+
"launch",
11+
"attach"
12+
],
13+
"description": "The request type - either 'launch' to start a new process or 'attach' to connect to an existing process"
14+
}
15+
},
16+
"required": [
17+
"request"
18+
],
19+
"allOf": [
20+
{
21+
"if": {
22+
"properties": {
23+
"request": {
24+
"const": "launch"
25+
}
26+
}
27+
},
28+
"then": {
29+
"properties": {
30+
"request": true,
31+
"program": {
32+
"type": "string",
33+
"pattern": "\\.(dll|exe)$",
34+
"description": "Path to the executable assembly (.dll or .exe) to launch. This is the main entry point of your .NET application. NetCoreDbg will use 'dotnet' as the runtime and pass this as the first argument."
35+
},
36+
"args": {
37+
"type": "array",
38+
"items": {
39+
"type": "string"
40+
},
41+
"default": [],
42+
"description": "Command line arguments to pass to the program. These arguments are appended after the program path when launching with 'dotnet'."
43+
},
44+
"cwd": {
45+
"type": "string",
46+
"description": "Working directory for the launched process. This is crucial for .NET applications as it determines where configuration files (like appsettings.json), relative file paths, and other resources are resolved from. For ASP.NET Core apps, this affects content root discovery and static file serving. If not specified, defaults to the workspace root directory.",
47+
"default": "${ZED_WORKTREE_ROOT}"
48+
},
49+
"env": {
50+
"type": "object",
51+
"additionalProperties": {
52+
"type": "string"
53+
},
54+
"default": {},
55+
"description": "Environment variables to set for the launched process. These are key-value pairs that will be available to your application at runtime."
56+
},
57+
"stopAtEntry": {
58+
"type": "boolean",
59+
"default": false,
60+
"description": "Whether to stop at the entry point (main method) of the program. When true, the debugger will break at the first line of user code, allowing you to step through from the very beginning."
61+
},
62+
"justMyCode": {
63+
"type": "boolean",
64+
"default": true,
65+
"description": "Enable Just My Code debugging. When true, the debugger will only step through and break in user-written code, skipping framework and library code. This matches the default behavior of Microsoft's vsdbg."
66+
},
67+
"enableStepFiltering": {
68+
"type": "boolean",
69+
"default": true,
70+
"description": "Enable step filtering to automatically step over properties, operators, and other code constructs that are typically not interesting during debugging. This matches the default behavior of Microsoft's vsdbg."
71+
},
72+
"tcp_connection": {
73+
"type": "string",
74+
"default": "localhost:4711",
75+
"description": "TCP Connection to connect with to netcoredbg"
76+
}
77+
},
78+
"required": [
79+
"program"
80+
]
81+
}
82+
},
83+
{
84+
"if": {
85+
"properties": {
86+
"request": {
87+
"const": "attach"
88+
}
89+
}
90+
},
91+
"then": {
92+
"properties": {
93+
"request": true,
94+
"processId": {
95+
"oneOf": [
96+
{
97+
"type": "integer",
98+
"minimum": 1,
99+
"description": "Numeric process ID to attach to"
100+
},
101+
{
102+
"type": "string",
103+
"pattern": "^[0-9]+$",
104+
"description": "String representation of process ID to attach to"
105+
}
106+
],
107+
"description": "The process ID of the running .NET application to attach to. Can be specified as a number or string representation of a number. The target process must be a .NET Core application with debugging enabled."
108+
}
109+
},
110+
"required": [
111+
"processId"
112+
]
113+
}
114+
}
115+
]
116+
}

extension.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,23 @@ language = "CSharp"
2121
repository = "https://github.com/tree-sitter/tree-sitter-c-sharp"
2222
commit = "dd5e59721a5f8dae34604060833902b882023aaf"
2323

24+
[debug_adapters.netcoredbg]
25+
schema_path = "debug_adapter_schemas/netcoredbg.json"
26+
27+
[debug_locators.csharp-test-runner]
28+
2429
# Used to run `csharp-language-server --download` after an update
2530
[[capabilities]]
2631
kind = "process:exec"
2732
command = "*"
2833
args = ["--download"]
34+
35+
[[capabilities]]
36+
kind = "download_file"
37+
host = "github.com"
38+
path = ["qwadrox", "netcoredbg", "**"]
39+
40+
[[capabilities]]
41+
kind = "download_file"
42+
host = "objects.githubusercontent.com"
43+
path = ["**"]

languages/csharp/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ brackets = [
1212
{ start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
1313
{ start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
1414
]
15+
debuggers = ["netcoredbg"]

languages/csharp/runnables.scm

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
; =========================
2+
; Test method with namespace
3+
; =========================
4+
(
5+
(namespace_declaration
6+
name: (_) @csharp_namespace
7+
body: (declaration_list
8+
(class_declaration
9+
name: (identifier) @csharp_class_name @csharp_csproj_hint
10+
body: (declaration_list
11+
(method_declaration
12+
(attribute_list
13+
(attribute
14+
name: (_) @attribute_name
15+
(#match? @attribute_name "^(Fact|Theory|Test|TestCase|TestCaseSource|TestMethod|DataTestMethod)$")))
16+
name: (identifier) @run @csharp_method_name)))))
17+
(#set! tag csharp-test-method)
18+
)
19+
20+
; ======================================
21+
; Test method with file-scoped namespace
22+
; ======================================
23+
(
24+
(file_scoped_namespace_declaration
25+
name: (_) @csharp_namespace
26+
(class_declaration
27+
name: (identifier) @csharp_class_name @csharp_csproj_hint
28+
body: (declaration_list
29+
(method_declaration
30+
(attribute_list
31+
(attribute
32+
name: (_) @attribute_name
33+
(#match? @attribute_name "^(Fact|Theory|Test|TestCase|TestCaseSource|TestMethod|DataTestMethod)$")))
34+
name: (identifier) @run @csharp_method_name))))
35+
(#set! tag csharp-test-method)
36+
)
37+
38+
; ============================
39+
; Test method without namespace
40+
; (anchored to top-level only)
41+
; ============================
42+
(
43+
(compilation_unit
44+
(class_declaration
45+
name: (identifier) @csharp_class_name @csharp_csproj_hint
46+
body: (declaration_list
47+
(method_declaration
48+
(attribute_list
49+
(attribute
50+
name: (_) @attribute_name
51+
(#match? @attribute_name "^(Fact|Theory|Test|TestCase|TestCaseSource|TestMethod|DataTestMethod)$")))
52+
name: (identifier) @run @csharp_method_name))))
53+
(#set! tag csharp-test-method)
54+
)
55+
56+
; ===============================
57+
; Test class with namespace
58+
; ===============================
59+
(
60+
(namespace_declaration
61+
name: (_) @csharp_namespace
62+
body: (declaration_list
63+
(class_declaration
64+
(attribute_list
65+
(attribute
66+
name: (_) @class_attribute
67+
(#match? @class_attribute "^(TestFixture|TestClass)$")))
68+
name: (identifier) @run @csharp_class_name)))
69+
(#set! tag csharp-test-class)
70+
)
71+
72+
; =====================================
73+
; Test class with file-scoped namespace
74+
; =====================================
75+
(
76+
(file_scoped_namespace_declaration
77+
name: (_) @csharp_namespace
78+
(class_declaration
79+
(attribute_list
80+
(attribute
81+
name: (_) @class_attribute
82+
(#match? @class_attribute "^(TestFixture|TestClass)$")))
83+
name: (identifier) @run @csharp_class_name))
84+
(#set! tag csharp-test-class)
85+
)
86+
87+
; ==============================
88+
; Test class without namespace
89+
; (anchored to top-level only)
90+
; ==============================
91+
(
92+
(compilation_unit
93+
(class_declaration
94+
(attribute_list
95+
(attribute
96+
name: (_) @class_attribute
97+
(#match? @class_attribute "^(TestFixture|TestClass)$")))
98+
name: (identifier) @run @csharp_class_name))
99+
(#set! tag csharp-test-class)
100+
)

languages/csharp/tasks.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
[
2+
{
3+
"label": "Test ${ZED_CUSTOM_csharp_namespace:}.${ZED_CUSTOM_csharp_class_name:}.${ZED_CUSTOM_csharp_method_name:}",
4+
"command": "dotnet",
5+
"args": [
6+
"test",
7+
"--filter",
8+
"FullyQualifiedName=${ZED_CUSTOM_csharp_namespace:}.${ZED_CUSTOM_csharp_class_name:}.${ZED_CUSTOM_csharp_method_name:}"
9+
],
10+
"cwd": "$ZED_DIRNAME",
11+
"use_new_terminal": false,
12+
"reveal": "always",
13+
"tags": [
14+
"csharp-test-method"
15+
],
16+
"env": {
17+
"CSHARP_TEST_NAMESPACE": "${ZED_CUSTOM_csharp_namespace:}",
18+
"CSHARP_TEST_CLASS": "${ZED_CUSTOM_csharp_class_name:}",
19+
"CSHARP_TEST_METHOD": "${ZED_CUSTOM_csharp_method_name:}",
20+
"CSHARP_TEST_FILE_DIR": "$ZED_DIRNAME"
21+
}
22+
},
23+
{
24+
"label": "Test class ${ZED_CUSTOM_csharp_namespace:}.${ZED_CUSTOM_csharp_class_name:}",
25+
"command": "dotnet",
26+
"args": [
27+
"test",
28+
"--filter",
29+
"FullyQualifiedName~${ZED_CUSTOM_csharp_namespace:}.${ZED_CUSTOM_csharp_class_name:}"
30+
],
31+
"cwd": "$ZED_DIRNAME",
32+
"use_new_terminal": false,
33+
"reveal": "always",
34+
"tags": [
35+
"csharp-test-class"
36+
],
37+
"env": {
38+
"CSHARP_TEST_NAMESPACE": "${ZED_CUSTOM_csharp_namespace:}",
39+
"CSHARP_TEST_CLASS": "${ZED_CUSTOM_csharp_class_name:}",
40+
"CSHARP_TEST_METHOD": "",
41+
"CSHARP_TEST_FILE_DIR": "$ZED_DIRNAME"
42+
}
43+
},
44+
{
45+
"label": "Test project",
46+
"command": "dotnet",
47+
"args": [
48+
"test"
49+
],
50+
"cwd": "$ZED_DIRNAME",
51+
"use_new_terminal": false,
52+
"reveal": "always",
53+
"tags": [
54+
"csharp-test-all"
55+
],
56+
"env": {
57+
"CSHARP_TEST_FILE_DIR": "$ZED_DIRNAME"
58+
}
59+
}
60+
]

0 commit comments

Comments
 (0)