Class: JsxRosetta::Backend::ViewComponent::ExpressionTranslator
- Inherits:
-
Object
- Object
- JsxRosetta::Backend::ViewComponent::ExpressionTranslator
- Defined in:
- lib/jsx_rosetta/backend/view_component/expression_translator.rb
Overview
Best-effort, narrowly-scoped JS-to-Ruby translation for the simple expression shapes that JSX components in real codebases use most often: bare identifiers, literals, simple member-expression chains (‘item.label`), and template literals composed of identifier interpolations. Anything more complex (function calls, conditionals, subscripts) returns `nil` from `#translate` so the backend can emit a TODO marker and fall back to the verbatim JS source.
Identifier resolution:
* Names in the active local scope (e.g. loop bindings) translate
to the bare snake_case identifier.
* Names in `prop_names` translate to a `@snake_case` instance
variable.
* Anything else translates to the bare snake_case identifier and
is recorded as unresolved.
Local scopes can be pushed via ‘with_locals` and stack — each entry shadows lower entries.
Defined Under Namespace
Classes: Result
Constant Summary collapse
- IDENTIFIER =
/\A[a-zA-Z_$][a-zA-Z_$0-9]*\z/- STRING_LITERAL =
/\A(['"])(.*)\1\z/m- NUMBER_LITERAL =
/\A-?\d+(\.\d+)?\z/- TEMPLATE_LITERAL =
/\A`(.*)`\z/m- TEMPLATE_INTERPOLATION =
/\$\{([a-zA-Z_$][a-zA-Z_$0-9]*(?:\.[a-zA-Z_$][a-zA-Z_$0-9]*)*)\}/- MEMBER_CHAIN =
/\A(?<root>[a-zA-Z_$][a-zA-Z_$0-9]*)(?<rest>(?:\.[a-zA-Z_$][a-zA-Z_$0-9]*)+)\z/- UNARY =
/\A(?<op>!+|-|\+)(?<operand>.+)\z/m- SIMPLE_LITERALS =
{ "null" => "nil", "undefined" => "nil", "true" => "true", "false" => "false" }.freeze
Instance Method Summary collapse
-
#initialize(prop_names:) ⇒ ExpressionTranslator
constructor
A new instance of ExpressionTranslator.
- #translate(source) ⇒ Object
- #with_locals(names) ⇒ Object
Constructor Details
#initialize(prop_names:) ⇒ ExpressionTranslator
Returns a new instance of ExpressionTranslator.
38 39 40 41 |
# File 'lib/jsx_rosetta/backend/view_component/expression_translator.rb', line 38 def initialize(prop_names:) @prop_names = prop_names.to_set @local_stack = [] end |
Instance Method Details
#translate(source) ⇒ Object
50 51 52 53 54 55 56 |
# File 'lib/jsx_rosetta/backend/view_component/expression_translator.rb', line 50 def translate(source) source = source.strip unresolved = [] ruby = translate_ruby(source, unresolved) ruby && Result.new(ruby: ruby, unresolved_identifiers: unresolved.uniq) end |
#with_locals(names) ⇒ Object
43 44 45 46 47 48 |
# File 'lib/jsx_rosetta/backend/view_component/expression_translator.rb', line 43 def with_locals(names) @local_stack.push(names.compact) yield ensure @local_stack.pop end |