expressir 2.1.22 → 2.1.23
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 +4 -4
- data/.rubocop.yml +9 -9
- data/.rubocop_todo.yml +62 -64
- data/Gemfile +2 -2
- data/README.adoc +202 -5
- data/bin/rspec +2 -1
- data/docs/liquid_drops.adoc +1 -1
- data/expressir.gemspec +0 -2
- data/lib/expressir/benchmark.rb +6 -3
- data/lib/expressir/cli.rb +24 -12
- data/lib/expressir/commands/benchmark.rb +7 -16
- data/lib/expressir/commands/benchmark_cache.rb +9 -17
- data/lib/expressir/commands/coverage.rb +43 -42
- data/lib/expressir/coverage.rb +41 -15
- data/lib/expressir/express/cache.rb +2 -1
- data/lib/expressir/express/formatter.rb +54 -12
- data/lib/expressir/express/hyperlink_formatter.rb +2 -1
- data/lib/expressir/express/parser.rb +329 -112
- data/lib/expressir/express/schema_head_formatter.rb +2 -1
- data/lib/expressir/express/visitor.rb +114 -51
- data/lib/expressir/model/declarations/entity.rb +2 -1
- data/lib/expressir/model/declarations/informal_proposition_rule.rb +24 -0
- data/lib/expressir/model/declarations/rule.rb +2 -1
- data/lib/expressir/model/declarations/schema.rb +4 -1
- data/lib/expressir/model/declarations/type.rb +2 -1
- data/lib/expressir/model/identifier.rb +2 -1
- data/lib/expressir/model/literals/string.rb +2 -1
- data/lib/expressir/model/model_element.rb +84 -145
- data/lib/expressir/model/repository.rb +2 -1
- data/lib/expressir/schema_manifest.rb +150 -0
- data/lib/expressir/schema_manifest_entry.rb +17 -0
- data/lib/expressir/version.rb +1 -1
- data/lib/expressir.rb +29 -12
- metadata +5 -2
@@ -9,7 +9,8 @@ module Expressir
|
|
9
9
|
# @!visibility private
|
10
10
|
def self.included(mod)
|
11
11
|
if !mod.superclass.private_method_defined?(:format_declarations_schema) || !mod.superclass.private_method_defined?(:format_declarations_schema_head)
|
12
|
-
raise Error::FormatterMethodMissingError.new("SchemaHeadFormatter",
|
12
|
+
raise Error::FormatterMethodMissingError.new("SchemaHeadFormatter",
|
13
|
+
"format_declarations_schema/format_declarations_schema_head")
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
@@ -41,7 +41,9 @@ module Expressir
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def method_missing(name, *args)
|
44
|
-
rulename = name.to_s.sub(/^visit_/, "").gsub(/_([a-z])/)
|
44
|
+
rulename = name.to_s.sub(/^visit_/, "").gsub(/_([a-z])/) do |m|
|
45
|
+
m[1].upcase
|
46
|
+
end.to_sym
|
45
47
|
self.class.define_method(name) { @data[rulename] }
|
46
48
|
send name, *args
|
47
49
|
end
|
@@ -84,28 +86,28 @@ module Expressir
|
|
84
86
|
|
85
87
|
@attached_remark_tokens = Set.new
|
86
88
|
|
87
|
-
@visit_methods =
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
89
|
+
@visit_methods = private_methods.grep(/^visit_/).to_h do |name|
|
90
|
+
rulename = name.to_s.sub(/^visit_/, "").gsub(/_([a-z])/) do
|
91
|
+
$1.upcase
|
92
|
+
end
|
93
|
+
[rulename.to_sym, name.to_sym]
|
94
|
+
end
|
93
95
|
end
|
94
96
|
|
95
97
|
def to_ctx(ast, name = :unnamed)
|
96
98
|
case ast
|
97
99
|
when Hash
|
98
|
-
nodes =
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
108
|
-
|
100
|
+
nodes = ast.to_h do |k, v|
|
101
|
+
if k =~ /^listOf_(.*)$/
|
102
|
+
itemkey = $1.to_sym
|
103
|
+
ary = Array === v ? v : [v]
|
104
|
+
[itemkey, to_ctx(ary.select do |v|
|
105
|
+
v[itemkey]
|
106
|
+
end.map { |v| v.slice(itemkey) })]
|
107
|
+
else
|
108
|
+
[k, to_ctx(v, k)]
|
109
|
+
end
|
110
|
+
end
|
109
111
|
Ctx.new nodes, name
|
110
112
|
when Array
|
111
113
|
ast.map do |element|
|
@@ -151,7 +153,7 @@ module Expressir
|
|
151
153
|
|
152
154
|
def get_source(ctx)
|
153
155
|
a, b = get_source_pos ctx
|
154
|
-
@source[a..b - 1].strip
|
156
|
+
@source[a..(b - 1)].strip
|
155
157
|
end
|
156
158
|
|
157
159
|
def visit_ast(ast, name)
|
@@ -177,7 +179,6 @@ module Expressir
|
|
177
179
|
node
|
178
180
|
end
|
179
181
|
|
180
|
-
# ###########################################3
|
181
182
|
private
|
182
183
|
|
183
184
|
def visit_top(ctx)
|
@@ -226,25 +227,34 @@ module Expressir
|
|
226
227
|
# check if path can create implicit remark item
|
227
228
|
# see https://github.com/lutaml/expressir/issues/78
|
228
229
|
rest, _, current_path = path.rpartition(".") # get last path part
|
229
|
-
|
230
|
+
path_prefix, _, current_path = current_path.rpartition(":")
|
230
231
|
parent_node = node_find(node, rest)
|
231
232
|
if parent_node&.class&.method_defined?(:remark_items)
|
232
233
|
remark_item = Model::Declarations::RemarkItem.new(
|
233
234
|
id: current_path,
|
234
235
|
)
|
235
|
-
remark_item.parent = parent_node
|
236
236
|
|
237
|
-
|
238
|
-
|
239
|
-
|
237
|
+
if parent_node.class.method_defined?(:informal_propositions) && (
|
238
|
+
current_path.match(/^IP\d+$/) || path_prefix.match(/^IP\d+$/)
|
239
|
+
)
|
240
|
+
id = /^IP\d+$/.match?(current_path) ? current_path : path_prefix
|
240
241
|
parent_node.informal_propositions ||= []
|
241
|
-
|
242
|
+
informal_proposition = Model::Declarations::InformalPropositionRule.new(id: id)
|
243
|
+
informal_proposition.parent = parent_node
|
244
|
+
parent_node.informal_propositions << informal_proposition
|
245
|
+
|
246
|
+
# Reassign the informal proposition id to the remark item
|
247
|
+
remark_item.id = id
|
248
|
+
remark_item.parent = informal_proposition
|
249
|
+
|
250
|
+
informal_proposition.remark_items ||= []
|
251
|
+
informal_proposition.remark_items << remark_item
|
242
252
|
else
|
243
253
|
parent_node.remark_items ||= []
|
244
254
|
parent_node.remark_items << remark_item
|
255
|
+
remark_item.parent = parent_node
|
245
256
|
end
|
246
257
|
parent_node.reset_children_by_id
|
247
|
-
|
248
258
|
remark_item
|
249
259
|
end
|
250
260
|
end
|
@@ -268,14 +278,16 @@ module Expressir
|
|
268
278
|
remark_tokens = get_remarks ctx
|
269
279
|
|
270
280
|
# skip already attached remarks
|
271
|
-
remark_tokens = remark_tokens.reject
|
281
|
+
remark_tokens = remark_tokens.reject do |x|
|
282
|
+
@attached_remark_tokens.include?(x)
|
283
|
+
end
|
272
284
|
|
273
285
|
# parse remarks, find remark targets
|
274
286
|
tagged_remark_tokens = []
|
275
287
|
untagged_remark_tokens = []
|
276
288
|
|
277
289
|
remark_tokens.each do |span|
|
278
|
-
text = @source[span[0]..span[1] - 1]
|
290
|
+
text = @source[span[0]..(span[1] - 1)]
|
279
291
|
remark_type = if text.start_with?("--")
|
280
292
|
:tail
|
281
293
|
else
|
@@ -304,6 +316,15 @@ module Expressir
|
|
304
316
|
tagged_remark_tokens << [span, remark_target, remark_text]
|
305
317
|
end
|
306
318
|
end
|
319
|
+
elsif text.match?(/^--IP\d+:/)
|
320
|
+
# Unquoted tagged tail remark: --IP1: content
|
321
|
+
remark_target_path = text[2..].strip
|
322
|
+
colon_end = text.index(":", 5)
|
323
|
+
remark_text = text[(colon_end + 1)...-2].strip.force_encoding("UTF-8")
|
324
|
+
remark_target = find_remark_target(node, remark_target_path)
|
325
|
+
if remark_target
|
326
|
+
tagged_remark_tokens << [span, remark_target, remark_text]
|
327
|
+
end
|
307
328
|
elsif text.start_with?("--")
|
308
329
|
# Untagged tail remark: -- content
|
309
330
|
untagged_text = text[2..].strip.force_encoding("UTF-8")
|
@@ -563,7 +584,8 @@ module Expressir
|
|
563
584
|
ctx__stmt = ctx.stmt
|
564
585
|
|
565
586
|
id = visit_if(ctx__variable_id)
|
566
|
-
expression = handle_qualified_ref(visit_if(ctx__general_ref),
|
587
|
+
expression = handle_qualified_ref(visit_if(ctx__general_ref),
|
588
|
+
ctx__qualifier)
|
567
589
|
statements = visit_if_map(ctx__stmt)
|
568
590
|
|
569
591
|
Model::Statements::Alias.new(
|
@@ -935,7 +957,8 @@ module Expressir
|
|
935
957
|
ctx__entity_head__subsuper__supertype_constraint__abstract_supertype_declaration) && true
|
936
958
|
supertype_expression = visit_if(ctx__entity_head__subsuper__supertype_constraint__abstract_supertype_declaration ||
|
937
959
|
ctx__entity_head__subsuper__supertype_constraint__supertype_rule)
|
938
|
-
subtype_of = visit_if(ctx__entity_head__subsuper__subtype_declaration,
|
960
|
+
subtype_of = visit_if(ctx__entity_head__subsuper__subtype_declaration,
|
961
|
+
[])
|
939
962
|
attributes = [
|
940
963
|
*visit_if_map_flatten(ctx__entity_body__explicit_attr),
|
941
964
|
*visit_if(ctx__entity_body__derive_clause),
|
@@ -1017,7 +1040,9 @@ module Expressir
|
|
1017
1040
|
|
1018
1041
|
extensible = ctx__EXTENSIBLE && true
|
1019
1042
|
based_on = visit_if(ctx__enumeration_extension__type_ref)
|
1020
|
-
items = visit_if(
|
1043
|
+
items = visit_if(
|
1044
|
+
ctx__enumeration_items || ctx__enumeration_extension__enumeration_items, []
|
1045
|
+
)
|
1021
1046
|
|
1022
1047
|
Model::DataTypes::Enumeration.new(
|
1023
1048
|
extensible: extensible,
|
@@ -1134,10 +1159,18 @@ module Expressir
|
|
1134
1159
|
return_type = visit_if(ctx__function_head__parameter_type)
|
1135
1160
|
declarations = visit_if_map(ctx__algorithm_head__declaration)
|
1136
1161
|
types = declarations.select { |x| x.is_a? Model::Declarations::Type }
|
1137
|
-
entities = declarations.select
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1162
|
+
entities = declarations.select do |x|
|
1163
|
+
x.is_a? Model::Declarations::Entity
|
1164
|
+
end
|
1165
|
+
subtype_constraints = declarations.select do |x|
|
1166
|
+
x.is_a? Model::Declarations::SubtypeConstraint
|
1167
|
+
end
|
1168
|
+
functions = declarations.select do |x|
|
1169
|
+
x.is_a? Model::Declarations::Function
|
1170
|
+
end
|
1171
|
+
procedures = declarations.select do |x|
|
1172
|
+
x.is_a? Model::Declarations::Procedure
|
1173
|
+
end
|
1141
1174
|
constants = visit_if(ctx__algorithm_head__constant_decl, [])
|
1142
1175
|
variables = visit_if(ctx__algorithm_head__local_decl, [])
|
1143
1176
|
statements = visit_if_map(ctx__stmt)
|
@@ -1756,10 +1789,18 @@ module Expressir
|
|
1756
1789
|
parameters = visit_if_map_flatten(ctx__procedure_head__procedure_head_parameter)
|
1757
1790
|
declarations = visit_if_map(ctx__algorithm_head__declaration)
|
1758
1791
|
types = declarations.select { |x| x.is_a? Model::Declarations::Type }
|
1759
|
-
entities = declarations.select
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1792
|
+
entities = declarations.select do |x|
|
1793
|
+
x.is_a? Model::Declarations::Entity
|
1794
|
+
end
|
1795
|
+
subtype_constraints = declarations.select do |x|
|
1796
|
+
x.is_a? Model::Declarations::SubtypeConstraint
|
1797
|
+
end
|
1798
|
+
functions = declarations.select do |x|
|
1799
|
+
x.is_a? Model::Declarations::Function
|
1800
|
+
end
|
1801
|
+
procedures = declarations.select do |x|
|
1802
|
+
x.is_a? Model::Declarations::Procedure
|
1803
|
+
end
|
1763
1804
|
constants = visit_if(ctx__algorithm_head__constant_decl, [])
|
1764
1805
|
variables = visit_if(ctx__algorithm_head__local_decl, [])
|
1765
1806
|
statements = visit_if_map(ctx__stmt)
|
@@ -2041,10 +2082,18 @@ module Expressir
|
|
2041
2082
|
applies_to = visit_if_map(ctx__rule_head__entity_ref)
|
2042
2083
|
declarations = visit_if_map(ctx__algorithm_head__declaration)
|
2043
2084
|
types = declarations.select { |x| x.is_a? Model::Declarations::Type }
|
2044
|
-
entities = declarations.select
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2085
|
+
entities = declarations.select do |x|
|
2086
|
+
x.is_a? Model::Declarations::Entity
|
2087
|
+
end
|
2088
|
+
subtype_constraints = declarations.select do |x|
|
2089
|
+
x.is_a? Model::Declarations::SubtypeConstraint
|
2090
|
+
end
|
2091
|
+
functions = declarations.select do |x|
|
2092
|
+
x.is_a? Model::Declarations::Function
|
2093
|
+
end
|
2094
|
+
procedures = declarations.select do |x|
|
2095
|
+
x.is_a? Model::Declarations::Procedure
|
2096
|
+
end
|
2048
2097
|
constants = visit_if(ctx__algorithm_head__constant_decl, [])
|
2049
2098
|
variables = visit_if(ctx__algorithm_head__local_decl, [])
|
2050
2099
|
statements = visit_if_map(ctx__stmt)
|
@@ -2106,11 +2155,19 @@ module Expressir
|
|
2106
2155
|
constants = visit_if(ctx__schema_body__constant_decl, [])
|
2107
2156
|
declarations = visit_if_map(ctx__schema_body__schema_body_declaration)
|
2108
2157
|
types = declarations.select { |x| x.is_a? Model::Declarations::Type }
|
2109
|
-
entities = declarations.select
|
2110
|
-
|
2111
|
-
|
2158
|
+
entities = declarations.select do |x|
|
2159
|
+
x.is_a? Model::Declarations::Entity
|
2160
|
+
end
|
2161
|
+
subtype_constraints = declarations.select do |x|
|
2162
|
+
x.is_a? Model::Declarations::SubtypeConstraint
|
2163
|
+
end
|
2164
|
+
functions = declarations.select do |x|
|
2165
|
+
x.is_a? Model::Declarations::Function
|
2166
|
+
end
|
2112
2167
|
rules = declarations.select { |x| x.is_a? Model::Declarations::Rule }
|
2113
|
-
procedures = declarations.select
|
2168
|
+
procedures = declarations.select do |x|
|
2169
|
+
x.is_a? Model::Declarations::Procedure
|
2170
|
+
end
|
2114
2171
|
|
2115
2172
|
Model::Declarations::Schema.new(
|
2116
2173
|
id: id,
|
@@ -2191,7 +2248,9 @@ module Expressir
|
|
2191
2248
|
extensible = ctx__EXTENSIBLE && true
|
2192
2249
|
generic_entity = ctx__GENERIC_ENTITY && true
|
2193
2250
|
based_on = visit_if(ctx__select_extension__type_ref)
|
2194
|
-
items = visit_if(
|
2251
|
+
items = visit_if(
|
2252
|
+
ctx__select_list || ctx__select_extension__select_list, []
|
2253
|
+
)
|
2195
2254
|
|
2196
2255
|
Model::DataTypes::Select.new(
|
2197
2256
|
extensible: extensible,
|
@@ -2405,7 +2464,9 @@ module Expressir
|
|
2405
2464
|
if ctx__supertype_factor.length >= 2
|
2406
2465
|
if ctx__ANDOR && (ctx__ANDOR.length == ctx__supertype_factor.length - 1)
|
2407
2466
|
operands = ctx__supertype_factor.map { |item| visit(item) }
|
2408
|
-
operators = ctx__ANDOR.map
|
2467
|
+
operators = ctx__ANDOR.map do
|
2468
|
+
Model::SupertypeExpressions::BinarySupertypeExpression::ANDOR
|
2469
|
+
end
|
2409
2470
|
|
2410
2471
|
handle_binary_supertype_expression(operands, operators)
|
2411
2472
|
else
|
@@ -2427,7 +2488,9 @@ module Expressir
|
|
2427
2488
|
if ctx__supertype_term.length >= 2
|
2428
2489
|
if ctx__AND && (ctx__AND.length == ctx__supertype_term.length - 1)
|
2429
2490
|
operands = ctx__supertype_term.map { |item| visit(item) }
|
2430
|
-
operators = ctx__AND.map
|
2491
|
+
operators = ctx__AND.map do
|
2492
|
+
Model::SupertypeExpressions::BinarySupertypeExpression::AND
|
2493
|
+
end
|
2431
2494
|
|
2432
2495
|
handle_binary_supertype_expression(operands, operators)
|
2433
2496
|
else
|
@@ -12,7 +12,8 @@ module Expressir
|
|
12
12
|
attribute :attributes, Attribute, collection: true
|
13
13
|
attribute :unique_rules, UniqueRule, collection: true
|
14
14
|
attribute :where_rules, WhereRule, collection: true
|
15
|
-
attribute :informal_propositions,
|
15
|
+
attribute :informal_propositions, InformalPropositionRule,
|
16
|
+
collection: true
|
16
17
|
attribute :_class, :string, default: -> { send(:name) }
|
17
18
|
|
18
19
|
key_value do
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Expressir
|
2
|
+
module Model
|
3
|
+
module Declarations
|
4
|
+
# Informal proposition rules are used to specify constraints that cannot be formally expressed
|
5
|
+
class InformalPropositionRule < ModelElement
|
6
|
+
include Identifier
|
7
|
+
|
8
|
+
attribute :expression, ModelElement
|
9
|
+
attribute :_class, :string, default: -> { send(:name) }
|
10
|
+
|
11
|
+
key_value do
|
12
|
+
map "_class", to: :_class, render_default: true
|
13
|
+
map "expression", to: :expression
|
14
|
+
end
|
15
|
+
|
16
|
+
def children
|
17
|
+
[
|
18
|
+
*remark_items,
|
19
|
+
]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -16,7 +16,8 @@ module Expressir
|
|
16
16
|
attribute :variables, Variable, collection: true
|
17
17
|
attribute :statements, ModelElement, collection: true
|
18
18
|
attribute :where_rules, WhereRule, collection: true
|
19
|
-
attribute :informal_propositions,
|
19
|
+
attribute :informal_propositions, InformalPropositionRule,
|
20
|
+
collection: true
|
20
21
|
attribute :_class, :string, default: -> { send(:name) }
|
21
22
|
|
22
23
|
key_value do
|
@@ -108,7 +108,10 @@ module Expressir
|
|
108
108
|
else
|
109
109
|
interface.items.filter_map do |item|
|
110
110
|
base_item = children_by_id[item.ref.id.safe_downcase]
|
111
|
-
|
111
|
+
if base_item
|
112
|
+
create_interfaced_item(item.id || base_item.id,
|
113
|
+
base_item)
|
114
|
+
end
|
112
115
|
end
|
113
116
|
end
|
114
117
|
end.compact
|
@@ -8,7 +8,8 @@ module Expressir
|
|
8
8
|
|
9
9
|
attribute :underlying_type, ModelElement
|
10
10
|
attribute :where_rules, WhereRule, collection: true
|
11
|
-
attribute :informal_propositions,
|
11
|
+
attribute :informal_propositions, InformalPropositionRule,
|
12
|
+
collection: true
|
12
13
|
attribute :_class, :string, default: -> { send(:name) }
|
13
14
|
|
14
15
|
key_value do
|
@@ -4,7 +4,8 @@ module Expressir
|
|
4
4
|
def self.included(mod)
|
5
5
|
mod.attribute :id, :string
|
6
6
|
mod.attribute :remarks, :string, collection: true
|
7
|
-
mod.attribute :remark_items,
|
7
|
+
mod.attribute :remark_items,
|
8
|
+
::Expressir::Model::Declarations::RemarkItem, collection: true
|
8
9
|
mod.attribute :untagged_remarks, :string, collection: true
|
9
10
|
|
10
11
|
mod.key_value do
|
@@ -10,7 +10,8 @@ module Expressir
|
|
10
10
|
|
11
11
|
key_value do
|
12
12
|
map "_class", to: :_class, render_default: true
|
13
|
-
map "value", to: :value,
|
13
|
+
map "value", to: :value,
|
14
|
+
value_map: { to: { nil: :empty, empty: :empty } }
|
14
15
|
map "encoded", to: :encoded
|
15
16
|
end
|
16
17
|
end
|