rggen-core 0.16.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +2 -2
  4. data/exe/rggen +0 -0
  5. data/lib/rggen/core.rb +6 -4
  6. data/lib/rggen/core/base/component.rb +18 -7
  7. data/lib/rggen/core/base/component_factory.rb +12 -9
  8. data/lib/rggen/core/base/component_layer_extension.rb +194 -0
  9. data/lib/rggen/core/base/feature_layer_extension.rb +158 -0
  10. data/lib/rggen/core/builder/builder.rb +33 -35
  11. data/lib/rggen/core/builder/component_entry.rb +3 -2
  12. data/lib/rggen/core/builder/component_registry.rb +22 -17
  13. data/lib/rggen/core/builder/input_component_registry.rb +43 -10
  14. data/lib/rggen/core/builder/{category.rb → layer.rb} +27 -26
  15. data/lib/rggen/core/builder/loader_registry.rb +48 -0
  16. data/lib/rggen/core/builder/plugins.rb +5 -3
  17. data/lib/rggen/core/configuration.rb +3 -2
  18. data/lib/rggen/core/configuration/component.rb +5 -0
  19. data/lib/rggen/core/configuration/component_factory.rb +1 -1
  20. data/lib/rggen/core/configuration/hash_loader.rb +4 -2
  21. data/lib/rggen/core/configuration/input_data.rb +15 -0
  22. data/lib/rggen/core/input_base/component_factory.rb +37 -6
  23. data/lib/rggen/core/input_base/feature.rb +9 -5
  24. data/lib/rggen/core/input_base/input_data.rb +13 -10
  25. data/lib/rggen/core/input_base/input_matcher.rb +15 -16
  26. data/lib/rggen/core/input_base/input_value_extractor.rb +34 -0
  27. data/lib/rggen/core/input_base/loader.rb +64 -21
  28. data/lib/rggen/core/input_base/verifier.rb +6 -7
  29. data/lib/rggen/core/input_base/yaml_loader.rb +22 -17
  30. data/lib/rggen/core/output_base/code_generator.rb +10 -23
  31. data/lib/rggen/core/output_base/component.rb +42 -39
  32. data/lib/rggen/core/output_base/component_factory.rb +4 -0
  33. data/lib/rggen/core/output_base/feature.rb +6 -7
  34. data/lib/rggen/core/printers.rb +2 -2
  35. data/lib/rggen/core/register_map.rb +6 -5
  36. data/lib/rggen/core/register_map/component.rb +4 -3
  37. data/lib/rggen/core/register_map/component_factory.rb +18 -1
  38. data/lib/rggen/core/register_map/feature.rb +2 -2
  39. data/lib/rggen/core/register_map/hash_loader.rb +61 -27
  40. data/lib/rggen/core/register_map/input_data.rb +30 -16
  41. data/lib/rggen/core/register_map/loader.rb +1 -1
  42. data/lib/rggen/core/register_map/ruby_loader.rb +1 -1
  43. data/lib/rggen/core/utility/code_utility.rb +8 -2
  44. data/lib/rggen/core/version.rb +1 -1
  45. metadata +11 -9
  46. data/lib/rggen/core/base/hierarchical_accessors.rb +0 -91
  47. data/lib/rggen/core/base/hierarchical_feature_accessors.rb +0 -83
  48. data/lib/rggen/core/core_extensions/casecmp.rb +0 -12
@@ -4,6 +4,11 @@ module RgGen
4
4
  module Core
5
5
  module Configuration
6
6
  class Component < InputBase::Component
7
+ private
8
+
9
+ def post_initialize
10
+ need_no_children
11
+ end
7
12
  end
8
13
  end
9
14
  end
@@ -7,7 +7,7 @@ module RgGen
7
7
  private
8
8
 
9
9
  def create_input_data(&block)
10
- InputBase::InputData.new(valid_value_lists, &block)
10
+ InputData.new(valid_value_lists, &block)
11
11
  end
12
12
  end
13
13
  end
@@ -4,8 +4,10 @@ module RgGen
4
4
  module Core
5
5
  module Configuration
6
6
  module HashLoader
7
- def format(read_data, file)
8
- input_data.values(Hash(read_data), file)
7
+ private
8
+
9
+ def format_layer_data(read_data, _layer, file)
10
+ Hash(read_data)
9
11
  rescue TypeError => e
10
12
  raise Core::LoadError.new(e.message, file)
11
13
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class InputData < InputBase::InputData
7
+ def initialize(valid_value_lists, &block)
8
+ super(nil, valid_value_lists, &block)
9
+ end
10
+
11
+ undef_method :child
12
+ end
13
+ end
14
+ end
15
+ end
@@ -4,6 +4,20 @@ module RgGen
4
4
  module Core
