layout, naming and jsDoc options - #19
Open
tinkerer-red wants to merge 1 commit into
Open
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
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.
AI Notice!
This PR was assisted with AI! feel free to close it, I only needed this for personal use anyways. While i can mostly read csharp im not very good at writing it. I merely needed to clean up the bad coding practices of 8 year old gamemaker code being updated. However to alleviate some concerns, i did not pump this out in a few minutes with a one off attempt, i spent several hours walking through each piece ensuring it was doing exactly what was expected. I've reviewed the code to the best of my abilities, and even did my best to refactor where i could to ensure the project stayed as close to your coding practices as possible. So real effort was at least put into this, and ai was merely used to bridge the gap. With that in mind im also aware some people refuse to use LLMs at all and can respect that. <3
Extends the existing formatter. Everything new is an option. Two defaults changed, noted below, easily changed back.
Default changes
width90 to 120. This is the default gamemaker ide window size before a horz scrollbar appears.braceStylewas[JsonIgnore], so it is now readable from.goborc.json.Parser fixes
Not options, these are just cases that failed to parse:
_d.mod,_b.data.mod,{ static: 1, mod: 2, div: 3 }.#regionsitting between the branches of an if/else chain. Common in libraries./*at end of file, which GameMaker reads as comment to EOF.Layout
braceStylegainsNewLineIndentedfor a brace indented with its body.elseOnNewLineputselse,catchandfinallyon their own line, to support the IDE's code editor.stackedConditionssplits a condition already broken across lines into one operand per line, operator leading, each operand parenthesized. Refuses when an operand is itself an unparenthesized&&/||chain, since GM leaves that grouping platform dependent. A chain that fits on one line stays on one line.braceSwitchCasesbraces a case once it holds more than one statement, not counting a trailingbreak, so the IDE can collapse it. Shorter cases stay on the case label's line.inlineShortBlockskeeps a body written on the keyword's line there and adds the braces, soif a return truebecomesif (a) { return true; }. It does not pull a multi line body up, and it pushes one back down if the line runs past width.preserveGluedStatementsleavesvar _i = 0; repeat (_n) { \n...\n _i++}as written, never creates new ones. (this is just something i do a lot and needed it myself, could be removed.)forheaders are always printed flat. GameMaker has trouble compiling a wrapped one, hit it in GMLive and could not work out why specifically. GM will likely need a unit test for this if its discovered why. One occurrence in an 8k file repo, so reverting it is not a major issue.Naming
prefixLocalVariablesrenamesvar xtovar _x. It leaves a name alone when_xalready exists, when a nested function declares the same name, and when the name is used as a shorthand struct key like{ value }. The nested function case is future proofing for if/when GM gets closures. These could probably be allowed but that is more of the core gobo ast than i am comfortable editing.prefixStaticVariablesdoes the same for statics with__. Statics holding a function are skipped, since other files call them by name. Off by default, because namespace like functions are moderately common:function namespace(){ static Foo = "Bar" } \n namespace()Comments and jsDoc
spaceAfterCommentMarkerputs a space after the slashes.wrapCommentsbreaks comments running pastwidth, respecting indent andjsDoc hanging columns as well as descriptions.
normalizeJsDocTagsmaps@descto@description,{int}to{Real}, etc. Mostly because rumors suggest deprecations are coming, to keep these inline with real jsdoc better.sortJsDocTagsorders jsdocs into a standard order to, mostly to keep@selfin a standardized place.alignJsDocDescriptionslines up doc descriptions.wrapJsDocInRegionwraps a docs comment in#region jsDocso the IDE can collapse it. Another one for personal use, but there is an existing feature request for this.addSelfToMethodsadds@selfnaming the enclosing constructor, these are not explicitly required by jsdocs, feather, or gm, its only here to encourage consistency.generateMissingJsDocwrites a skeleton above an undocumented function. Again here for consistency, a find all helps to know what you havent documented.removeCommentedOutCodedeletes comments that parse as code.Rewrites
removeArrayCopyAccessorturnsa[@ i]intoa[i]. Off by default: it is only safe with the Copy on Write game option disabled, where the accessor does nothing. technically this one could also just simply be a find and replace all[@though that captures strings.Implementation notes
The naming and comment options run as passes over the syntax tree, so formatting runs twice. once to settle braces and indentation, then again over the result because the second pass needs braced code, otherwise a
#regioncan land as the body of a bracelessif. Also partially to do with libraries which place#regions between multiple if/else chains.Comments come from the parser's trivia, not a standalone lexer pass. The lexer alone desyncs on template strings, because the parser is what drives its modes.
Tested against a 8k file repo: no parse errors, other then the one workaround mentioned before with GMLive, which is resolved as a hot fix.