Class: Rjq::ModuleLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/rjq/module_loader.rb

Defined Under Namespace

Classes: Result

Constant Summary collapse

MAX_DEPTH =
64

Instance Method Summary collapse

Constructor Details

#initialize(resolver, allow_comments: true, max_filter_depth: Parser::DEFAULT_MAX_FILTER_DEPTH) ⇒ ModuleLoader

Returns a new instance of ModuleLoader.



8
9
10
11
12
13
# File 'lib/rjq/module_loader.rb', line 8

def initialize(resolver, allow_comments: true, max_filter_depth: Parser::DEFAULT_MAX_FILTER_DEPTH)
  @resolver = resolver
  @cache = {}
  @allow_comments = allow_comments
  @max_filter_depth = max_filter_depth
end

Instance Method Details

#load(program, source_path: nil, stack: []) ⇒ Object

Raises:



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rjq/module_loader.rb', line 15

def load(program, source_path: nil, stack: [])
  raise CompileError, "module import depth exceeds #{MAX_DEPTH}" if stack.length >= MAX_DEPTH
  program.directives.select { |directive| directive.type == :module }.each do |directive|
    ConstantEvaluator.evaluate_object(directive.)
  end

  definitions = []
  variables = {}
   = @resolver..dup
  program.directives.each do |directive|
    next if directive.type == :module

    options = directive. ? ConstantEvaluator.evaluate_object(directive.) : {}
    data = directive.alias_name&.start_with?('$') || false
    source = @resolver.resolve(directive.name, from: source_path, metadata: options, data: data)
    raise CompileError, "circular module import: #{directive.name}" if stack.include?(source.path)

    if data
      value = JSON::Parser.parse_one(source.content)
      name = directive.alias_name.delete_prefix('$')
      variables[name] = value
      definitions << AST::FunctionDefinition.new("#{name}::#{name}", [], AST::Literal.new(value))
      [directive.name] ||= 
      next
    end

    loaded, parsed = @cache[source.path]
    unless loaded
      parsed = Parser.new(source.content, source_name: source.path, allow_comments: @allow_comments,
                                          max_filter_depth: @max_filter_depth).parse
      loaded = load(parsed, source_path: source.path, stack: stack + [source.path])
      @cache[source.path] = [loaded, parsed]
    end
    .merge!(loaded.)
    [directive.name] = (parsed)
    variables.merge!(loaded.variables)
    imported = loaded.program.definitions
    imported = namespace_definitions(imported, directive.alias_name) if directive.type == :import
    definitions.concat(imported)
  end
  definitions.concat(program.definitions)
  Result.new(
    program: AST::Program.new(program.body, definitions, []),
    metadata: ,
    variables: variables
  )
end