5
5
  module InputBase
6
6
  class ComponentFactory < Base::ComponentFactory
7
+ class << self
8
+ def enable_no_children_error
9
+ @enable_no_children_error = true
10
+ end
11
+
12
+ def disable_no_children_error
13
+ @enable_no_children_error = false
14
+ end
15
+
16
+ def enable_no_children_error?
17
+ @enable_no_children_error.nil? || @enable_no_children_error
18
+ end
19
+ end
20
+
7
21
  attr_setter :loaders
8
22
 
9
23
  private
@@ -27,8 +41,13 @@ module RgGen
27
41
  end
28
42
 
29
43
  def find_loader(file)
30
- loader = loaders.find { |l| l.support?(file) }
31
- loader || (raise Core::LoadError.new('unsupported file type', file))
44
+ loaders.find { |l| l.support?(file) } ||
45
+ (raise Core::LoadError.new('unsupported file type', file))
46
+ end
47
+
48
+ def valid_value_lists
49
+ component_factories
50
+ .transform_values(&->(f) { f.valid_value_list })
32
51
  end
33
52
 
34
53
  def create_input_data(&block)
@@ -58,9 +77,23 @@ module RgGen
58
77
  end
59
78
 
60
79
  def post_build(component)
80
+ exist_no_children?(component) &&
81
+ raise_no_children_error(component)
61
82
  component.verify(:component)
62
83
  end
63
84
 
85
+ def exist_no_children?(component)
86
+ enable_no_children_error? &&
87
+ component.need_children? && component.children.empty?
88
+ end
89
+
90
+ def enable_no_children_error?
91
+ self.class.enable_no_children_error?
92
+ end
93
+
94
+ def raise_no_children_error(_component)
95
+ end
96
+
64
97
  def finalize(component)
65
98
  component.verify(:all)
66
99
  end
@@ -77,10 +110,8 @@ module RgGen
77
110
 
78
111
  protected
79
112
 
80
- def valid_value_lists
81
- list = [Array(active_feature_factories&.keys)]
82
- list.concat(Array(child_factory&.valid_value_lists))
83
- list
113
+ def valid_value_list
114
+ Array(active_feature_factories&.keys)
84
115
  end
85
116
  end
86
117
  end
@@ -44,14 +44,14 @@ module RgGen
44
44
 
45
45
  def input_pattern(pattern_or_patterns, **options, &converter)
46
46
  @input_matcher =
47
- InputMatcher.new(pattern_or_patterns, options, &converter)
47
+ InputMatcher.new(pattern_or_patterns, **options, &converter)
48
48
  end
49
49
 
50
50
  attr_reader :input_matcher
51
51
 
52
52
  def verify(scope, &block)
53
53
  @verifiers ||= {}
54
- (@verifiers[scope] ||= []) << Verifier.new(&block)
54
+ (@verifiers[scope] ||= []) << create_verifier(&block)
55
55
  end
56
56
 
57
57
  attr_reader :verifiers
@@ -75,10 +75,14 @@ module RgGen
75
75
 
76
76
  private
77
77
 
78
+ def create_verifier(&body)
79
+ Verifier.new(&body)
80
+ end
81
+
78
82
  def export_verifiers(subclass)
79
- copied_verifiers =
80
- @verifiers.map { |scope, blocks| [scope, blocks.dup] }.to_h
81
- subclass.instance_variable_set(:@verifiers, copied_verifiers)
83
+ subclass.instance_variable_set(
84
+ :@verifiers, @verifiers.transform_values(&:dup)
85
+ )
82
86
  end
83
87
  end
84
88
 
@@ -4,7 +4,8 @@ module RgGen
4
4
  module Core
5
5
  module InputBase
6
6
  class InputData
7
- def initialize(valid_value_lists)
7
+ def initialize(layer, valid_value_lists)
8
+ @layer = layer
8
9
  @valid_value_lists = valid_value_lists
9
10
  @values = Hash.new(NAValue)
10
11
  @children = []
@@ -12,6 +13,8 @@ module RgGen
12
13
  block_given? && yield(self)
13
14
  end
14
15
 
16
+ attr_reader :layer
17
+
15
18
  def value(value_name, value, position = nil)
16
19
  symbolized_name = value_name.to_sym
17
20
  return unless valid_value?(symbolized_name)
@@ -24,8 +27,8 @@ module RgGen
24
27
  end
25
28
  end
26
29
 
27
- def []=(value_name, position = nil, value)
28
- value(value_name, value, position)
30
+ def []=(value_name, position_or_value, value = nil)
31
+ value(value_name, value || position_or_value, position_or_value)
29
32
  end
