Class: Kumi::Core::Analyzer::Passes::ImportAnalysisPass

Inherits:
PassBase
  • Object
show all
Defined in:
lib/kumi/core/analyzer/passes/import_analysis_pass.rb

Instance Method Summary collapse

Methods inherited from PassBase

#debug, #debug_enabled?, #initialize

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

Constructor Details

This class inherits a constructor from Kumi::Core::Analyzer::Passes::PassBase

Instance Method Details

#run(errors) ⇒ Object



8
9
10
11
12
13
14
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
62
63
64
65
66
67
68
69
# File 'lib/kumi/core/analyzer/passes/import_analysis_pass.rb', line 8

def run(errors)
  imported_decls = get_state(:imported_declarations)
  imported_schemas = {}

  imported_decls.each do |name, meta|
    source_module_ref = meta[:from_module]

    begin
      source_module = resolve_source_module(source_module_ref)
    rescue NameError => e
      report_error(
        errors,
        "cannot import `#{name}`: module #{source_module_ref.inspect} not found (#{e.message})",
        location: meta[:loc]
      )
      next
    end

    begin
      syntax_tree = source_module.__kumi_syntax_tree__
    rescue NoMethodError
      report_error(
        errors,
        "cannot import `#{name}` from #{qualified_ref(source_module_ref, source_module)}: not a Kumi schema (missing __kumi_syntax_tree__)",
        location: meta[:loc]
      )
      next
    end

    source_decl = syntax_tree.values.find { |v| v.name == name } ||
                  syntax_tree.traits.find { |t| t.name == name }

    unless source_decl
      available = (syntax_tree.values.map(&:name) + syntax_tree.traits.map(&:name)).sort
      msg = "imported declaration `#{name}` not found in #{qualified_ref(source_module_ref, source_module)}"
      msg += "\navailable declarations: #{available.join(', ')}" if available.any?
      report_error(errors, msg, location: meta[:loc])
      next
    end

    begin
      analyzed_state = Kumi::Analyzer.analyze!(syntax_tree).state
    rescue => e
      report_error(
        errors,
        "failed to analyze imported schema from #{qualified_ref(source_module_ref, source_module)}: #{e.class}: #{e.message}",
        location: meta[:loc]
      )
      next
    end

    imported_schemas[name] = {
      decl: source_decl,
      source_module: source_module,
      source_root: syntax_tree,
      analyzed_state: analyzed_state,
      input_metadata: analyzed_state[:input_metadata] || {}
    }
  end

  state.with(:imported_schemas, imported_schemas.freeze)
end