Class: ScaffoldParser::Scaffolders::XSD

Inherits:
Object
  • Object
show all
Includes:
Parser::Handlers::Utils
Defined in:
lib/scaffold_parser/scaffolders/xsd.rb,
lib/scaffold_parser/scaffolders/xsd/parser.rb,
lib/scaffold_parser/scaffolders/xsd/parser/stack.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/all.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/blank.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/klass.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/utils.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/choice.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/import.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/module.rb,
lib/scaffold_parser/scaffolders/xsd/parser/module_template.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/include.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/elements.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/sequence.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/at_method.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/extension.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/base_method.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/element_ref.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/list_method.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/complex_type.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/class_inherit.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/module_include.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/order_elements.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/submodel_method.rb,
lib/scaffold_parser/scaffolders/xsd/parser/handlers/proxy_list_method.rb

Defined Under Namespace

Classes: Parser

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Parser::Handlers::Utils

#indent, #indent_string, #single_quote, #wrap_in_namespace

Constructor Details

#initialize(doc, options, parse_options = {}) ⇒ XSD

Returns a new instance of XSD.



13
14
15
16
17
# File 'lib/scaffold_parser/scaffolders/xsd.rb', line 13

def initialize(doc, options, parse_options = {})
  @doc = doc
  @options = options
  @parse_options = parse_options
end

Class Method Details

.call(doc, options, parse_options = {}) ⇒ Object



9
10
11
# File 'lib/scaffold_parser/scaffolders/xsd.rb', line 9

def self.call(doc, options, parse_options = {})
  self.new(doc, options, parse_options).call
end

Instance Method Details

#callObject



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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/scaffold_parser/scaffolders/xsd.rb', line 19

def call
  all = [@doc.schema] + @doc.schema.collect_included_schemas(@parse_options) + @doc.schema.collect_imported_schemas(@parse_options)

  classes = Parser.call(all, @options)
  top_level_elements = all.flat_map(&:elements)
  ref_map = top_level_elements.map { |e| [e.name_with_prefix, e.type_with_prefix]}.to_h

  # reject dumb classes which are just extension proxies to simple types :D
  classes = classes.reject do |klass|
    inherit_from = classes.find do |cl|
      cl.name_with_prefix == klass&.inherit_from&.split(':')&.map(&:camelize)&.join('::')
    end

    klass.methods.empty? && klass.includes.empty? && inherit_from.nil?
  end

  # remove dumb classes inheritance
  classes = classes.map do |klass|
    inherit_from = classes.find do |cl|
      cl.name_with_prefix == klass&.inherit_from&.split(':')&.map(&:camelize)&.join('::')
    end

    if inherit_from.nil?
      klass.inherit_from = nil
    end
    klass
  end

  # remove dumb classes includes
  classes = classes.map do |klass|
    existing_includes = (klass.includes || []).select do |incl|
      classes.map(&:name_with_prefix).include? incl.full_ref
    end

    klass.includes = existing_includes

    klass
  end

  # remove proxy lists through named complex types
  # #TODO: could i somehow remove proxy complex types so they are not outputted into class files?
  #   ... they are not used anyhow.. probably not used..? Can't they be inherited from or something?
  classes = classes.map do |klass|
    klass.methods = klass.methods.map do |meth|
      if meth.is_a?(Parser::Handlers::SubmodelMethod)
        submodel_class = classes.find { |cl| cl.name_with_prefix == meth.submodel_class }

        if (submodel_class.methods.size == 1) && submodel_class.methods.first.is_a?(Parser::Handlers::ListMethod) && submodel_class.inherit_from.nil? && submodel_class.includes.empty?
          submodel_class.methods.first.to_proxy_list(meth.source, meth.at)
        else
          meth
        end
      else
        meth
      end
    end

    klass
  end

  classes.each do |klass|
    klass.methods = klass.methods.map do |meth|
      if meth.is_a?(Parser::Handlers::SubmodelMethod) && !classes.map(&:name_with_prefix).include?(meth.submodel_class)
        meth.to_at_method
      elsif  meth.is_a?(Parser::Handlers::ElementRef)
        meth.to_submodel_method(ref_map)
      else
        meth
      end
    end
  end

  requires = create_requires_template(classes)
  parsers = classes.map do |klass|
    path = ["parsers", klass.namespace&.underscore, "#{klass.name.underscore}.rb"].compact.join('/')
    string = wrap_in_namespace(klass.to_s, 'Parsers')

    [path, string]
  end
  builders = classes.map do |klass|
    path = ["builders", klass.namespace&.underscore, "#{klass.name.underscore}.rb"].compact.join('/')
    string = wrap_in_namespace(klass.to_builder_s, 'Builders')

    [path, string]
  end

  all = parsers + builders
  result = all.map do |path, string|
    [path, wrap_in_namespace(string, @options[:namespace])]
  end

  result + [['requires.rb', requires]]
end