Rubygem: Implement multi-backend architecture including Node.js #455
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.
This pull request introduces a flexible backend system for the ruby gem, allowing Herb to use different backends.
Currently we implement a
native(the previous implementation, based on the Ruby C Extension) and anodebackend (that uses the JavaScript packages vianodo). In the future we might want to implement a pure WASM and an FFI backend as well.This architecture enables the Herb gem to leverage the JavaScript-based tools (formatter, linter, printer) while maintaining the fast native backend for core parsing operations. Users can mix backends for maximum flexibility. So you can parse using the
nativebackend and thenformatusing thenodebackend.This pull request introduces a Backend base class with a common interface, similar to how the
@herb-tools/corehandles this and adds newHerb.format,Herb.lint, andHerb.print_nodeAPIs.Example usage:
We now also implement a
#to_sourcemethod on theNodeandParseResultwhich formats by default:You can also print the source as it was parsed using the
IdentityPrinterby passing (format: false). But this requires the ParseResult to be produced using theHerb.parse(source, track_whitespace: true)option.