Class: Kumi::Core::RubyParser::SchemaBuilder

Inherits:
Object
  • Object
show all
Includes:
ErrorReporting, GuardRails, Syntax
Defined in:
lib/kumi/core/ruby_parser/schema_builder.rb

Constant Summary collapse

DSL_METHODS =
i[value trait input ref literal fn select shift roll import].freeze

Constants included from GuardRails

GuardRails::RESERVED

Instance Method Summary collapse

Methods included from ErrorReporting

#inferred_location, #raise_localized_error, #raise_syntax_error, #raise_type_error, #report_enhanced_error, #report_error, #report_semantic_error, #report_syntax_error, #report_type_error

Methods included from GuardRails

included

Constructor Details

#initialize(context) ⇒ SchemaBuilder



13
14
15
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 13

def initialize(context)
  @context = context
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object



105
106
107
108
109
110
111
112
113
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 105

def method_missing(method_name, *args, &)
  if args.empty? && !block_given?
    update_location
    # Create proxy for declaration references (traits/values)
    DeclarationReferenceProxy.new(method_name, @context)
  else
    super
  end
end

Instance Method Details

#fn(fn_name, *args, **kwargs) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 75

def fn(fn_name, *args, **kwargs)
  update_location

  if args.empty? && !kwargs.empty? && @context.imported_names.include?(fn_name)
    mapping = build_import_mapping(kwargs)
    Kumi::Syntax::ImportCall.new(fn_name, mapping, loc: @context.current_location)
  else
    expr_args = args.map { ensure_syntax(_1) }
    Kumi::Syntax::CallExpression.new(fn_name, expr_args, kwargs, loc: @context.current_location)
  end
end

#import(*names, from:) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 60

def import(*names, from:)
  update_location

  unless from.is_a?(Module) || from.is_a?(Class)
    raise_syntax_error(
      "import 'from:' must reference a module or class",
      location: @context.current_location
    )
  end

  import_decl = Kumi::Syntax::ImportDeclaration.new(names, from, loc: @context.current_location)
  @context.imports << import_decl
  @context.imported_names.merge(names)
end

#inputObject



39
40
41
42
43
44
45
46
47
48
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 39

def input(&)
  return InputProxy.new(@context) unless block_given?

  raise_syntax_error("input block already defined", location: @context.current_location) if @context.input_block_defined?
  @context.mark_input_block_defined!

  update_location
  input_builder = InputBuilder.new(@context)
  input_builder.instance_eval(&)
end

#let(name = nil, expr = nil, &blk) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 17

def let(name = nil, expr = nil, &blk)
  update_location
  validate_value_args(name, expr, blk)

  expression = blk ? build_cascade(&blk) : ensure_syntax(expr)
  @context.values << Kumi::Syntax::ValueDeclaration.new(name, expression, inline: true, loc: @context.current_location)
end

#literal(value) ⇒ Object



55
56
57
58
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 55

def literal(value)
  update_location
  Kumi::Syntax::Literal.new(value, loc: @context.current_location)
end

#ref(name) ⇒ Object



50
51
52
53
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 50

def ref(name)
  update_location
  Kumi::Syntax::DeclarationReference.new(name, loc: @context.current_location)
end

#respond_to_missing?(_method_name, _include_private = false) ⇒ Boolean



115
116
117
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 115

def respond_to_missing?(_method_name, _include_private = false)
  true
end

#roll(*args, **kwargs) ⇒ Object



95
96
97
98
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 95

def roll(*args, **kwargs)
  args_expr = args.map { ensure_syntax(_1) }
  Kumi::Syntax::CallExpression.new(:roll, args_expr, kwargs, loc: @context.current_location)
end

#select(condition, value_when_true, value_when_false) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 87

def select(condition, value_when_true, value_when_false)
  update_location
  condition_expr = ensure_syntax(condition)
  true_expr = ensure_syntax(value_when_true)
  false_expr = ensure_syntax(value_when_false)
  Kumi::Syntax::CallExpression.new(:__select__, [condition_expr, true_expr, false_expr], loc: @context.current_location)
end

#shift(*args, **kwargs) ⇒ Object



100
101
102
103
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 100

def shift(*args, **kwargs)
  args_expr = args.map { ensure_syntax(_1) }
  Kumi::Syntax::CallExpression.new(:roll, args_expr, kwargs, loc: @context.current_location)
end

#trait(*args, **kwargs) ⇒ Object



33
34
35
36
37
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 33

def trait(*args, **kwargs)
  update_location
  raise_syntax_error("keyword trait syntax not supported", location: @context.current_location) unless kwargs.empty?
  build_positional_trait(args)
end

#value(name = nil, expr = nil, &blk) ⇒ Object



25
26
27
28
29
30
31
# File 'lib/kumi/core/ruby_parser/schema_builder.rb', line 25

def value(name = nil, expr = nil, &blk)
  update_location
  validate_value_args(name, expr, blk)

  expression = blk ? build_cascade(&blk) : ensure_syntax(expr)
  @context.values << Kumi::Syntax::ValueDeclaration.new(name, expression, loc: @context.current_location)
end