From 5ddf1e4b4d0187c1b99491daa328cae2c16f03f1 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Sun, 21 Jan 2024 01:05:41 -0500 Subject: [PATCH] lsp: flag unnamed variables in IR files (#3325) ![image](https://github.com/open-goal/jak-project/assets/13153231/a020fbf6-65b9-4317-8a9d-5991f2d15e32) --- .../config/jak3/ntsc_v1/var_names.jsonc | 281 ++++-------------- lsp/state/workspace.cpp | 32 +- lsp/state/workspace.h | 4 +- 3 files changed, 91 insertions(+), 226 deletions(-) diff --git a/decompiler/config/jak3/ntsc_v1/var_names.jsonc b/decompiler/config/jak3/ntsc_v1/var_names.jsonc index 98bfe546d5..290dc00ec9 100644 --- a/decompiler/config/jak3/ntsc_v1/var_names.jsonc +++ b/decompiler/config/jak3/ntsc_v1/var_names.jsonc @@ -1,313 +1,162 @@ { "(method 0 inline-array-class)": { - "args": [ - "allocation", - "type-to-make", - "count" - ] + "args": ["allocation", "type-to-make", "count"] }, "(method 9 inline-array-class)": { - "args": [ - "object-to-insert" - ] + "args": ["object-to-insert"] }, "(method 3 inline-array-class)": { - "args": [ - "idx-to-remove" - ] + "args": ["idx-to-remove"] }, "identity": { - "args": [ - "obj" - ] + "args": ["obj"] }, "1/": { - "args": [ - "x" - ] + "args": ["x"] }, "+": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "-": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "*": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "/": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "ash": { - "args": [ - "x", - "shift-amount" - ] + "args": ["x", "shift-amount"] }, "mod": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "rem": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "abs": { - "args": [ - "x" - ] + "args": ["x"] }, "min": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "max": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "logior": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "logand": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "lognor": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "logxor": { - "args": [ - "a", - "b" - ] + "args": ["a", "b"] }, "lognot": { - "args": [ - "x" - ] + "args": ["x"] }, "basic-type?": { - "args": [ - "obj", - "typ" - ] + "args": ["obj", "typ"] }, "type-type?": { - "args": [ - "check-type", - "parent-type" - ] + "args": ["check-type", "parent-type"] }, "type?": { - "args": [ - "obj", - "desired-type" - ] + "args": ["obj", "desired-type"] }, "find-parent-method": { - "args": [ - "typ", - "method-id" - ] + "args": ["typ", "method-id"] }, "ref&": { - "args": [ - "list", - "idx" - ] + "args": ["list", "idx"] }, "ref": { - "args": [ - "list", - "idx" - ] + "args": ["list", "idx"] }, "last": { - "args": [ - "list" - ] + "args": ["list"] }, "member": { - "args": [ - "obj-to-find", - "list" - ] + "args": ["obj-to-find", "list"] }, "nmember": { - "args": [ - "obj-to-find", - "list" - ] + "args": ["obj-to-find", "list"] }, "assoc": { - "args": [ - "key", - "assoc-list" - ] + "args": ["key", "assoc-list"] }, "assoce": { - "args": [ - "key", - "assoc-list" - ] + "args": ["key", "assoc-list"] }, "nassoc": { - "args": [ - "key", - "assoc-list" - ] + "args": ["key", "assoc-list"] }, "nassoce": { - "args": [ - "key", - "assoc-list" - ] + "args": ["key", "assoc-list"] }, "append!": { - "args": [ - "list", - "new-obj" - ] + "args": ["list", "new-obj"] }, "delete!": { - "args": [ - "obj", - "list" - ] + "args": ["obj", "list"] }, "delete-car!": { - "args": [ - "car-to-match", - "list" - ] + "args": ["car-to-match", "list"] }, "insert-cons!": { - "args": [ - "new-obj", - "list" - ] + "args": ["new-obj", "list"] }, "sort": { - "args": [ - "list", - "compare-func" - ] + "args": ["list", "compare-func"] }, "string->symbol-debug": { - "args": [ - "str" - ] + "args": ["str"] }, "symbol->string-debug": { - "args": [ - "sym" - ] + "args": ["sym"] }, "symbol->hash": { - "args": [ - "sym" - ] + "args": ["sym"] }, "mem-copy!": { - "args": [ - "dst", - "src", - "bytes" - ] + "args": ["dst", "src", "bytes"] }, "qmem-copy<-!": { - "args": [ - "dst", - "src", - "qwc" - ] + "args": ["dst", "src", "qwc"] }, "qmem-copy->!": { - "args": [ - "dst", - "src", - "qwc" - ] + "args": ["dst", "src", "qwc"] }, "qmem-clear!": { - "args": [ - "dst", - "qwc" - ] + "args": ["dst", "qwc"] }, "mem-set32!": { - "args": [ - "dst", - "word-count", - "value" - ] + "args": ["dst", "word-count", "value"] }, "mem-or!": { - "args": [ - "dst", - "src", - "bytes" - ] + "args": ["dst", "src", "bytes"] }, "fact": { - "args": [ - "x" - ] + "args": ["x"] }, "print": { - "args": [ - "obj" - ] + "args": ["obj"] }, "printl": { - "args": [ - "obj" - ] + "args": ["obj"] }, "inspect": { - "args": [ - "obj" - ] + "args": ["obj"] }, "mem-print": { - "args": [ - "ptr", - "word-count" - ] + "args": ["ptr", "word-count"] }, "print-tree-bitmask": { - "args": [ - "mask", - "count" - ] + "args": ["mask", "count"] }, "valid?": { "args": [ @@ -319,29 +168,15 @@ ] }, "matrix-transpose!": { - "args": [ - "dst", - "src" - ] + "args": ["dst", "src"] }, "matrix-axis-sin-cos!": { - "args": [ - "dst", - "axis", - "s", - "c" - ] + "args": ["dst", "axis", "s", "c"] }, "vector-rad<-vector-deg/2!": { - "args": [ - "out", - "in" - ] + "args": ["out", "in"] }, "vector-rad<-vector-deg!": { - "args": [ - "out", - "in" - ] + "args": ["out", "in"] } -} \ No newline at end of file +} diff --git a/lsp/state/workspace.cpp b/lsp/state/workspace.cpp index 6447df0e48..e8ac977f57 100644 --- a/lsp/state/workspace.cpp +++ b/lsp/state/workspace.cpp @@ -326,13 +326,19 @@ WorkspaceIRFile::WorkspaceIRFile(const std::string& content) { const auto line_ending = file_util::get_majority_file_line_endings(content); m_lines = str_util::split_string(content, line_ending); + bool in_opengoal_block = false; for (int i = 0; i < m_lines.size(); i++) { const auto& line = m_lines.at(i); if (m_all_types_uri == "") { find_all_types_path(line); } + if (str_util::contains(line, ";;-*-OpenGOAL-Start-*-")) { + in_opengoal_block = true; + } else if (str_util::contains(line, ";;-*-OpenGOAL-End-*-")) { + in_opengoal_block = false; + } find_function_symbol(i, line); - identify_diagnostics(i, line); + identify_diagnostics(i, line, in_opengoal_block); } lg::info("Added new IR file. {} lines with {} symbols and {} diagnostics", m_lines.size(), @@ -400,7 +406,10 @@ void WorkspaceIRFile::find_function_symbol(const uint32_t line_num_zero_based, } void WorkspaceIRFile::identify_diagnostics(const uint32_t line_num_zero_based, - const std::string& line) { + const std::string& line, + const bool in_opengoal_block) { + std::regex unnamed_variables_regex( + "(?:(?:arg\\d+)|(?:f\\d+|at|v[0-1]|a[0-3]|t[0-9]|s[0-7]|k[0-1]|gp|sp|sv|fp|ra)\\-\\d+)"); std::regex info_regex(";; INFO: (.*)"); std::regex warn_regex(";; WARN: (.*)"); std::regex error_regex(";; ERROR: (.*)"); @@ -408,6 +417,24 @@ void WorkspaceIRFile::identify_diagnostics(const uint32_t line_num_zero_based, std::smatch warn_matches; std::smatch error_matches; + if (in_opengoal_block) { + for (auto regex_iterator = + std::sregex_iterator(line.begin(), line.end(), unnamed_variables_regex); + regex_iterator != std::sregex_iterator(); ++regex_iterator) { + std::smatch match = *regex_iterator; + LSPSpec::Diagnostic new_diag; + new_diag.m_severity = LSPSpec::DiagnosticSeverity::Warning; + new_diag.m_message = fmt::format("{} - Unnamed variable", match.str()); + LSPSpec::Range diag_range; + diag_range.m_start = {line_num_zero_based, (u32)match.position(0)}; + diag_range.m_end = {line_num_zero_based, + diag_range.m_start.m_character + (u32)match.length()}; + new_diag.m_range = diag_range; + new_diag.m_source = "OpenGOAL LSP"; + m_diagnostics.push_back(new_diag); + } + } + LSPSpec::Range diag_range; diag_range.m_start = {line_num_zero_based, 0}; diag_range.m_end = {line_num_zero_based, (uint32_t)line.length() - 1}; @@ -440,6 +467,7 @@ void WorkspaceIRFile::identify_diagnostics(const uint32_t line_num_zero_based, return; } } + // Check for a error level warnings if (std::regex_search(line, error_matches, error_regex)) { // NOTE - assumes we can only find 1 function per line diff --git a/lsp/state/workspace.h b/lsp/state/workspace.h index 54825c9d97..997a9bb6c5 100644 --- a/lsp/state/workspace.h +++ b/lsp/state/workspace.h @@ -53,7 +53,9 @@ class WorkspaceIRFile { /// Make any relevant diagnostics on the IR line. /// It's assumed each line in an IR can have atmost one diagnostic, and they are contained to just /// that line! - void identify_diagnostics(const uint32_t line_num_zero_based, const std::string& line); + void identify_diagnostics(const uint32_t line_num_zero_based, + const std::string& line, + const bool in_opengoal_block); }; class WorkspaceAllTypesFile {