Add Go implementation using latest jsonic, follow ini/csv patterns#1
Conversation
- Add Go JSONC parser in go/ directory using github.com/jsonicjs/jsonic/go from main branch (v0.1.16 pseudo-version) - Follow ini/csv plugin pattern: custom value keyword matcher, programmatic rule modification for trailing commas, embedded grammar for ZZ handling - Go module at github.com/jsonicjs/jsonc/go with Go 1.24.7 - Comprehensive Go test suite (16 tests) covering comments, strings, numbers, keywords, objects, arrays, trailing commas, error cases - Add jsonc-grammar.jsonic and embed-grammar.js following csv/ini pattern - Add Makefile with dual TS/Go build targets (build, test, clean, publish-go) - Update GitHub Actions workflow for both Node.js and Go CI - Update README with diataxis documentation approach (tutorials, reference, explanation) for both TypeScript and Go - Update copyright year to 2025 https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c9428ca7c9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Number: &jsonic.NumberOptions{ | ||
| Lex: boolPtr(true), | ||
| Hex: boolPtr(false), | ||
| Oct: boolPtr(false), | ||
| Bin: boolPtr(false), | ||
| Exclude: func(s string) bool { |
There was a problem hiding this comment.
Disable numeric separators in JSONC parser options
MakeJsonic disables hex/octal/binary numbers but leaves NumberOptions.Sep at the jsonic default ("_"), so inputs like 1_000 are still accepted. JSONC only allows JSON numeric syntax, so this silently accepts non-JSONC literals and can produce cross-language inconsistencies with the TypeScript plugin, which explicitly disables separators.
Useful? React with 👍 / 👎.
| String: &jsonic.StringOptions{ | ||
| Chars: `"`, | ||
| AllowUnknown: boolPtr(false), |
There was a problem hiding this comment.
Turn off multiline backtick strings for JSONC mode
The string configuration sets Chars to " but does not set MultiChars, so jsonic's default multiline delimiter (backtick) remains enabled. This means inputs like `foo` can parse successfully even though JSONC only permits double-quoted JSON strings, causing the Go implementation to accept syntax outside the documented format.
Useful? React with 👍 / 👎.
| Comment: &jsonic.CommentOptions{ | ||
| Lex: &commentLex, | ||
| }, |
There was a problem hiding this comment.
Restrict comment definitions to JSONC comment markers
Only Comment.Lex is configured, so the default jsonic comment definitions are kept, including # line comments. As a result, # ... is parsed as a valid comment in JSONC mode even though JSONC supports only // and /* */, which broadens accepted syntax beyond the plugin's stated behavior.
Useful? React with 👍 / 👎.
- Move TS source to src/ with tsconfig outputting to dist/ (matching ini/csv) - Move parser options into jsonc-grammar.jsonic (text, number, string, map, lex, rule options now in grammar; runtime options like comment.lex and number.exclude remain in code) - Switch from @jsonic/jsonic-next to jsonic (>=2.22.2) matching ini/csv - Switch from jest to node:test matching ini/csv test runner - Remove spurious old files: jsonc.min.js, jsonc.js, jsonc.js.map, jsonc.d.ts, jest.config.js, tsconfig.json (root), compiled test artifacts - Update package.json: main points to dist/jsonc.js, files includes src+dist, build uses tsc -p src, modernized devDependencies - Update .gitignore to include dist/ and *.tsbuildinfo (matching ini/csv) - Use jsonic.grammar() to apply grammar options in TS plugin - All 15 TS tests and 16 Go tests pass https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
- Remove redundant jsonic.rule('val', ...) from TS plugin; the grammar's
inject: { append: true } already handles the ZZ alt via jsonic.grammar()
- Remove unused RuleSpec import
- Move number.exclude note into grammar comment (regex must stay in code
as jsonic grammar does not support @/regexp/ syntax)
- Grammar file now documents all JSONC options; only runtime-dependent
options (comment.lex, rule.include) and JS-typed options (number.exclude
regex) remain in code
https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
- Grammar now defines number.exclude via @exclude-leading-dot funcref - Go plugin applies grammar options+rules via j.Grammar() with GrammarSpec.OptionsMap and GrammarSpec.Ref for funcref resolution - TS uses jsonic.grammar() for static options; number.exclude set via jsonic.options() as TS grammar resolution differs from Go - Remove unused mapToGrammarSpec helper (plugin constructs GrammarSpec directly) - Remaining jsonic.options() calls: comment.lex and rule.include (runtime-dependent on plugin arguments, cannot be static grammar) https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
regexp.MatchString is already func(string) bool, matching the type MapToOptions expects for number.Exclude. https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
MapToOptions handles: number, string, comment, map, value, rule. MapToOptions does NOT handle: text, lex (jsonic core limitation). Go Make() now only sets text.lex, lex.empty, and comment.lex (runtime). All other static options are applied from the grammar via Grammar() with OptionsMap and @funcref resolution. j.Exclude() is called after Grammar() since Grammar replaces sub-structs. https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
Grammar now uses @/^\./ syntax for number.exclude. resolveFuncRefs resolves this to RegExp in TS (matching number.exclude type) and *regexp.Regexp in Go. Go pre-resolves to regexp.MatchString (func(string) bool) since MapToOptions requires that type. TS number.exclude no longer set in code — fully from grammar. Only comment.lex and rule.include remain in code (runtime-dependent). https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
MakeJsonic() now only passes lex.empty to Make() (stored on Jsonic
struct, cannot be set later). All other options are applied in the
plugin via Grammar() OptionsMap and SetOptions(), matching the TS
pattern of jsonic.grammar(grammar) + jsonic.options({...}).
https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
Go plugin now follows the same pattern as TS:
parsed = jsonic.Parse(grammarText)
j.Grammar(&GrammarSpec{OptionsMap: ..., Rule: ...})
j.SetOptions(Options{...}) // runtime options
j.Exclude(...)
Removed ~150 lines: convertAlts, convertAltList, convertAlt helpers
and manual rule map iteration. The single val rule is constructed
directly as a typed GrammarAltListSpec.
https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
jsonic Go now keeps value keyword matching active when text.lex=false, matching TS behavior. Removes the custom jsonc-value matcher that was only needed to work around the old jsonic limitation. Also uses Rule.Exclude via SetOptions instead of the now-unexported j.Exclude() method. https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
Go: j.GrammarText(grammarText) applies grammar options directly from text, replacing the manual parse+extract+pre-resolve pattern. Val ZZ rule still via Grammar() since GrammarText handles options only. TS: collapsed to one-liner jsonic.grammar(Jsonic.make()(grammarText)) (TS jsonic does not have grammarText yet). Removed regexp import — number.exclude @/regexp/ is now resolved by GrammarText's ResolveFuncRefs, and the val rule uses typed structs. https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
GrammarText now handles both options and rules from grammar text. SetOptions merges properly preserving GrammarText settings. Go plugin now mirrors TS: GrammarText(grammarText) + SetOptions for runtime options. Note: Rule.Exclude via SetOptions/Make breaks string matching in this jsonic version - pending jsonic fix. https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
Rule.Exclude still breaks string matching — same 2 test failures. https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
GrammarText + Rule.Exclude now works correctly. Go plugin uses GrammarText + SetOptions mirroring TS structure. 16 Go tests, 15 TS tests pass. https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
Renamed jsoncPlugin to Jsonc (exported, matches TS function name).
Plugin body follows same order as TS: compute runtime values,
GrammarText, SetOptions. Removed optionsToMap, boolPtr helpers.
MakeJsonic now just Make() + Use(Jsonc, {...}).
https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
Go now exports only the Jsonc plugin function, matching TS which exports only Jsonc and JsoncOptions. Users call jsonic.Make().Use(Jsonc) directly. Removed Parse, MakeJsonic, JsoncOptions, optionsToMap, boolOpt helpers. Tests updated to use makeJsonc test helper with jsonic.Make(). https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
- Trailing comma alts now in grammar (pair/elem close with inject prepend), removing programmatic PrependClose workaround - Jsonc returns error instead of panicking - No longer implements Plugin interface (returns error) - Grammar tags trailing comma alts with g:comma (not jsonc,comma) so TS include:'jsonc,json' correctly excludes them by default https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
Plugin type now returns error. Jsonc matches the Plugin signature and can be passed directly to j.Use(). Tests updated accordingly. https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj
from main branch (v0.1.16 pseudo-version)
rule modification for trailing commas, embedded grammar for ZZ handling
keywords, objects, arrays, trailing commas, error cases
explanation) for both TypeScript and Go
https://claude.ai/code/session_01SJsPRf7HKzrBUNXYBSd7Gj