rggen-core 0.9.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 (87) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +46 -0
  3. data/LICENSE +21 -0
  4. data/README.md +46 -0
  5. data/exe/rggen +13 -0
  6. data/lib/rggen/core.rb +101 -0
  7. data/lib/rggen/core/base/component.rb +54 -0
  8. data/lib/rggen/core/base/component_factory.rb +84 -0
  9. data/lib/rggen/core/base/feature.rb +46 -0
  10. data/lib/rggen/core/base/feature_factory.rb +37 -0
  11. data/lib/rggen/core/base/hierarchical_accessors.rb +91 -0
  12. data/lib/rggen/core/base/hierarchical_feature_accessors.rb +83 -0
  13. data/lib/rggen/core/base/internal_struct.rb +21 -0
  14. data/lib/rggen/core/base/shared_context.rb +18 -0
  15. data/lib/rggen/core/builder.rb +13 -0
  16. data/lib/rggen/core/builder/builder.rb +150 -0
  17. data/lib/rggen/core/builder/category.rb +116 -0
  18. data/lib/rggen/core/builder/component_entry.rb +29 -0
  19. data/lib/rggen/core/builder/component_registry.rb +47 -0
  20. data/lib/rggen/core/builder/feature_registry.rb +126 -0
  21. data/lib/rggen/core/builder/input_component_registry.rb +35 -0
  22. data/lib/rggen/core/builder/list_feature_entry.rb +98 -0
  23. data/lib/rggen/core/builder/output_component_registry.rb +10 -0
  24. data/lib/rggen/core/builder/simple_feature_entry.rb +39 -0
  25. data/lib/rggen/core/cli.rb +29 -0
  26. data/lib/rggen/core/configuration.rb +19 -0
  27. data/lib/rggen/core/configuration/component.rb +10 -0
  28. data/lib/rggen/core/configuration/component_factory.rb +19 -0
  29. data/lib/rggen/core/configuration/error.rb +16 -0
  30. data/lib/rggen/core/configuration/feature.rb +13 -0
  31. data/lib/rggen/core/configuration/feature_factory.rb +11 -0
  32. data/lib/rggen/core/configuration/hash_loader.rb +15 -0
  33. data/lib/rggen/core/configuration/json_loader.rb +18 -0
  34. data/lib/rggen/core/configuration/loader.rb +11 -0
  35. data/lib/rggen/core/configuration/ruby_loader.rb +15 -0
  36. data/lib/rggen/core/configuration/yaml_loader.rb +18 -0
  37. data/lib/rggen/core/core_extensions/casecmp.rb +12 -0
  38. data/lib/rggen/core/core_extensions/forwardable.rb +12 -0
  39. data/lib/rggen/core/core_extensions/forwardable_workaround.rb +22 -0
  40. data/lib/rggen/core/core_extensions/object.rb +14 -0
  41. data/lib/rggen/core/dsl.rb +30 -0
  42. data/lib/rggen/core/exceptions.rb +29 -0
  43. data/lib/rggen/core/facets.rb +7 -0
  44. data/lib/rggen/core/generator.rb +51 -0
  45. data/lib/rggen/core/input_base/component.rb +30 -0
  46. data/lib/rggen/core/input_base/component_factory.rb +88 -0
  47. data/lib/rggen/core/input_base/feature.rb +130 -0
  48. data/lib/rggen/core/input_base/feature_factory.rb +80 -0
  49. data/lib/rggen/core/input_base/input_data.rb +98 -0
  50. data/lib/rggen/core/input_base/input_matcher.rb +79 -0
  51. data/lib/rggen/core/input_base/input_value.rb +34 -0
  52. data/lib/rggen/core/input_base/json_loader.rb +16 -0
  53. data/lib/rggen/core/input_base/loader.rb +44 -0
  54. data/lib/rggen/core/input_base/property.rb +76 -0
  55. data/lib/rggen/core/input_base/verifier.rb +41 -0
  56. data/lib/rggen/core/input_base/yaml_loader.rb +34 -0
  57. data/lib/rggen/core/options.rb +181 -0
  58. data/lib/rggen/core/output_base/code_generator.rb +59 -0
  59. data/lib/rggen/core/output_base/component.rb +100 -0
  60. data/lib/rggen/core/output_base/component_factory.rb +35 -0
  61. data/lib/rggen/core/output_base/erb_engine.rb +21 -0
  62. data/lib/rggen/core/output_base/feature.rb +147 -0
  63. data/lib/rggen/core/output_base/feature_factory.rb +13 -0
  64. data/lib/rggen/core/output_base/file_writer.rb +40 -0
  65. data/lib/rggen/core/output_base/template_engine.rb +27 -0
  66. data/lib/rggen/core/printers.rb +53 -0
  67. data/lib/rggen/core/register_map.rb +21 -0
  68. data/lib/rggen/core/register_map/component.rb +20 -0
  69. data/lib/rggen/core/register_map/component_factory.rb +19 -0
  70. data/lib/rggen/core/register_map/error.rb +16 -0
  71. data/lib/rggen/core/register_map/feature.rb +22 -0
  72. data/lib/rggen/core/register_map/feature_factory.rb +11 -0
  73. data/lib/rggen/core/register_map/hash_loader.rb +47 -0
  74. data/lib/rggen/core/register_map/input_data.rb +34 -0
  75. data/lib/rggen/core/register_map/json_loader.rb +18 -0
  76. data/lib/rggen/core/register_map/loader.rb +15 -0
  77. data/lib/rggen/core/register_map/ruby_loader.rb +15 -0
  78. data/lib/rggen/core/register_map/yaml_loader.rb +18 -0
  79. data/lib/rggen/core/utility/attribute_setter.rb +53 -0
  80. data/lib/rggen/core/utility/code_utility.rb +64 -0
  81. data/lib/rggen/core/utility/code_utility/code_block.rb +88 -0
  82. data/lib/rggen/core/utility/code_utility/line.rb +51 -0
  83. data/lib/rggen/core/utility/code_utility/source_file.rb +104 -0
  84. data/lib/rggen/core/utility/code_utility/structure_definition.rb +54 -0
  85. data/lib/rggen/core/utility/regexp_patterns.rb +38 -0
  86. data/lib/rggen/core/version.rb +10 -0
  87. metadata +188 -0
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module OutputBase
6
+ class ComponentFactory < Base::ComponentFactory
7
+ private
8
+
9
+ def create_component(parent, configuration, register_map, &block)
10
+ target_component.new(parent, configuration, register_map, &block)
11
+ end
12
+
13
+ def create_features(component, configuration, register_map)
14
+ @feature_factories.each_value do |factory|
15
+ create_feature(component, factory, configuration, register_map)
16
+ end
17
+ end
18
+
19
+ def create_children(component, configuration, register_map)
20
+ register_map.children.each do |child|
21
+ create_child(component, configuration, child)
22
+ end
23
+ end
24
+
25
+ def post_build(component)
26
+ component.pre_build
27
+ end
28
+
29
+ def finalize(component)
30
+ component.build
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module OutputBase
6
+ class ERBEngine < TemplateEngine
7
+ def file_extension
8
+ :erb
9
+ end
10
+
11
+ def parse_template(path)
12
+ Erubi::Engine.new(File.binread(path), filename: path)
13
+ end
14
+
15
+ def render(context, template)
16
+ context.instance_eval(template.src, template.filename, 1)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module OutputBase
6
+ class Feature < Base::Feature
7
+ include Base::HierarchicalFeatureAccessors
8
+
9
+ class << self
10
+ attr_reader :pre_builders
11
+ attr_reader :builders
12
+
13
+ def code_generators
14
+ @code_generators ||= {}
15
+ end
16
+
17
+ def template_engine(engine = nil)
18
+ @template_engine = engine.instance if engine
19
+ @template_engine
20
+ end
21
+
22
+ attr_reader :file_writer
23
+
24
+ def exported_methods
25
+ @exported_methods ||= []
26
+ end
27
+
28
+ private
29
+
30
+ def pre_build(&body)
31
+ @pre_builders ||= []
32
+ @pre_builders << body
33
+ end
34
+
35
+ def build(&body)
36
+ @builders ||= []
37
+ @builders << body
38
+ end
39
+
40
+ [:pre_code, :main_code, :post_code].each do |phase|
41
+ define_method(phase) do |kind, **options, &body|
42
+ block =
43
+ if options[:from_template]
44
+ caller_location = caller_locations(1, 1).first
45
+ template_path = extract_template_path(options)
46
+ -> { process_template(template_path, caller_location) }
47
+ else
48
+ body
49
+ end
50
+ code_generators[__method__] ||= CodeGenerator.new
51
+ code_generators[__method__].register(kind, block)
52
+ end
53
+ end
54
+
55
+ def extract_template_path(options)
56
+ path = options[:from_template]
57
+ path.equal?(true) ? nil : path
58
+ end
59
+
60
+ def write_file(file_name_pattern, &body)
61
+ @file_writer = FileWriter.new(file_name_pattern, body)
62
+ end
63
+
64
+ def export(*methods)
65
+ methods.each do |method|
66
+ exported_methods.include?(method) || (
67
+ exported_methods << method
68
+ )
69
+ end
70
+ end
71
+ end
72
+
73
+ class << self
74
+ def inherited(subclass)
75
+ export_instance_variable(:@pre_builders, subclass, &:dup)
76
+ export_instance_variable(:@builders, subclass, &:dup)
77
+ export_instance_variable(:@template_engine, subclass)
78
+ export_instance_variable(:@file_writer, subclass)
79
+ export_instance_variable(:@exported_methods, subclass, &:dup)
80
+ copy_code_generators(subclass)
81
+ end
82
+
83
+ def copy_code_generators(subclass)
84
+ @code_generators&.each do |phase, generator|
85
+ subclass.code_generators[phase] = generator.copy
86
+ end
87
+ end
88
+ end
89
+
90
+ def post_initialize
91
+ define_hierarchical_accessors
92
+ end
93
+
94
+ def pre_build
95
+ helper
96
+ .pre_builders
97
+ &.each { |body| instance_exec(&body) }
98
+ end
99
+
100
+ def build
101
+ helper
102
+ .builders
103
+ &.each { |body| instance_exec(&body) }
104
+ end
105
+
106
+ def export(*methods)
107
+ methods.each do |method|
108
+ unless exported_methods(:class).include?(method) ||
109
+ exported_methods(:object).include?(method)
110
+ exported_methods(:object) << method
111
+ end
112
+ end
113
+ end
114
+
115
+ def exported_methods(scope)
116
+ if scope == :class
117
+ self.class.exported_methods
118
+ else
119
+ @exported_methods ||= []
120
+ end
121
+ end
122
+
123
+ def generate_code(phase, kind, code = nil)
124
+ generator = self.class.code_generators[phase]
125
+ (generator&.generate(self, kind, code)) || code
126
+ end
127
+
128
+ def write_file(directory = nil)
129
+ file_writer = self.class.file_writer
130
+ file_writer&.write_file(self, directory)
131
+ end
132
+
133
+ private
134
+
135
+ def configuration
136
+ component.configuration
137
+ end
138
+
139
+ def process_template(path = nil, caller_location = nil)
140
+ caller_location ||= caller_locations(1, 1).first
141
+ template_engine = self.class.template_engine
142
+ template_engine.process_template(self, path, caller_location)
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module OutputBase
6
+ class FeatureFactory < Base::FeatureFactory
7
+ def create(component, configuration, register_map)
8
+ create_feature(component, configuration, register_map)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module OutputBase
6
+ class FileWriter
7
+ def initialize(pattern, body)
8
+ @pattern = Erubi::Engine.new(pattern)
9
+ @body = body
10
+ end
11
+
12
+ def write_file(context, directory = nil)
13
+ path = generate_path(context, directory)
14
+ content = generate_content(context, path)
15
+ create_directory(path)
16
+ File.binwrite(path, content)
17
+ end
18
+
19
+ private
20
+
21
+ def generate_path(context, directory)
22
+ [
23
+ *Array(directory), context.instance_eval(@pattern.src)
24
+ ].map(&:to_s).reject(&:empty?).to_path
25
+ end
26
+
27
+ def generate_content(context, path)
28
+ content = context.create_blank_file(path)
29
+ @body && context.instance_exec(content, &@body)
30
+ content
31
+ end
32
+
33
+ def create_directory(path)
34
+ directory = path.dirname
35
+ directory.directory? || directory.mkpath
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module OutputBase
6
+ class TemplateEngine
7
+ include Singleton
8
+
9
+ def process_template(context, path = nil, caller_location = nil)
10
+ unless path
11
+ caller_location ||= caller_locations(1, 1).first
12
+ path = File.ext(caller_location.path, file_extension.to_s)
13
+ end
14
+ render(context, templates[path])
15
+ end
16
+
17
+ private
18
+
19
+ def templates
20
+ @templates ||= Hash.new do |templates, path|
21
+ templates[path] = parse_template(path)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ class HelpPrinter
6
+ def initialize(option_parser)
7
+ @option_parser = option_parser
8
+ end
9
+
10
+ def run(_builder, _options)
11
+ puts @option_parser.help
12
+ end
13
+ end
14
+
15
+ class VersionPrinter
16
+ def initialize(verbose)
17
+ @verbose = verbose
18
+ end
19
+
20
+ def run(builder, options)
21
+ verbose? && load_setup_file(builder, options[:setup])
22
+ puts help_message(builder)
23
+ end
24
+
25
+ private
26
+
27
+ def verbose?
28
+ @verbose
29
+ end
30
+
31
+ def load_setup_file(builder, file)
32
+ file.nil? || file.empty? || builder.load_setup_file(file)
33
+ end
34
+
35
+ def help_message(builder)
36
+ [
37
+ simple_version,
38
+ *(verbose? && verbose_version(builder) || nil)
39
+ ].join("\n")
40
+ end
41
+
42
+ def simple_version
43
+ "RgGen #{Core::MAJOR}.#{Core::MINOR}"
44
+ end
45
+
46
+ def verbose_version(builder)
47
+ { core: Core::VERSION }
48
+ .merge(builder.library_versions)
49
+ .map { |(lib, version)| " - rggen-#{lib} #{version}" }
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ def self.setup(builder)
7
+ builder.input_component_registry(:register_map) do
8
+ register_component [
9
+ :register_map, :register_block, :register, :bit_field
10
+ ] do |category|
11
+ component Component, ComponentFactory
12
+ feature Feature, FeatureFactory if category != :register_map
13
+ end
14
+
15
+ base_loader Loader
16
+ register_loaders [RubyLoader, JSONLoader, YAMLLoader]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class Component < InputBase::Component
7
+ include Base::HierarchicalAccessors
8
+
9
+ attr_reader :configuration
10
+
11
+ private
12
+
13
+ def post_initialize(_parent, configuration)
14
+ @configuration = configuration
15
+ define_hierarchical_accessors
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class ComponentFactory < InputBase::ComponentFactory
7
+ private
8
+
9
+ def create_component(parent, configuration, _, &block)
10
+ @target_component.new(parent, configuration, &block)
11
+ end
12
+
13
+ def create_input_data(&block)
14
+ RegisterMapData.new(valid_value_lists, &block)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class RegisterMapError < Core::RuntimeError
7
+ end
8
+
9
+ module RaiseError
10
+ def error(message, position = nil)
11
+ raise RegisterMapError.new(message, position || @position)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class Feature < InputBase::Feature
7
+ include Base::HierarchicalFeatureAccessors
8
+ include RaiseError
9
+
10
+ private
11
+
12
+ def configuration
13
+ @component.configuration
14
+ end
15
+
16
+ def post_initialize
17
+ define_hierarchical_accessors
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end