highway 0.0.1 → 1.0.1
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/lib/highway.rb +8 -4
- data/lib/highway/compiler/analyze/analyzer.rb +249 -0
- data/lib/highway/compiler/analyze/tree/root.rb +95 -0
- data/lib/highway/compiler/analyze/tree/segments/text.rb +36 -0
- data/lib/highway/compiler/analyze/tree/segments/variable.rb +43 -0
- data/lib/highway/compiler/analyze/tree/stage.rb +48 -0
- data/lib/highway/compiler/analyze/tree/step.rb +69 -0
- data/lib/highway/compiler/analyze/tree/values/array.rb +45 -0
- data/lib/highway/compiler/analyze/tree/values/base.rb +67 -0
- data/lib/highway/compiler/analyze/tree/values/hash.rb +45 -0
- data/lib/highway/compiler/analyze/tree/values/primitive.rb +43 -0
- data/lib/highway/compiler/analyze/tree/variable.rb +48 -0
- data/lib/highway/compiler/build/builder.rb +154 -0
- data/lib/highway/compiler/build/output/invocation.rb +70 -0
- data/lib/highway/compiler/build/output/manifest.rb +52 -0
- data/lib/highway/compiler/parse/parser.rb +92 -0
- data/lib/highway/compiler/parse/tree/root.rb +73 -0
- data/lib/highway/compiler/parse/tree/step.rb +62 -0
- data/lib/highway/compiler/parse/tree/variable.rb +48 -0
- data/lib/highway/compiler/parse/versions/v1.rb +110 -0
- data/lib/highway/compiler/suite.rb +56 -0
- data/lib/highway/environment.rb +282 -0
- data/lib/highway/fastlane/action.rb +67 -0
- data/lib/highway/interface.rb +135 -0
- data/lib/highway/main.rb +173 -0
- data/lib/highway/runtime/context.rb +229 -0
- data/lib/highway/runtime/report.rb +80 -0
- data/lib/highway/runtime/runner.rb +286 -0
- data/lib/highway/steps/infrastructure.rb +20 -0
- data/lib/highway/steps/library/action.rb +42 -0
- data/lib/highway/steps/library/appcenter.rb +106 -0
- data/lib/highway/steps/library/appstore.rb +137 -0
- data/lib/highway/steps/library/carthage.rb +67 -0
- data/lib/highway/steps/library/cocoapods.rb +76 -0
- data/lib/highway/steps/library/copy_artifacts.rb +36 -0
- data/lib/highway/steps/library/lane.rb +42 -0
- data/lib/highway/steps/library/sh.rb +36 -0
- data/lib/highway/steps/library/slack.rb +381 -0
- data/lib/highway/steps/library/testflight.rb +105 -0
- data/lib/highway/steps/library/xcode_archive.rb +162 -0
- data/lib/highway/steps/library/xcode_test.rb +264 -0
- data/lib/highway/steps/parameters/base.rb +52 -0
- data/lib/highway/steps/parameters/compound.rb +141 -0
- data/lib/highway/steps/parameters/single.rb +74 -0
- data/lib/highway/steps/registry.rb +92 -0
- data/lib/highway/steps/step.rb +52 -0
- data/lib/highway/steps/types/any.rb +65 -0
- data/lib/highway/steps/types/anyof.rb +64 -0
- data/lib/highway/steps/types/array.rb +44 -0
- data/lib/highway/steps/types/bool.rb +36 -0
- data/lib/highway/steps/types/enum.rb +44 -0
- data/lib/highway/steps/types/hash.rb +45 -0
- data/lib/highway/steps/types/number.rb +38 -0
- data/lib/highway/steps/types/set.rb +39 -0
- data/lib/highway/steps/types/string.rb +47 -0
- data/lib/highway/steps/types/url.rb +35 -0
- data/lib/highway/utilities.rb +51 -0
- data/lib/highway/version.rb +9 -1
- metadata +194 -22
- data/.gitignore +0 -4
- data/Gemfile +0 -4
- data/Rakefile +0 -1
- data/highway.gemspec +0 -24
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8e7516548771a99c73bea486d466a28a3019e93729955a359a6cc004d2336b6f
|
4
|
+
data.tar.gz: '083baad25067f0dd1c23194c04fec6ec53e7478a6aca9e79d40661d5e99c9447'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db98b371c18cb00198ff871ee8730373d90544bf880a2ccbccb361f1e9603363e6a48372882f1c966f5e413942841d9a53a6472da204338a04e5ad1a4d51e701
|
7
|
+
data.tar.gz: 37d1df04101159db5b871ef8144f857fd79f1499f8795fb42135dd0f141fefa2c60eceb3d59780c091fc1eea74085fdd1b0ddae8eb26e63b74e849342f9d82a4
|
data/lib/highway.rb
CHANGED
@@ -0,0 +1,249 @@
|
|
1
|
+
#
|
2
|
+
# analyzer.rb
|
3
|
+
# Copyright © 2019 Netguru S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
require "highway/compiler/analyze/tree/root"
|
7
|
+
require "highway/utilities"
|
8
|
+
|
9
|
+
module Highway
|
10
|
+
module Compiler
|
11
|
+
module Analyze
|
12
|
+
|
13
|
+
# This class is responsible for semantic analysis of a parse tree. This is
|
14
|
+
# the second phase of the compiler.
|
15
|
+
class Analyzer
|
16
|
+
|
17
|
+
public
|
18
|
+
|
19
|
+
# Initialize an instance.
|
20
|
+
#
|
21
|
+
# @param registry [Highway::Steps::Registry] The steps registry.
|
22
|
+
# @param reporter [Highway::Interface] The interface.
|
23
|
+
def initialize(registry:, interface:)
|
24
|
+
@registry = registry
|
25
|
+
@interface = interface
|
26
|
+
end
|
27
|
+
|
28
|
+
# Analyze the parse tree.
|
29
|
+
#
|
30
|
+
# The semantic analyzer validates the parse tree in terms of content,
|
31
|
+
# performs segmentation of values and resolves steps against the
|
32
|
+
# registry.
|
33
|
+
#
|
34
|
+
# The semantic analyzer produces a semantic tree which is then used by
|
35
|
+
# build phase to generate a manifest.
|
36
|
+
#
|
37
|
+
# @param parse_tree [Highway::Compiler::Parse::Tree::Root] The parse tree.
|
38
|
+
#
|
39
|
+
# @return [Highway::Compiler::Analyze::Tree::Root]
|
40
|
+
def analyze(parse_tree:)
|
41
|
+
|
42
|
+
sema_tree = Analyze::Tree::Root.new()
|
43
|
+
|
44
|
+
sema_tree.add_stage(index: 0, name: "bootstrap", policy: :normal, )
|
45
|
+
sema_tree.add_stage(index: 1, name: "test", policy: :normal)
|
46
|
+
sema_tree.add_stage(index: 2, name: "deploy", policy: :normal)
|
47
|
+
sema_tree.add_stage(index: 3, name: "report", policy: :always)
|
48
|
+
|
49
|
+
sema_tree.default_preset = "default"
|
50
|
+
|
51
|
+
validate_preset_names(parse_tree: parse_tree)
|
52
|
+
validate_variable_names(parse_tree: parse_tree)
|
53
|
+
validate_variable_values(parse_tree: parse_tree)
|
54
|
+
validate_step_names(parse_tree: parse_tree)
|
55
|
+
validate_step_parameter_values(parse_tree: parse_tree)
|
56
|
+
|
57
|
+
resolve_variables(parse_tree: parse_tree, sema_tree: sema_tree)
|
58
|
+
resolve_steps(parse_tree: parse_tree, sema_tree: sema_tree)
|
59
|
+
|
60
|
+
validate_variable_references(sema_tree: sema_tree)
|
61
|
+
|
62
|
+
sema_tree
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def validate_preset_names(parse_tree:)
|
69
|
+
parse_tree.variables.each do |variable|
|
70
|
+
assert_preset_name_valid(variable.preset, keypath: ["variables"])
|
71
|
+
end
|
72
|
+
parse_tree.steps.each do |step|
|
73
|
+
assert_preset_name_valid(step.preset, keypath: [step.stage])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate_variable_names(parse_tree:)
|
78
|
+
parse_tree.variables.each do |variable|
|
79
|
+
assert_variable_name_valid(variable.name, keypath: ["variables", variable.preset])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def validate_variable_values(parse_tree:)
|
84
|
+
parse_tree.variables.each do |variable|
|
85
|
+
assert_variable_value_valid(variable.value, keypath: ["variables", variable.preset, variable.name])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def validate_step_names(parse_tree:)
|
90
|
+
parse_tree.steps.each do |step|
|
91
|
+
assert_step_exists(step.name, keypath: [step.stage, step.preset])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def validate_step_parameter_values(parse_tree:)
|
96
|
+
parse_tree.steps.each do |step|
|
97
|
+
step.parameters.each_pair do |param_name, param_value|
|
98
|
+
assert_step_parameter_value_valid(param_value, keypath: [step.stage, step.preset, step.name, param_name])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def validate_variable_references(sema_tree:)
|
104
|
+
sema_tree.variables.each do |variable|
|
105
|
+
variable.value.select_variable_segments_with_scope(:static).each do |segment|
|
106
|
+
unless (ref_variable = find_referenced_variable(sema_tree: sema_tree, name: segment.name, preset: variable.preset))
|
107
|
+
@interface.fatal!("Unknown variable: '#{segment.name}' referenced from: '#{Utilities::keypath_to_s(["variables", variable.preset, variable.name])}'.")
|
108
|
+
end
|
109
|
+
if ref_variable.value.select_variable_segments_with_scope(:static).any? { |other| other.name == variable.name }
|
110
|
+
@interface.fatal!("Detected a reference cycle between: '#{Utilities::keypath_to_s(["variables", variable.preset, variable.name])}' and '#{Utilities::keypath_to_s(["variables", ref_variable.preset, ref_variable.name])}'.")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
sema_tree.steps.each do |step|
|
115
|
+
step.parameters.children.each_pair do |name, value|
|
116
|
+
value.select_variable_segments_with_scope(:static).each do |segment|
|
117
|
+
unless find_referenced_variable(sema_tree: sema_tree, name: segment.name, preset: step.preset)
|
118
|
+
@interface.fatal!("Unknown variable: '#{segment.name}' referenced from: '#{Utilities::keypath_to_s([step.stage, step.preset, step.name, name])}'.")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def resolve_variables(parse_tree:, sema_tree:)
|
126
|
+
parse_tree.variables.each do |variable|
|
127
|
+
value = segmentize_value(variable.value)
|
128
|
+
sema_tree.add_variable(name: variable.name, value: value, preset: variable.preset)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def resolve_steps(parse_tree:, sema_tree:)
|
133
|
+
parse_tree.steps.each do |step|
|
134
|
+
klass = @registry.get_by_name(step.name)
|
135
|
+
parameters = segmentize_value(step.parameters)
|
136
|
+
sema_tree.add_step(index: step.index, name: step.name, step_class: klass, parameters: parameters, stage: step.stage, preset: step.preset)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def segmentize_value(value)
|
141
|
+
if value.is_a?(String)
|
142
|
+
Analyze::Tree::Values::Primitive.new(
|
143
|
+
value.to_enum(:scan, %r((?<!\\)\$\(([A-Z0-9:_]+)\)|((?:[^\\\$]|\\\$)+))).map { Regexp.last_match }.map { |match|
|
144
|
+
if match[1]
|
145
|
+
if match[1][0, 4] == "ENV:"
|
146
|
+
Analyze::Tree::Segments::Variable.new(match[1][4..-1], scope: :env)
|
147
|
+
else
|
148
|
+
Analyze::Tree::Segments::Variable.new(match[1], scope: :static)
|
149
|
+
end
|
150
|
+
elsif match[2]
|
151
|
+
Analyze::Tree::Segments::Text.new(match[2])
|
152
|
+
end
|
153
|
+
}
|
154
|
+
)
|
155
|
+
elsif value.is_a?(Array)
|
156
|
+
Analyze::Tree::Values::Array.new(
|
157
|
+
value.map { |element|
|
158
|
+
segmentize_value(element)
|
159
|
+
}
|
160
|
+
)
|
161
|
+
elsif value.is_a?(Hash)
|
162
|
+
Analyze::Tree::Values::Hash.new(
|
163
|
+
Utilities::hash_map(value) { |name, element|
|
164
|
+
[name, segmentize_value(element)]
|
165
|
+
}
|
166
|
+
)
|
167
|
+
elsif value.is_a?(TrueClass) || value.is_a?(FalseClass) || value.is_a?(Numeric) || value.is_a?(NilClass)
|
168
|
+
Analyze::Tree::Values::Primitive.new(
|
169
|
+
[Analyze::Tree::Segments::Text.new(value.to_s)]
|
170
|
+
)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def find_referenced_variable(sema_tree:, name:, preset:)
|
175
|
+
sema_tree.variables.find do |variable|
|
176
|
+
variable.name == name && [preset, sema_tree.default_preset].include?(variable.preset)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def assert_preset_name_valid(value, keypath:)
|
181
|
+
unless %r(^[a-z_]*$) =~ value
|
182
|
+
@interface.fatal!("Invalid preset name: '#{value}' at: '#{Utilities::keypath_to_s(keypath)}'.")
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def assert_variable_name_valid(value, keypath:)
|
187
|
+
unless %r(^[A-Z_][A-Z0-9_]*$) =~ value
|
188
|
+
@interface.fatal!("Invalid variable name: '#{value}' at: '#{Utilities::keypath_to_s(keypath)}'.")
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def assert_variable_value_valid(value, keypath:)
|
193
|
+
if value.is_a?(String)
|
194
|
+
unless %r(^((?:[^\$]*(?:(?:\\\$)|(?<!\\)\$\((?:ENV:)?[A-Z_][A-Z0-9_]*\))*)*)$) =~ value
|
195
|
+
@interface.fatal!("Invalid variable value: '#{value}' at: '#{Utilities::keypath_to_s(keypath)}'.")
|
196
|
+
end
|
197
|
+
elsif value.is_a?(Array) || value.is_a?(Hash)
|
198
|
+
@interface.fatal!("Invalid variable value: '#{value}' at: '#{Utilities::keypath_to_s(keypath)}'.")
|
199
|
+
else
|
200
|
+
unless value.is_a?(TrueClass) || value.is_a?(FalseClass) || value.is_a?(Numeric) || value.is_a?(NilClass)
|
201
|
+
@interface.fatal!("Invalid variable value: '#{value}' at: '#{Utilities::keypath_to_s(keypath)}'.")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def assert_step_exists(value, keypath:)
|
207
|
+
unless @registry.get_by_name(value)
|
208
|
+
@interface.fatal!("Unknown step: '#{value}' at: '#{Utilities::keypath_to_s(keypath)}'.")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def assert_step_parameter_name_valid(value, expected:, keypath:)
|
213
|
+
unless expected.include?(value)
|
214
|
+
expected_names = expected.map { |name| "'#{name}'" }.join(", ")
|
215
|
+
@interface.fatal!("Unknown step parameter: '#{value}' at '#{Utilities::keypath_to_s(keypath)}'. Expected one of: [#{expected_names}].")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def assert_step_parameter_value_valid(value, keypath:)
|
220
|
+
if value.is_a?(String)
|
221
|
+
unless %r(^((?:[^\$]*(?:(?:\\\$)|(?<!\\)\$\((?:ENV:)?[A-Z_]+\))*)*)$) =~ value
|
222
|
+
@interface.fatal!("Invalid step parameter value: '#{value}' at: '#{Utilities::keypath_to_s(keypath)}'.")
|
223
|
+
end
|
224
|
+
elsif value.is_a?(Array)
|
225
|
+
value.each_with_index do |single_value, index|
|
226
|
+
assert_step_parameter_value_valid(single_value, keypath: keypath + [index])
|
227
|
+
end
|
228
|
+
elsif value.is_a?(Hash)
|
229
|
+
value.each_pair do |key, single_value|
|
230
|
+
assert_step_parameter_value_valid(single_value, keypath: keypath + [key])
|
231
|
+
end
|
232
|
+
else
|
233
|
+
unless value.is_a?(TrueClass) || value.is_a?(FalseClass) || value.is_a?(Numeric) || value.is_a?(NilClass)
|
234
|
+
@interface.fatal!("Invalid step parameter value: '#{value}' at: '#{Utilities::keypath_to_s(keypath)}'.")
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def assert_step_parameter_exists(value, expected:, keypath:)
|
240
|
+
unless value.include?(expected)
|
241
|
+
@interface.fatal!("Missing value for required step parameter: '#{expected}' at: '#{Utilities::keypath_to_s(keypath)}'.")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#
|
2
|
+
# root.rb
|
3
|
+
# Copyright © 2019 Netguru S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
require "highway/compiler/analyze/tree/segments/text"
|
7
|
+
require "highway/compiler/analyze/tree/segments/variable"
|
8
|
+
require "highway/compiler/analyze/tree/stage"
|
9
|
+
require "highway/compiler/analyze/tree/step"
|
10
|
+
require "highway/compiler/analyze/tree/values/array"
|
11
|
+
require "highway/compiler/analyze/tree/values/hash"
|
12
|
+
require "highway/compiler/analyze/tree/values/primitive"
|
13
|
+
require "highway/compiler/analyze/tree/variable"
|
14
|
+
|
15
|
+
module Highway
|
16
|
+
module Compiler
|
17
|
+
module Analyze
|
18
|
+
module Tree
|
19
|
+
|
20
|
+
# This class represents a root node of a semantic tree. It contains
|
21
|
+
# other nodes, such as variables and steps.
|
22
|
+
class Root
|
23
|
+
|
24
|
+
public
|
25
|
+
|
26
|
+
# Initialize an instance.
|
27
|
+
def initialize()
|
28
|
+
@variables = Array.new()
|
29
|
+
@steps = Array.new()
|
30
|
+
@stages = Array.new()
|
31
|
+
end
|
32
|
+
|
33
|
+
# Name of the default preset.
|
34
|
+
#
|
35
|
+
# @return [String]
|
36
|
+
attr_accessor :default_preset
|
37
|
+
|
38
|
+
# Variables in the tree.
|
39
|
+
#
|
40
|
+
# @return [Array<Highway::Compiler::Analyze::Tree::Variable>]
|
41
|
+
attr_reader :variables
|
42
|
+
|
43
|
+
# Steps in the tree.
|
44
|
+
#
|
45
|
+
# @return [Array<Highway::Compiler::Analyze::Tree::Step>]
|
46
|
+
attr_reader :steps
|
47
|
+
|
48
|
+
# Stages in the tree.
|
49
|
+
#
|
50
|
+
# @return [Array<Highway::Compiler::Analyze::Tree::Stage>]
|
51
|
+
attr_reader :stages
|
52
|
+
|
53
|
+
# Add a variable to the tree.
|
54
|
+
#
|
55
|
+
# @param name [String] Name of the variable.
|
56
|
+
# @param value [Highway::Compiler::Analyze::Tree::Values::*] Value of the variable.
|
57
|
+
# @param preset [String] Parent preset of the variable.
|
58
|
+
#
|
59
|
+
# @return [Void]
|
60
|
+
def add_variable(name:, value:, preset:)
|
61
|
+
@variables << Variable.new(name: name, value: value, preset: preset)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Add a step to the tree.
|
65
|
+
#
|
66
|
+
# @param index [Integer] Index of step in its scope.
|
67
|
+
# @param name [String] Name of the step.
|
68
|
+
# @param step_class [Class] Definition class of the step.
|
69
|
+
# @param parameters [Highway::Compiler::Analyze::Tree::Values::Hash] The hash value of step parameters.
|
70
|
+
# @param preset [String] Parent preset of the step.
|
71
|
+
# @param stage [String] Parent stage of the step.
|
72
|
+
#
|
73
|
+
# @return [Void]
|
74
|
+
def add_step(index:, name:, step_class:, parameters:, preset:, stage:)
|
75
|
+
@steps << Step.new(index: index, name: name, step_class: step_class, parameters: parameters, preset: preset, stage: stage)
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
# Add a stage to the tree.
|
80
|
+
#
|
81
|
+
# @param index [Integer] Index of the stage.
|
82
|
+
# @param name [String] Name of the stage.
|
83
|
+
# @param policy [Symbol] Execution policy of the stage.
|
84
|
+
#
|
85
|
+
# @return [Void]
|
86
|
+
def add_stage(index:, name:, policy:)
|
87
|
+
@stages << Stage.new(index: index, name: name, policy: policy)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#
|
2
|
+
# text.rb
|
3
|
+
# Copyright © 2019 Netguru S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
module Highway
|
7
|
+
module Compiler
|
8
|
+
module Analyze
|
9
|
+
module Tree
|
10
|
+
module Segments
|
11
|
+
|
12
|
+
# This class represents a text value segment in the semantic tree. It
|
13
|
+
# consists of a raw text value.
|
14
|
+
class Text
|
15
|
+
|
16
|
+
public
|
17
|
+
|
18
|
+
# Initialize an instance.
|
19
|
+
#
|
20
|
+
# @param value [String] The raw text value.
|
21
|
+
def initialize(value)
|
22
|
+
@value = value
|
23
|
+
end
|
24
|
+
|
25
|
+
# The raw text value.
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
attr_reader :value
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# variable.rb
|
3
|
+
# Copyright © 2019 Netguru S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
module Highway
|
7
|
+
module Compiler
|
8
|
+
module Analyze
|
9
|
+
module Tree
|
10
|
+
module Segments
|
11
|
+
|
12
|
+
# This class represents a variable value segment in the semantic
|
13
|
+
# tree. It consists of a variable name and its lookup scope.
|
14
|
+
class Variable
|
15
|
+
|
16
|
+
public
|
17
|
+
|
18
|
+
# Initialize an instance.
|
19
|
+
#
|
20
|
+
# @param name [String] The variable name.
|
21
|
+
# @param scope [Symbol] The lookup scope of variable.
|
22
|
+
def initialize(name, scope:)
|
23
|
+
@name = name
|
24
|
+
@scope = scope
|
25
|
+
end
|
26
|
+
|
27
|
+
# The variable name.
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
attr_reader :name
|
31
|
+
|
32
|
+
# The lookup scope of the variable.
|
33
|
+
#
|
34
|
+
# @return [Symbol]
|
35
|
+
attr_reader :scope
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|