rggen-core 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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