Skip to content

V0.2.2 - Better Diagnostics #5

Merged
DaemonF0rge merged 9 commits intomainfrom
Next
Mar 14, 2026
Merged

V0.2.2 - Better Diagnostics #5
DaemonF0rge merged 9 commits intomainfrom
Next

Conversation

@DaemonF0rge
Copy link
Copy Markdown

This pull request introduces several improvements to the Enfusion Script language server, focusing on enhanced parsing and diagnostics, better handling of file events, and support for additional language features. The most significant changes include improved detection of symbols and types within function bodies for more accurate diagnostics, robust handling of file closures and deletions, and parser enhancements for variable declarations and enum member separation.

Parser and Symbol Analysis Improvements:

  • Added tracking of type references (bodyTypeRefs) and standalone identifier references (bodyIdentifierRefs) within function bodies in the AST, enabling more precise unknown-symbol diagnostics and cross-module checks. [1] [2] [3] [4] [5] [6] [7] [8]
  • Enhanced parser logic to correctly handle comma-separated variable declarations (e.g., float x, y, z;), including initializer expressions, and to avoid false positives inside function call arguments. [1] [2] [3]

Diagnostics and File Event Handling:

  • Improved handling of file closure and deletion events: when a file is closed and no longer exists on disk, its symbols are immediately removed from the index and diagnostics are cleared, preventing duplicate warnings. [1] [2]
  • When re-indexing or revalidating open files, diagnostics are now properly cleared for files that are no longer part of the workspace, ensuring users do not see stale warnings. [1] [2]

Parser Robustness and Language Support:

  • Added support for the thread keyword in the lexer’s keyword set, improving language coverage.
  • Updated enum member parsing to flag and recover from semicolon-separated members, enforcing correct comma separation per language rules.

Miscellaneous:

  • Bumped extension version to 0.2.2 in package.json.
  • Added debug output for server startup and diagnostics in debug-output.txt.

