summaryrefslogtreecommitdiff
path: root/src/server/diagnostics.odin
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/diagnostics.odin')
-rw-r--r--src/server/diagnostics.odin126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/server/diagnostics.odin b/src/server/diagnostics.odin
new file mode 100644
index 0000000..411ffbc
--- /dev/null
+++ b/src/server/diagnostics.odin
@@ -0,0 +1,126 @@
+package server
+
+import "core:log"
+import "core:slice"
+import "core:strings"
+import "src:common"
+
+DiagnosticType :: enum {
+ Syntax,
+ Unused,
+ Check,
+}
+
+diagnostics: [DiagnosticType]map[string][dynamic]Diagnostic
+
+add_diagnostics :: proc(type: DiagnosticType, uri: string, diagnostic: Diagnostic) {
+ diagnostic_type := &diagnostics[type]
+
+ if diagnostic_type == nil {
+ log.errorf("Diagnostic type did not exist: %v", type)
+ return
+ }
+
+ uri := uri
+
+ when ODIN_OS == .Windows {
+ uri = strings.to_lower(uri, context.temp_allocator)
+ }
+
+ diagnostic_array := &diagnostic_type[uri]
+
+ if diagnostic_array == nil {
+ diagnostic_type[strings.clone(uri)] = make([dynamic]Diagnostic)
+ diagnostic_array = &diagnostic_type[uri]
+ }
+
+ diagnostic := diagnostic
+
+ diagnostic.message = strings.clone(diagnostic.message)
+ diagnostic.code = strings.clone(diagnostic.code)
+
+ append(diagnostic_array, diagnostic)
+}
+
+remove_diagnostics :: proc(type: DiagnosticType, uri: string) {
+ diagnostic_type := &diagnostics[type]
+
+ if diagnostic_type == nil {
+ log.errorf("Diagnostic type did not exist: %v", type)
+ return
+ }
+
+ uri := uri
+
+ when ODIN_OS == .Windows {
+ uri = strings.to_lower(uri, context.temp_allocator)
+ }
+
+ diagnostic_array := &diagnostic_type[uri]
+
+ if diagnostic_array == nil {
+ return
+ }
+
+ for diagnostic in diagnostic_array {
+ delete(diagnostic.message)
+ delete(diagnostic.code)
+ }
+
+ clear(diagnostic_array)
+}
+
+clear_diagnostics :: proc(type: DiagnosticType) {
+ diagnostic_type := &diagnostics[type]
+
+ if diagnostic_type == nil {
+ log.errorf("Diagnostic type did not exist: %v", type)
+ return
+ }
+
+ for _, &diagnostic_array in diagnostic_type {
+ for diagnostic in diagnostic_array {
+ delete(diagnostic.message)
+ delete(diagnostic.code)
+ }
+ clear(&diagnostic_array)
+ }
+}
+
+push_diagnostics :: proc(writer: ^Writer) {
+ merged_diagnostics := make(map[string][dynamic]Diagnostic, context.temp_allocator)
+
+ for diagnostic_type in diagnostics {
+ for k, v in diagnostic_type {
+ diagnostic_array := &merged_diagnostics[k]
+
+ if diagnostic_array == nil {
+ merged_diagnostics[k] = make([dynamic]Diagnostic, context.temp_allocator)
+ diagnostic_array = &merged_diagnostics[k]
+ }
+
+ append(diagnostic_array, ..v[:])
+ }
+ }
+
+ for k, v in merged_diagnostics {
+ //Find the unique diagnostics, since some poor profile settings make the checker check the same file multiple times
+ unique := slice.unique(v[:])
+
+ params := NotificationPublishDiagnosticsParams {
+ uri = k,
+ diagnostics = unique,
+ }
+
+ notifaction := Notification {
+ jsonrpc = "2.0",
+ method = "textDocument/publishDiagnostics",
+ params = params,
+ }
+
+ if writer != nil {
+ send_notification(notifaction, writer)
+ }
+ }
+
+}