30
33
 
31
34
  def [](value_name)
@@ -39,8 +42,8 @@ module RgGen
39
42
 
40
43
  attr_reader :children
41
44
 
42
- def child(value_list = nil, &block)
43
- create_child_data do |child_data|
45
+ def child(layer, value_list = nil, &block)
46
+ create_child_data(layer) do |child_data|
44
47
  child_data.build_by_block(block)
45
48
  child_data.values(value_list)
46
49
  @children << child_data
@@ -56,11 +59,11 @@ module RgGen
56
59
  private
57
60
 
58
61
  def valid_value?(value_name)
59
- @valid_value_lists.first.include?(value_name)
62
+ @valid_value_lists[layer].include?(value_name)
60
63
  end
61
64
 
62
65
  def define_setter_methods
63
- @valid_value_lists.first.each(&method(:define_setter_method))
66
+ @valid_value_lists[layer].each(&method(:define_setter_method))
64
67
  end
65
68
 
66
69
  def define_setter_method(value_name)
@@ -79,12 +82,12 @@ module RgGen
79
82
  locations[0].path.include?('docile') ? locations[1] : locations[0]
80
83
  end
81
84
 
82
- def create_child_data(&block)
83
- child_data_class.new(@valid_value_lists[1..-1], &block)
85
+ def create_child_data(layer, &block)
86
+ child_data_class.new(layer, @valid_value_lists, &block)
84
87
  end
85
88
 
86
89
  def child_data_class
87
- InputData
90
+ self.class
88
91
  end
89
92
 
90
93
  protected
@@ -4,7 +4,7 @@ module RgGen
4
4
  module Core
5
5
  module InputBase
6
6
  class InputMatcher
7
- def initialize(pattern_or_patterns, options, &converter)
7
+ def initialize(pattern_or_patterns, **options, &converter)
8
8
  @options = options
9
9
  @converter = converter
10
10
  @patterns = format_patterns(pattern_or_patterns)
@@ -22,23 +22,22 @@ module RgGen
22
22
 
23
23
  private
24
24
 
25
- def format_patterns(patterns)
25
+ def format_patterns(pattern_or_patterns)
26
26
  if @options.fetch(:match_wholly, true)