Add detection and diagnostics for static call targets like ClassName.Method() across modules. Parser: add bodyTypeRefs to FunctionDeclNode and record uppercase Identifier '.' patterns (excluding chained property accesses) as TypeNode references. Analyzer: add checkBodyTypeRef to emit an error when a referenced type is defined in a higher-numbered module and wire checks into function and top-level node processing. Tests: add unit tests covering higher/same/lower-module calls, chained property access, and uppercase-variable cases. Also add /docs to .gitignore.
Enhance parsing and diagnostics: add BodyIdentifierRef to capture standalone identifiers used in function bodies and wire a checkBodyIdentifierRefs routine into the Analyzer to produce warnings for unknown identifiers (with built-in, primitive, enum, local, class, function and index lookups to avoid false positives). Improve local-variable parsing to handle comma-separated declarations via a commaChain token (detects multi-variable declarations like `int a, b, c;` and resets the chain at statement/brace boundaries and on non-declaration triggers). Add enum member separator validation and diagnostic for semicolons between members. Adjust LSP behavior to clear diagnostics for non-workspace files on re-index/revalidate and remove stale index entries immediately when a closed file no longer exists on disk. Include many unit tests exercising the new behaviors, add a sample test file, and add a small debug-output log; also remove an old test fixture file.
Treat '(' as a delimiter when recognizing local variable declarations so constructor-style declarations like `ScriptInputUserData serializer();` are detected as locals (server/src/analysis/ast/parser.ts). Add a curated list of native DayZ engine constants and include them in the analyzer's built-in symbol set to avoid reporting them as unknown (server/src/analysis/project/graph.ts). Add a unit test covering the constructor-style local detection (test/parser.test.ts) and update debug output (debug-output.txt). These changes improve parsing accuracy and reduce false unknown-symbol diagnostics.
Add numerous native engine constants to NATIVE_ENGINE_CONSTANTS (additional UA* UI/input constants for navigation, gestures, quickbar and action categories, UI radial, dialog/exclamation type, and damage types such as DT_FIRE_ARM, DT_EXPLOSION, DT_CLOSE_COMBAT). Update debug-output.txt with extra runDiagnostics/checkUnknownSymbols entries for various Factions scripts. These changes help the analyzer recognize newer engine symbols and reduce unknown-symbol diagnostics.
Include 'thread' in the keywords set in server/src/analysis/lexer/rules.ts (under modifiers) so the lexer recognizes 'thread' as a language keyword.
Preserve the raw pre-declaration substring and detect any newlines that were removed by trimEnd so declarations that start on their own line aren't misclassified. The code now computes preDeclPos, separates trimmed text from trailing whitespace, checks for a newline in the trailing portion, and uses that to decide whether to skip (declaration) — fixing cases where indentation or trailing comments caused the previous trim-based check to miss the newline.
Add access modifier validation and harden local-variable parsing. Introduces Analyzer.checkAccessModifierViolations (server/src/analysis/project/graph.ts) to report private/protected member access violations for qualified and unqualified accesses using class hierarchy lookup. Parser improvements (server/src/analysis/ast/parser.ts) track parenthesis depth and preserve comma-chain types across '=' and ',' while only resetting on statement boundaries to avoid falsely detecting call arguments as locals. Tests updated/added (test/*) to cover modded-method resolution, protected/private access cases, and several comma-chain parsing edge cases; test_enscript.c also extended with class scenarios exercising access rules.
When collecting class declarations by name, deduplicate entries using the source URI combined with the node start position (line:character) instead of URI alone so distinct declarations in the same file (e.g. original + modded class declarations) are preserved. Renamed the seen set and build a composite key from _sourceUri and node.start to avoid collapsing separate class nodes. Added tests verifying that a modded method declared in the same file is found and that same-file original+modded declarations do not produce duplicate completions or duplicate type-mismatch diagnostics.
Update package.json version from 0.2.1 to 0.2.2 to mark a new patch release. No other changes included.
Copilot AI review requested due to automatic review settings March 14, 2026 19:56
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Enfusion Script language server to improve parsing fidelity and diagnostic accuracy, especially for symbol/type usage within function bodies and for handling workspace file lifecycle events.

Changes:

  • Extended the parser AST to track bodyTypeRefs (static access targets) and bodyIdentifierRefs (standalone identifiers) inside function bodies, enabling new/stronger unknown-symbol and cross-module checks.
  • Improved local variable detection in function bodies (comma-separated declarations, constructor-style locals) and added enum-member separator diagnostics (semicolon vs comma).
  • Hardened diagnostics behavior around file close/delete and workspace revalidation to avoid stale/duplicate diagnostics.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated no comments.

Show a summary per file
File Description
server/src/analysis/ast/parser.ts Adds function-body reference tracking and improves local/enum parsing behavior.
server/src/analysis/project/graph.ts Uses new body refs for unknown-symbol and cross-module checks; adds access-modifier diagnostics.
server/src/lsp/handlers/diagnostics.ts Cleans up index + diagnostics on close when the backing file no longer exists.
server/src/index.ts Clears diagnostics for open docs that are no longer workspace files during reindex/revalidate.
server/src/analysis/lexer/rules.ts Adds thread to keyword set.
test/parser.test.ts Adds broad parser coverage for comma-chain locals, enum separators, and bodyIdentifierRefs behavior.
test/module-visibility.test.ts Adds cross-module diagnostics coverage for static call targets.
test/features.test.ts Adds regression coverage for diagnostics + modded class resolution + access checks.
test/test_enscript.c Removes old test fixture file from root.
test/3_game/test_enscript.c Adds a larger script fixture under module folder.
package.json Bumps extension version to 0.2.2.
debug-output.txt Adds captured debug output from a local run.
.gitignore Adds /docs ignore entry.

Review notes (issues found):

  • server/src/analysis/project/graph.ts:
    • checkBodyIdentifierRefs does a full docCache scan per identifier ref (for (const [, fileAst] of this.docCache) { ... } around lines ~7146–7167). This is redundant given the existing fast indexes (globalSymbolIndex, classIndex, enumIndex, functionIndex) and can become a major performance bottleneck once the 500-file threshold is reached. Consider removing the scan and relying on the indexes, or building a single Set of top-level names once per run and querying that.
    • NATIVE_ENGINE_CONSTANTS contains multiple duplicates (e.g., UAGear, UAUIGesturesOpen, UAUIQuickbarToggle, DT_CUSTOM in the ~54–93 region). Duplicates won’t break correctness (they’re later put into a Set), but they add maintenance noise—dedupe the list to keep it authoritative.
  • server/src/analysis/ast/parser.ts:
    • The “STANDALONE IDENTIFIER REFERENCE DETECTION” comment claims identifiers are excluded when “followed by '.' (static access…)”, but the implementation still records the identifier when t.value === '.' (see the block around ~964–987). Either adjust the condition to match the comment, or update the comment to reflect the actual behavior (especially since tests expect some dot-prefixed cases like SomeClass to be captured).
  • debug-output.txt:
    • This looks like a local runtime log (timestamps, local drive paths). Keeping it in-repo can create churn and isn’t stable test data; consider removing it from version control and adding it to .gitignore if it’s meant for local troubleshooting only.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@DaemonF0rge DaemonF0rge merged commit da85a79 into main Mar 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants