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.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/LICENSE +21 -0
- data/README.md +46 -0
- data/exe/rggen +13 -0
- data/lib/rggen/core.rb +101 -0
- data/lib/rggen/core/base/component.rb +54 -0
- data/lib/rggen/core/base/component_factory.rb +84 -0
- data/lib/rggen/core/base/feature.rb +46 -0
- data/lib/rggen/core/base/feature_factory.rb +37 -0
- data/lib/rggen/core/base/hierarchical_accessors.rb +91 -0
- data/lib/rggen/core/base/hierarchical_feature_accessors.rb +83 -0
- data/lib/rggen/core/base/internal_struct.rb +21 -0
- data/lib/rggen/core/base/shared_context.rb +18 -0
- data/lib/rggen/core/builder.rb +13 -0
- data/lib/rggen/core/builder/builder.rb +150 -0
- data/lib/rggen/core/builder/category.rb +116 -0
- data/lib/rggen/core/builder/component_entry.rb +29 -0
- data/lib/rggen/core/builder/component_registry.rb +47 -0
- data/lib/rggen/core/builder/feature_registry.rb +126 -0
- data/lib/rggen/core/builder/input_component_registry.rb +35 -0
- data/lib/rggen/core/builder/list_feature_entry.rb +98 -0
- data/lib/rggen/core/builder/output_component_registry.rb +10 -0
- data/lib/rggen/core/builder/simple_feature_entry.rb +39 -0
- data/lib/rggen/core/cli.rb +29 -0
- data/lib/rggen/core/configuration.rb +19 -0
- data/lib/rggen/core/configuration/component.rb +10 -0
- data/lib/rggen/core/configuration/component_factory.rb +19 -0
- data/lib/rggen/core/configuration/error.rb +16 -0
- data/lib/rggen/core/configuration/feature.rb +13 -0
- data/lib/rggen/core/configuration/feature_factory.rb +11 -0
- data/lib/rggen/core/configuration/hash_loader.rb +15 -0
- data/lib/rggen/core/configuration/json_loader.rb +18 -0
- data/lib/rggen/core/configuration/loader.rb +11 -0
- data/lib/rggen/core/configuration/ruby_loader.rb +15 -0
- data/lib/rggen/core/configuration/yaml_loader.rb +18 -0
- data/lib/rggen/core/core_extensions/casecmp.rb +12 -0
- data/lib/rggen/core/core_extensions/forwardable.rb +12 -0
- data/lib/rggen/core/core_extensions/forwardable_workaround.rb +22 -0
- data/lib/rggen/core/core_extensions/object.rb +14 -0
- data/lib/rggen/core/dsl.rb +30 -0
- data/lib/rggen/core/exceptions.rb +29 -0
- data/lib/rggen/core/facets.rb +7 -0
- data/lib/rggen/core/generator.rb +51 -0
- data/lib/rggen/core/input_base/component.rb +30 -0
- data/lib/rggen/core/input_base/component_factory.rb +88 -0
- data/lib/rggen/core/input_base/feature.rb +130 -0
- data/lib/rggen/core/input_base/feature_factory.rb +80 -0
- data/lib/rggen/core/input_base/input_data.rb +98 -0
- data/lib/rggen/core/input_base/input_matcher.rb +79 -0
- data/lib/rggen/core/input_base/input_value.rb +34 -0
- data/lib/rggen/core/input_base/json_loader.rb +16 -0
- data/lib/rggen/core/input_base/loader.rb +44 -0
- data/lib/rggen/core/input_base/property.rb +76 -0
- data/lib/rggen/core/input_base/verifier.rb +41 -0
- data/lib/rggen/core/input_base/yaml_loader.rb +34 -0
- data/lib/rggen/core/options.rb +181 -0
- data/lib/rggen/core/output_base/code_generator.rb +59 -0
- data/lib/rggen/core/output_base/component.rb +100 -0
- data/lib/rggen/core/output_base/component_factory.rb +35 -0
- data/lib/rggen/core/output_base/erb_engine.rb +21 -0
- data/lib/rggen/core/output_base/feature.rb +147 -0
- data/lib/rggen/core/output_base/feature_factory.rb +13 -0
- data/lib/rggen/core/output_base/file_writer.rb +40 -0
- data/lib/rggen/core/output_base/template_engine.rb +27 -0
- data/lib/rggen/core/printers.rb +53 -0
- data/lib/rggen/core/register_map.rb +21 -0
- data/lib/rggen/core/register_map/component.rb +20 -0
- data/lib/rggen/core/register_map/component_factory.rb +19 -0
- data/lib/rggen/core/register_map/error.rb +16 -0
- data/lib/rggen/core/register_map/feature.rb +22 -0
- data/lib/rggen/core/register_map/feature_factory.rb +11 -0
- data/lib/rggen/core/register_map/hash_loader.rb +47 -0
- data/lib/rggen/core/register_map/input_data.rb +34 -0
- data/lib/rggen/core/register_map/json_loader.rb +18 -0
- data/lib/rggen/core/register_map/loader.rb +15 -0
- data/lib/rggen/core/register_map/ruby_loader.rb +15 -0
- data/lib/rggen/core/register_map/yaml_loader.rb +18 -0
- data/lib/rggen/core/utility/attribute_setter.rb +53 -0
- data/lib/rggen/core/utility/code_utility.rb +64 -0
- data/lib/rggen/core/utility/code_utility/code_block.rb +88 -0
- data/lib/rggen/core/utility/code_utility/line.rb +51 -0
- data/lib/rggen/core/utility/code_utility/source_file.rb +104 -0
- data/lib/rggen/core/utility/code_utility/structure_definition.rb +54 -0
- data/lib/rggen/core/utility/regexp_patterns.rb +38 -0
- data/lib/rggen/core/version.rb +10 -0
- 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
|