Repository navigation
Escape keyword-named bindings in the JavaScript generator [patch] - #462
Open
matt-edmondson wants to merge 2 commits into
Open
matt-edmondson wants to merge 2 commits into
matt-edmondson wants to merge 2 commits into
Conversation
JavaScript wrote keyword-named parameters, locals, functions, classes and top-level names verbatim, so `total(in, typeof)` or `function return(...)` failed to parse. These bindings now get an underscore (`in_`, `return_`) at the declaration and at every use. Members keep their names. JavaScript reads a keyword after a `.` and as a field, accessor or method name, so `holder.default` and `this.switch()` stay as written. A new `EscapesMemberNames` hook on LanguageGeneratorBase tells EscapeReference to escape only a reference's leading segment, and SpellCallee to leave a call with a receiver alone and to count only free functions. Part of #106. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017vfJW3ect9msbMq1zFsRLD
Keeps ReservedWordIdentifierTests.cs untouched, so this branch and the Go keyword PR (#445) merge in either order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017vfJW3ect9msbMq1zFsRLD
|
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
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.



Part of #106. JavaScript was the last target the issue's triage listed as still writing keyword-named identifiers verbatim.
What was wrong
The JavaScript generator had no reserved-word set, so a keyword-named parameter, local, function, class or top-level name came out as written. For example,
total(in, typeof),function return(with)andlet new = ...all fail to parse (SyntaxError: Unexpected token 'in').Design decision
The last triage comment on #106 left this open: JavaScript accepts a keyword as a member name after a
.(holder.default,this.switch()), and as a field, accessor or method name. The sharedEscapeReferenceandSpellCallee, however, escaped every segment. This PR takes the option that renames as little as possible:let/const, and enum and alias constants.extends,newand an alias's value go throughEscapeReferencetoo.Changes
LanguageGeneratorBase: a newprotected virtual bool EscapesMemberNames => true. When a target returns false:EscapeReferenceescapes only a reference's leading segment.SpellCalleecounts only free functions, because methods weren't escaped.Every other generator keeps the default, so their output is unchanged.
JavaScriptGenerator:ReservedWords: the reserved words, the strict-mode future reserved words, the literals, andarguments/eval, which strict code can't bind. Class bodies and modules are strict.IsReceiverWord(this,super,true,false,null) andEscapesMemberNames => false.EscapeIdentifier.Tests
New file
Coder.Test/Languages/JavaScriptReservedWordIdentifierTests.cs. The tests live in their own file so this PR and #445 (Go), which both extend the shared test file, merge in either order. I checked withgit merge-treethat this branch merges cleanly with both #445 and #446.JavaScript_KeywordNamesRunAndResolveruns the generated script under node with a driver. The driver reads backholder.class,holder.default, aget delete()accessor,total(in_, typeof_)with localslet_/new_,this.switch()called from another method,Flag.null,return_(…)called fromrelay(), a top-levelvar_, andclass Child extends import_.JavaScript_ReferenceEscapesTheBindingButNotTheMemberchecks the text:this.class,this.switch()andget delete()are unescaped, and there is nothis_,class_,switch_ornull_.With the two generator files reverted, both tests fail: node reports
SyntaxError: Unexpected token 'in', and the text assertion fails. With the change, the full suite passes: 1666/1666 on net10.0, Linux.Left open on #106
From the earlier triage: in C, the function-pointer member
(*name)of an interface's vtable struct still isn't escaped.Generated by Claude Code