Module: Kumi::Frontends::Ruby
- Defined in:
- lib/kumi/frontends/ruby.rb
Class Method Summary collapse
- .load(path:, inputs: {}) ⇒ Object
- .parse(src, path) ⇒ Object
-
.translate_uppercase_reference(error, path) ⇒ Object
A bare reference to a declaration whose name starts with an uppercase letter (e.g. ‘let :W` then `W`) is read by Ruby as a constant, not a method, so the DSL’s method_missing never sees it and Ruby raises a raw ‘uninitialized constant …::W`.
Class Method Details
.load(path:, inputs: {}) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/kumi/frontends/ruby.rb', line 10 def load(path:, inputs: {}) src = File.read(path) begin [parse(src, path), inputs] rescue StandardError => e # Render the same `file:line: message` + code-frame the text frontend # produces. Located errors (SyntaxError/SemanticError) carry a Location; # anything else degrades to a clean `file: message` with no frame. raise StandardError, SourceFrame.render(e, src: src, file_label: path) end end |
.parse(src, path) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/kumi/frontends/ruby.rb', line 23 def parse(src, path) mod = Module.new mod.extend(Kumi::Schema) begin mod.module_eval(src, path) rescue NameError => e raise translate_uppercase_reference(e, path) || e end # Extract just the syntax tree AST (same as Text frontend) if mod.const_defined?(:GoldenSchema) golden = mod.const_get(:GoldenSchema) golden.build if golden.respond_to?(:build) golden.__syntax_tree__ elsif mod.__syntax_tree__ mod.__syntax_tree__ else raise "No schema AST found. Make sure the .rb file calls 'schema do...end'" end end |
.translate_uppercase_reference(error, path) ⇒ Object
A bare reference to a declaration whose name starts with an uppercase letter (e.g. ‘let :W` then `W`) is read by Ruby as a constant, not a method, so the DSL’s method_missing never sees it and Ruby raises a raw ‘uninitialized constant …::W`. The text frontend accepts such names, so this is a Ruby-only limitation — turn it into a clear, located error instead of leaking Ruby’s anonymous-module constant message.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/kumi/frontends/ruby.rb', line 50 def translate_uppercase_reference(error, path) const = error.name return nil unless const&.to_s&.match?(/\A[A-Z]/) return nil unless error..include?("uninitialized constant") frame = error.backtrace_locations&.find { |f| f.path == path } location = frame && Kumi::Syntax::Location.new(file: frame.path, line: frame.lineno, column: 0) Kumi::Core::Errors::SyntaxError.new( "`#{const}` looks like a reference to a declaration, but names starting " \ "with an uppercase letter can't be referenced bare in the Ruby DSL " \ "(Ruby reads them as constants). Use `ref(:#{const})`, or rename the " \ "declaration to start with a lowercase letter.", location ) end |