27
- patterns_hash(patterns)
28
- .map { |i, pattern| [i, /\A#{pattern}\z/] }
29
- .to_h
27
+ expand_patterns(pattern_or_patterns)
28
+ .transform_values { |pattern| /\A#{pattern}\z/ }
30
29
  else
31
- patterns_hash(patterns)
30
+ expand_patterns(pattern_or_patterns)
32
31
  end
33
32
  end
34
33
 
35
- def patterns_hash(patterns)
36
- if patterns.is_a?(Hash)
37
- patterns
38
- else
39
- Array(patterns)
40
- .map.with_index { |pattern, i| [i, pattern] }
41
- .to_h
34
+ def expand_patterns(pattern_or_patterns)
35
+ Array(pattern_or_patterns).each_with_object({}) do |pattern, patterns|
36
+ if pattern.is_a? Hash
37
+ patterns.update(pattern)
38
+ else
39
+ patterns[patterns.size] = pattern
40
+ end
42
41
  end
43
42
  end
44
43
 
@@ -62,11 +61,11 @@ module RgGen
62
61
  end
63
62
 
64
63
  def match_patterns(rhs)
65
- match_data, index =
64
+ index, match_data =
66
65
  @patterns
67
- .map { |i, pattern| pattern.match(rhs) { |m| [m, i] } }
66
+ .transform_values { |pattern| pattern.match(rhs) }
68
67
  .compact
69
- .max { |m| m[0].length }
68
+ .max_by { |_, m| m[0].length }
70
69
  match_data && [convert_match_data(match_data), index]
71
70
  end
72
71
 
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module InputBase
6
+ class InputValueExtractor
7
+ def initialize(target_layers, target_value)
8
+ @target_layers = Array(target_layers)
9
+ @target_value = target_value
10
+ end
11
+
12
+ class << self
13
+ attr_reader :extractor
14
+
15
+ private
16
+
17
+ def extract(&body)
18
+ @extractor = body
19
+ end
20
+ end
21
+
22
+ def target_value?(layer, value)
23
+ value == @target_value &&
24
+ (@target_layers.empty? || @target_layers.include?(layer))
25
+ end
26
+
27
+ def extract(input_data)
28
+ body = self.class.extractor
29
+ instance_exec(input_data, &body)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -4,40 +4,83 @@ module RgGen
4
4
  module Core
5
5
  module InputBase
6
6
  class Loader
7
- class << self
8
- def support_types(types)
9
- @support_types = types.map(&:to_sym)
10
- end
7
+ def self.support_types(types = nil)
8
+ types && (@support_types ||= []).concat(types.map(&:to_sym))
9
+ @support_types
10
+ end
11
11
 
12
- def support?(file)
13
- file_ext = File.ext(file).to_sym
14
- @support_types.any? { |type| type.casecmp?(file_ext) }
15
- end
12
+ def initialize(extractors, ignore_values)
13
+ @extractors = extractors
14
+ @ignore_values = ignore_values
15
+ end
16
16
 
17
- def load_file(file, input_data, valid_value_list)
18
- new(input_data, valid_value_list).load_file(file)
19
- end
17
+ def support?(file)
18
+ ext = File.ext(file).to_sym
19
+ types = self.class.support_types
20
+ types&.any? { |type| type.casecmp?(ext) } || false
20
21
  end
21
22
 
22
- def initialize(input_data, valid_value_lists)
23
+ def load_file(file, input_data, valid_value_lists)
24
+ File.readable?(file) ||
25
+ (raise Core::LoadError.new('cannot load such file', file))
23
26
  @input_data = input_data
24
27
  @valid_value_lists = valid_value_lists
28
+ format(read_file(file), input_data, input_data.layer, file)
25
29
  end
26
30
 
27
- def load_file(file)
28
- File.readable?(file) || (
29
- raise Core::LoadError.new('cannot load such file', file)
30
- )
31
- format(read_file(file), file)
31
+ private
32
+
33
+ attr_reader :input_data
34
+
35
+ def format(read_data, input_data, layer, file)
36
+ layer_data =
37
+ format_layer_data(read_data, layer, file) ||
38
+ format_layer_data_by_extractors(read_data, layer)
39
+ layer_data &&
40
+ input_data.values(filter_layer_data(layer_data, layer), file)
41
+ format_sub_layer(read_data, input_data, layer, file)
32
42
  end
33
43
 
34
- private
44
+ def format_sub_layer(read_data, input_data, layer, file)
45
+ format_sub_layer_data(read_data, layer, file)
46
+ &.flat_map { |sub_layer, data_array| [sub_layer].product(data_array) }
47
+ &.each do |(sub_layer, data)|
48
+ format(data, input_data.child(sub_layer), sub_layer, file)
49
+ end
50
+ end
35
51
 
36
- def format(_read_data, _file)
52
+ def format_layer_data(_read_data, _layer, _file)
37
53
  end
38
54
 
39
- attr_reader :input_data
40
- attr_reader :valid_value_lists
55
+ def format_layer_data_by_extractors(read_data, layer)
56
+ layer_data = {}
57
+ valid_values(layer).each do |value|
58
+ @extractors
59
+ .select { |extractor| extractor.target_value?(layer, value) }
60
+ .each do |extractor|
61
+ extract_value(read_data, extractor, layer_data, value)
62
+ end
63
+ end
64
+ layer_data.empty? ? nil : layer_data
65
+ end
66
+
67
+ def extract_value(read_data, extractor, layer_data, value)
68
+ data = extractor.extract(read_data)
69
+ data && (layer_data[value] = data)
70
+ end
71
+
72
+ def filter_layer_data(layer_data, layer)
73
+ layer_data
74
+ .select { |key, _| valid_values(layer).include?(key) }
75
+ end
76
+
77
+ def format_sub_layer_data(_read_data, _layer, _file)
78
+ end
79
+
80
+ def valid_values(layer)
81
+ @valid_value_lists[layer]
82
+ .reject { |value| @ignore_values[layer]&.include?(value) }
83
+ end
41
84
  end
42
85
  end
43
86
  end
@@ -20,20 +20,19 @@ module RgGen
20
20
  @message = block
21
21
  end
22
22
 
23
- def verify(feature)
23
+ def verify(feature, *values)
24
24
  if @error_checker
25
- feature.instance_eval(&@error_checker)
25
+ feature.instance_exec(*values, &@error_checker)
26
26
  else
27
- default_error_check(feature)
27
+ default_error_check(feature, values)
28
28
  end
29
29
  end
30
30
 
31
31
  private
32
32
 
33
- def default_error_check(feature)
34
- feature.instance_exec(@condition, @message) do |condition, message|
35
- instance_eval(&condition) && error(instance_eval(&message))
36
- end
33
+ def default_error_check(feature, values)
34
+ feature.instance_exec(*values, &@condition) &&
35
+ feature.__send__(:error, feature.instance_exec(*values, &@message))
37
36
  end
38
37
  end
39
38
  end