-
Notifications
You must be signed in to change notification settings - Fork 373
Fix JS Programming decompiler: prevent space replacement with variable names #2541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sensei-hacker
wants to merge
14
commits into
iNavFlight:maintenance-9.x
Choose a base branch
from
sensei-hacker:fix/js-programming-space-replacement-bug
base: maintenance-9.x
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Fix JS Programming decompiler: prevent space replacement with variable names #2541
sensei-hacker
wants to merge
14
commits into
iNavFlight:maintenance-9.x
from
sensei-hacker:fix/js-programming-space-replacement-bug
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Augment decompiler to track which Logic Conditions map to which lines in generated JavaScript code. This enables real-time highlighting of active conditions in the JavaScript Programming tab. Key features: - 3-pass mapping algorithm handles simple, compound, and nested conditions - Compound conditions (a && b) correctly map all sub-LCs to same line - Activator chains propagate line numbers to child LCs - Hoisted variables and sticky/timer patterns tracked - Returns lcToLineMapping in decompile() result Part of Feature 1: Active LC Highlighting (Phase 1/5)
Implement real-time status polling and gutter decoration updates in the JavaScript Programming tab to show which Logic Conditions are currently active/true. Key features: - Status polling every 100ms using MSPChainer - updateActiveHighlighting() filters true LCs and applies gutter markers - clearActiveHighlighting() when code is dirty (unsaved changes) - Proper cleanup on tab switch/disconnect - isDirty check prevents highlighting stale code Part of Feature 1: Active LC Highlighting (Phase 2/5)
Implement CSS and Monaco editor configuration for green checkmark gutter markers that indicate active/true Logic Conditions. Key changes: - Add .lc-active-true CSS class with SVG green checkmark icon - Add Monaco gutter margin background styling - Enable glyphMargin: true in Monaco editor options - Set up proper cursor and sizing for gutter decorations Part of Feature 1: Active LC Highlighting (Phase 3/5)
Fix 'Cannot read properties of null' error in updateActiveHighlighting() by adding proper null checks for FC.LOGIC_CONDITIONS_STATUS and FC.LOGIC_CONDITIONS before accessing .get(). This prevents errors during tab initialization when FC data is still loading.
The onChange handler was firing after setValue() during load, causing isDirty to be set to true even after we cleared it. This prevented the highlighting from ever appearing because updateActiveHighlighting() returns early when isDirty is true. Fixed by using setTimeout() to clear isDirty after the setValue() change event has been processed.
Previous approach tried to find LCs by parsing the generated code for /* LC X */ comments, but normal if-statements don't have these comments. New approach: - Track LC index and line content during code generation - After adding boilerplate, search for the tracked lines in final code - Map LC index to actual line numbers in final output This ensures all if-statements and their associated LCs get mapped correctly for the active highlighting feature.
Track what's being searched for and what's being found to diagnose why the LC-to-line mapping is empty.
This will help us diagnose why the green checkmarks aren't appearing by logging: - When the function is called - If isDirty is blocking it - What the LC-to-line mapping is - If FC data is available - Which LCs are TRUE - What lines should be highlighted - If decorations are created
FC.LOGIC_CONDITIONS_STATUS.get() requires a condition index parameter and returns a single value. We need getAll() to get the entire status array. This was causing 'FC data is null' errors and preventing any highlighting from appearing.
This completes the active LC highlighting feature with two major improvements: 1. FALSE condition indicators: Gray hollow circles (○) display when conditions evaluate to FALSE, complementing the existing green checkmarks for TRUE conditions. Mixed states (TRUE and FALSE on same line) show green checkmark. 2. Transpiler-side line tracking: LC-to-line mappings are now generated during transpilation, providing immediate visual feedback after "Transpile" or "Save to FC" without requiring "Load from FC" roundtrip. Correctly adjusts for auto-added import statement offset. Technical changes: - Add lineOffset tracking in codegen to account for prepended import lines - Store currentSourceLine context during statement generation - Return lcToLineMapping in transpiler result - Update tab to use transpiler mapping immediately after transpile/save - Change polling interval from 100ms to 500ms to reduce MSP load (2Hz vs 10Hz) - Reorder checks: verify FC data availability before isDirty state - Clean up excessive debug logging for production readiness Testing: - Verified circles appear on correct lines after transpile - Tested TRUE/FALSE/MIXED states display properly - Confirmed decompiler mapping replaces transpiler mapping on load - Reviewed with inav-code-review agent - all critical issues resolved
Fixes all 6 medium-priority issues identified by qodo-merge bot: 1. Clear stale decorations when loading code from FC 2. Clear mapping/decorations when loading default code 3. Add in-flight guard to prevent overlapping MSP polling requests 4. Remove duplicate intervals before adding new one 5. Improve type safety with Array.isArray() checks for MSP data Code organization improvements: - Extract highlighting logic to new module js/transpiler/lc_highlighting.js - Reduce tab file from 928 to 893 lines (-35 lines) - Create 5 testable, pure functions: categorizeLCsByStatus(), mapLCsToLines(), createMonacoDecorations(), applyDecorations(), clearDecorations() - Better separation of concerns (tab orchestrates, module implements) - Improved code maintainability and testability
**Problem:**
When decompiling logic conditions with activator hoisting and a stored
variable map, all spaces between words were being replaced with custom
variable names (e.g., "const min" became "constmin", comments like
"INAV JavaScript Programming" became "INAVminJavaScriptminProgramming").
**Root Cause:**
In decompiler.js applyCustomVariableNames() at line 293, the code was
storing entire objects from hoistedActivatorVars instead of extracting
the varName string:
const entry = { varName: 'cond1', scopeLcIndex: -1 }
When this object was used in a template literal to build a regex pattern:
`\\b${entry}\\b` → `\\b[object Object]\\b`
In regex, `[object Object]` is a CHARACTER CLASS that matches any single
character from the set: {o,b,j,e,c,t,space,O}. This caused the regex
pattern `\\b[object Object]\\b` to match spaces between word boundaries,
replacing them with the custom variable name.
**Fix:**
Changed line 293-294 to extract the .varName property:
- Before: lcIndexToGeneratedName.set(lcIndex, generatedName);
- After: lcIndexToGeneratedName.set(lcIndex, entry.varName);
This ensures the regex replacement uses the actual variable name string
instead of "[object Object]" character class.
**Files Changed:**
- js/transpiler/transpiler/decompiler.js
**Testing:**
Verified with test cases showing the fix prevents space replacement in
both code and comments.
Contributor
ⓘ Your approaching your monthly quota for Qodo. Upgrade your plan PR Compliance Guide 🔍All compliance sections have been disabled in the configurations. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
User description
Summary
Fixes a bug in the JavaScript Programming decompiler where spaces between words were being replaced with custom variable names, resulting in corrupted output like "constmin" instead of "const min" and "INAVminJavaScript" instead of "INAV JavaScript".
This PR depends on #2539 and should be merged after 2539
Root Cause
In
decompiler.jsat line 293, theapplyCustomVariableNames()function was storing entire objects fromhoistedActivatorVarsinstead of extracting thevarNamestring property:When the object was used in a template literal to build a regex pattern, it converted to the string
"[object Object]", which created a regex character class[object Object]matching any character from the set{o,b,j,e,c,t,space,O}. This caused the pattern\b[object Object]\bto match spaces between word boundaries.Changes
Modified
inav-configurator/js/transpiler/transpiler/decompiler.jslines 293-294:This ensures the regex replacement uses the actual variable name string instead of the
[object Object]character class.Testing
✅ Tested with problematic logic conditions via browser console
✅ Verified no "constmin" corruption
✅ Verified no "AccessminAPI" corruption
✅ Verified proper spacing in comments: "// INAV JavaScript Programming"
✅ Verified proper spacing in code: "const min = ..."
✅ All test cases passed
Tested using the running configurator instance by:
Code Review
Reviewed with inav-code-review agent - APPROVED with no critical or important issues found.
The fix:
varNamestring property from entry objectsentryinstead ofgeneratedName)Related
Addresses user-reported issue where decompiled code showed corrupted spacing.
PR Type
Enhancement, Bug fix
Description
Implement real-time active Logic Condition highlighting in Monaco editor
Fix bug in decompiler where spaces were replaced with variable names
varNamestring property instead of storing entire object[object Object]character classAdd line offset tracking for accurate source-to-editor line number mapping
Diagram Walkthrough
File Walkthrough
monaco_loader.js
Enable Monaco gutter margin for decorationsjs/transpiler/editor/monaco_loader.js
glyphMargin:truelc_highlighting.js
New module for Logic Condition highlighting utilitiesjs/transpiler/lc_highlighting.js
categorizeLCsByStatus()separates enabled LCs into TRUE/FALSE arraysmapLCsToLines()maps LC indices to editor lines with combined status(true/false/mixed)
createMonacoDecorations()generates gutter marker decorations withhover messages
applyDecorations()andclearDecorations()manage decoration lifecyclejavascript_programming.js
Implement active LC highlighting with status pollingtabs/javascript_programming.js
lcToLineMapping,activeDecorations, andstatusChainerpropertiesfor highlighting state
intervalandLCHighlightingmodulessetupActiveHighlighting()to create 500ms polling interval for LCstatus updates
updateActiveHighlighting()to categorize LCs, map to lines, andapply decorations
clearActiveHighlighting()to remove all gutter decorationsisDirtyrace condition by usingsetTimeout()aftersetValue()calls
cleanup()methodcodegen.js
Add LC-to-line mapping tracking in code generationjs/transpiler/transpiler/codegen.js
lcToLineMappingobject to track LC index to source line mappingcurrentSourceLineandlineOffsetproperties for line trackinggenerateStatement()using AST location infopushLogicCommand()when LC is createdlineOffsetfrom Acorn line numbers to match Monaco editorline numbers
index.js
Pass line offset and mapping to transpiler resultjs/transpiler/transpiler/index.js
lineOffsetfrom transpiler to codegen for accurate line numbertracking
lcToLineMappingfrom transpile result for highlighting supportjavascript_programming.html
Add CSS styling for active LC gutter markerstabs/javascript_programming.html
.lc-active-trueCSS class with green checkmark SVG icon for TRUEconditions
.lc-active-falseCSS class with gray hollow circle SVG icon forFALSE conditions
decompiler.js
Fix space replacement bug and add LC-to-line mappingjs/transpiler/transpiler/decompiler.js
entry.varNameinstead of storing entire object inlcIndexToGeneratedNamemaplcToLineMappingand_tempLcLinesproperties for tracking LC linepositions
decompileTree()finalizeLcLineMapping()method with 5-pass algorithm to map LCs tofinal code lines
relationships, and compound conditions
lcToLineMappingin decompile result