expressir 0.2.15-arm64-darwin → 0.2.21-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +5 -0
  3. data/.github/workflows/release.yml +16 -4
  4. data/README.adoc +3 -3
  5. data/exe/format +66 -12
  6. data/lib/expressir/express_exp/2.4/express_parser.bundle +0 -0
  7. data/lib/expressir/express_exp/2.5/express_parser.bundle +0 -0
  8. data/lib/expressir/express_exp/2.6/express_parser.bundle +0 -0
  9. data/lib/expressir/express_exp/2.7/express_parser.bundle +0 -0
  10. data/lib/expressir/express_exp/3.0/express_parser.bundle +0 -0
  11. data/lib/expressir/express_exp/cache.rb +48 -0
  12. data/lib/expressir/express_exp/formatter.rb +185 -135
  13. data/lib/expressir/express_exp/hyperlink_formatter.rb +1 -3
  14. data/lib/expressir/express_exp/parser.rb +33 -29
  15. data/lib/expressir/express_exp/schema_head_formatter.rb +2 -7
  16. data/lib/expressir/express_exp/visitor.rb +11 -30
  17. data/lib/expressir/model.rb +2 -0
  18. data/lib/expressir/model/cache.rb +13 -0
  19. data/lib/expressir/model/entity.rb +6 -6
  20. data/lib/expressir/model/expressions/query_expression.rb +3 -3
  21. data/lib/expressir/model/function.rb +15 -11
  22. data/lib/expressir/model/informal_proposition.rb +4 -1
  23. data/lib/expressir/model/interfaced_item.rb +4 -1
  24. data/lib/expressir/model/model_element.rb +43 -13
  25. data/lib/expressir/model/procedure.rb +15 -11
  26. data/lib/expressir/model/repository.rb +3 -3
  27. data/lib/expressir/model/rule.rb +16 -12
  28. data/lib/expressir/model/schema.rb +52 -48
  29. data/lib/expressir/model/statements/alias.rb +3 -3
  30. data/lib/expressir/model/statements/repeat.rb +3 -3
  31. data/lib/expressir/model/subtype_constraint.rb +1 -6
  32. data/lib/expressir/model/type.rb +9 -5
  33. data/lib/expressir/version.rb +1 -1
  34. data/original/examples/syntax/{hyperlink.exp → multiple.exp} +8 -8
  35. data/original/examples/syntax/multiple.yaml +184 -0
  36. data/original/examples/syntax/multiple_formatted.exp +71 -0
  37. data/original/examples/syntax/multiple_hyperlink_formatted.exp +71 -0
  38. data/original/examples/syntax/multiple_schema_head_hyperlink_formatted.exp +13 -0
  39. data/original/examples/syntax/remark.exp +41 -41
  40. data/original/examples/syntax/remark.yaml +446 -0
  41. data/original/examples/syntax/remark_formatted.exp +62 -50
  42. data/original/examples/syntax/{simple.exp → single.exp} +1 -1
  43. data/original/examples/syntax/single.yaml +9 -0
  44. data/original/examples/syntax/single_formatted.exp +6 -0
  45. data/original/examples/syntax/single_formatted.yaml +19 -0
  46. data/original/examples/syntax/syntax.exp +29 -19
  47. data/original/examples/syntax/syntax.yaml +3439 -0
  48. data/original/examples/syntax/syntax_formatted.exp +271 -131
  49. data/original/examples/syntax/syntax_schema_head_formatted.exp +18 -0
  50. data/spec/expressir/express_exp/cache_spec.rb +64 -0
  51. data/spec/expressir/express_exp/formatter_spec.rb +111 -0
  52. data/spec/expressir/express_exp/parser_spec.rb +98 -0
  53. data/spec/expressir/model/{model_element/find_spec.rb → model_element_spec.rb} +96 -10
  54. metadata +20 -17
  55. data/original/examples/syntax/hyperlink_formatted.exp +0 -51
  56. data/original/examples/syntax/source.exp +0 -16
  57. data/spec/expressir/express_exp/formatter/remark_spec.rb +0 -28
  58. data/spec/expressir/express_exp/formatter/syntax_spec.rb +0 -28
  59. data/spec/expressir/express_exp/hyperlink_formatter_spec.rb +0 -24
  60. data/spec/expressir/express_exp/parser/head_source_spec.rb +0 -38
  61. data/spec/expressir/express_exp/parser/multiple_spec.rb +0 -37
  62. data/spec/expressir/express_exp/parser/remark_spec.rb +0 -411
  63. data/spec/expressir/express_exp/parser/source_spec.rb +0 -29
  64. data/spec/expressir/express_exp/parser/syntax_spec.rb +0 -3086
  65. data/spec/expressir/express_exp/schema_head_formatter_spec.rb +0 -36
  66. data/spec/expressir/model/model_element/hash_spec.rb +0 -66
@@ -1,8 +1,6 @@
1
- require "expressir/express_exp/formatter"
2
-
3
1
  module Expressir
4
2
  module ExpressExp
5
- class HyperlinkFormatter < Formatter
3
+ module HyperlinkFormatter
6
4
  def format_expressions_simple_reference(node)
7
5
  return node.id if node.parent.is_a? Model::Expressions::AttributeReference
8
6
 
@@ -6,54 +6,58 @@ rescue LoadError
6
6
  end
7
7
  require 'expressir/express_exp/visitor'
8
8
 
9
- module Expressir
10
- module ExpressExp
11
- class Parser
12
- def self.from_file(file)
13
- input = File.read(file)
14
-
15
9
  =begin
16
- char_stream = Antlr4::Runtime::CharStreams.from_string(input, 'String')
17
- lexer = ::ExpressParser::Lexer.new(char_stream)
18
- token_stream = Antlr4::Runtime::CommonTokenStream.new(lexer)
19
- parser = ::ExpressParser::Parser.new(token_stream)
10
+ char_stream = Antlr4::Runtime::CharStreams.from_string(input, 'String')
11
+ lexer = ::ExpressParser::Lexer.new(char_stream)
12
+ token_stream = Antlr4::Runtime::CommonTokenStream.new(lexer)
13
+ parser = ::ExpressParser::Parser.new(token_stream)
20
14
 
21
- # don't attempt to recover from any parsing error
22
- parser.instance_variable_set(:@_err_handler, Antlr4::Runtime::BailErrorStrategy.new)
15
+ # don't attempt to recover from any parsing error
16
+ parser.instance_variable_set(:@_err_handler, Antlr4::Runtime::BailErrorStrategy.new)
23
17
 
24
- parse_tree = parser.syntax()
18
+ parse_tree = parser.syntax()
25
19
 
26
- visitor = Visitor.new(token_stream)
27
- repo = visitor.visit(parse_tree)
20
+ visitor = Visitor.new(token_stream)
21
+ repo = visitor.visit(parse_tree)
28
22
  =end
29
23
 
24
+ module Expressir
25
+ module ExpressExp
26
+ class Parser
27
+ def self.from_file(file, options = {})
28
+ input = File.read(file)
29
+
30
30
  parser = ::ExpressParser::Parser.parse(input)
31
31
 
32
32
  parse_tree = parser.syntax()
33
33
 
34
- visitor = Visitor.new(parser.tokens)
35
- repo = visitor.visit(parse_tree)
34
+ visitor = Visitor.new(parser.tokens, options)
35
+ repository = visitor.visit(parse_tree)
36
36
 
37
- repo.schemas.each{|schema| schema.file = file}
37
+ repository.schemas.each do |schema|
38
+ schema.file = file.to_s
39
+ end
38
40
 
39
- repo
41
+ repository
40
42
  end
41
43
 
42
- def self.from_files(files)
43
- schemas = files.map{|file| self.from_file(file).schemas}.flatten
44
+ def self.from_files(files, options = {})
45
+ schemas = files.each_with_index.map do |file, i|
46
+ # start = Time.now
47
+ repository = self.from_file(file, options)
48
+ # STDERR.puts "#{i+1}/#{files.length} #{file} #{Time.now - start}"
49
+ repository.schemas
50
+ end.flatten
44
51
 
45
- repo = Model::Repository.new({
52
+ repository = Model::Repository.new({
46
53
  schemas: schemas
47
54
  })
48
55
 
49
- repo.schemas.each{|schema| schema.parent = repo}
50
-
51
- repo
52
- end
56
+ repository.schemas.each do |schema|
57
+ schema.parent = repository
58
+ end
53
59
 
54
- # deprecated
55
- def self.from_exp(file)
56
- self.from_file(file)
60
+ repository
57
61
  end
58
62
  end
59
63
  end
@@ -1,13 +1,8 @@
1
- require "expressir/express_exp/formatter"
2
-
3
1
  module Expressir
4
2
  module ExpressExp
5
- class SchemaHeadFormatter < Formatter
3
+ module SchemaHeadFormatter
6
4
  def format_schema(node)
7
- [
8
- "SCHEMA #{node.id}#{node.version ? " #{format(node.version)}" : ""};",
9
- *node.interfaces.map{|x| format(x)}
10
- ].join("\n")
5
+ format_schema_head(node)
11
6
  end
12
7
  end
13
8
  end
@@ -36,8 +36,10 @@ module Expressir
36
36
  class Visitor < ::ExpressParser::Visitor
37
37
  REMARK_CHANNEL = 2
38
38
 
39
- def initialize(tokens)
39
+ def initialize(tokens, options = {})
40
40
  @tokens = tokens
41
+ @include_source = options[:include_source]
42
+
41
43
  @attached_remark_tokens = ::Set.new
42
44
 
43
45
  super()
@@ -45,7 +47,9 @@ module Expressir
45
47
 
46
48
  def visit(ctx)
47
49
  node = super(ctx)
48
- attach_source(ctx, node)
50
+ if @include_source
51
+ attach_source(ctx, node)
52
+ end
49
53
  attach_remarks(ctx, node)
50
54
  node
51
55
  end
@@ -92,35 +96,11 @@ module Expressir
92
96
  @tokens[start_index..stop_index]
93
97
  end
94
98
 
95
- def get_head_tokens(ctx)
96
- start_index, stop_index = if ctx.is_a? ::ExpressParser::SchemaDeclContext
97
- start_index = ctx.start.token_index
98
- stop_index = if ctx.schema_body.interface_specification.length > 0
99
- ctx.schema_body.interface_specification.last.stop.token_index
100
- elsif ctx.schema_version_id
101
- ctx.schema_version_id.stop.token_index + 1
102
- else
103
- ctx.schema_id.stop.token_index + 1
104
- end
105
-
106
- [start_index, stop_index]
107
- end
108
-
109
- if start_index and stop_index
110
- @tokens[start_index..stop_index]
111
- end
112
- end
113
-
114
99
  def attach_source(ctx, node)
115
100
  if node.class.method_defined? :source
116
101
  tokens = get_tokens(ctx)
117
102
  node.source = get_tokens_source(tokens)
118
103
  end
119
-
120
- if node.class.method_defined? :head_source
121
- tokens = get_head_tokens(ctx)
122
- node.head_source = get_tokens_source(tokens)
123
- end
124
104
  end
125
105
 
126
106
  def find_remark_target(node, path)
@@ -145,6 +125,7 @@ module Expressir
145
125
  id: informal_proposition_id
146
126
  })
147
127
  target_node.informal_propositions << informal_proposition
128
+ target_node.reset_children_by_id
148
129
  informal_proposition.parent = target_node
149
130
  informal_proposition
150
131
  end
@@ -1949,8 +1930,8 @@ module Expressir
1949
1930
  entities = declarations.select{|x| x.is_a? Model::Entity}
1950
1931
  subtype_constraints = declarations.select{|x| x.is_a? Model::SubtypeConstraint}
1951
1932
  functions = declarations.select{|x| x.is_a? Model::Function}
1952
- procedures = declarations.select{|x| x.is_a? Model::Procedure}
1953
1933
  rules = declarations.select{|x| x.is_a? Model::Rule}
1934
+ procedures = declarations.select{|x| x.is_a? Model::Procedure}
1954
1935
 
1955
1936
  Model::Schema.new({
1956
1937
  id: id,
@@ -1961,8 +1942,8 @@ module Expressir
1961
1942
  entities: entities,
1962
1943
  subtype_constraints: subtype_constraints,
1963
1944
  functions: functions,
1964
- procedures: procedures,
1965
- rules: rules
1945
+ rules: rules,
1946
+ procedures: procedures
1966
1947
  })
1967
1948
  end
1968
1949
 
@@ -2173,7 +2154,7 @@ module Expressir
2173
2154
  id = visit_if(ctx__subtype_constraint_head__subtype_constraint_id)
2174
2155
  applies_to = visit_if(ctx__subtype_constraint_head__entity_ref)
2175
2156
  abstract = ctx__subtype_constraint_body__abstract_supertype && true
2176
- total_over = visit_if(ctx__subtype_constraint_body__total_over)
2157
+ total_over = visit_if(ctx__subtype_constraint_body__total_over, [])
2177
2158
  supertype_expression = visit_if(ctx__subtype_constraint_body__supertype_expression)
2178
2159
 
2179
2160
  Model::SubtypeConstraint.new({
@@ -1,5 +1,7 @@
1
1
  require 'expressir/model/model_element'
2
2
 
3
+ require 'expressir/model/cache'
4
+
3
5
  require 'expressir/model/identifier'
4
6
 
5
7
  require 'expressir/model/attribute'
@@ -0,0 +1,13 @@
1
+ module Expressir
2
+ module Model
3
+ class Cache < ModelElement
4
+ attr_accessor :version
5
+ attr_accessor :content
6
+
7
+ def initialize(options = {})
8
+ @version = options[:version]
9
+ @content = options[:content]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -28,12 +28,12 @@ module Expressir
28
28
  end
29
29
 
30
30
  def children
31
- items = []
32
- items.push(*@attributes)
33
- items.push(*@unique)
34
- items.push(*@where)
35
- items.push(*@informal_propositions)
36
- items
31
+ [
32
+ *attributes,
33
+ *unique,
34
+ *where,
35
+ *informal_propositions
36
+ ]
37
37
  end
38
38
  end
39
39
  end
@@ -19,9 +19,9 @@ module Expressir
19
19
  end
20
20
 
21
21
  def children
22
- items = []
23
- items.push(self)
24
- items
22
+ [
23
+ self
24
+ ]
25
25
  end
26
26
  end
27
27
  end
@@ -33,18 +33,22 @@ module Expressir
33
33
  super
34
34
  end
35
35
 
36
+ def enumeration_items
37
+ types.flat_map{|x| x.enumeration_items}
38
+ end
39
+
36
40
  def children
37
- items = []
38
- items.push(*@parameters)
39
- items.push(*@types)
40
- items.push(*@types.flat_map{|x| x.type.is_a?(Types::Enumeration) ? x.type.items : []})
41
- items.push(*@entities)
42
- items.push(*@subtype_constraints)
43
- items.push(*@functions)
44
- items.push(*@procedures)
45
- items.push(*@constants)
46
- items.push(*@variables)
47
- items
41
+ [
42
+ *parameters,
43
+ *types,
44
+ *enumeration_items,
45
+ *entities,
46
+ *subtype_constraints,
47
+ *functions,
48
+ *procedures,
49
+ *constants,
50
+ *variables
51
+ ]
48
52
  end
49
53
  end
50
54
  end
@@ -3,10 +3,13 @@ module Expressir
3
3
  class InformalProposition < ModelElement
4
4
  include Identifier
5
5
 
6
+ undef :source
7
+ undef :source=
8
+
6
9
  def initialize(options = {})
7
10
  @id = options[:id]
8
11
  @remarks = options.fetch(:remarks, [])
9
- @source = options[:source]
12
+ # @source = options[:source]
10
13
 
11
14
  super
12
15
  end
@@ -3,12 +3,15 @@ module Expressir
3
3
  class InterfacedItem < ModelElement
4
4
  include Identifier
5
5
 
6
+ undef :source
7
+ undef :source=
8
+
6
9
  attr_accessor :base_item
7
10
 
8
11
  def initialize(options = {})
9
12
  @id = options[:id]
10
13
  @remarks = options.fetch(:remarks, [])
11
- @source = options[:source]
14
+ # @source = options[:source]
12
15
 
13
16
  @base_item = options[:base_item]
14
17
 
@@ -1,7 +1,12 @@
1
+ require 'pathname'
2
+
1
3
  module Expressir
2
4
  module Model
3
5
  class ModelElement
4
6
  CLASS_KEY = '_class'
7
+ FILE_KEY = 'file'
8
+ PARENT_KEY = 'parent'
9
+ CHILDREN_BY_ID_KEY = 'children_by_id'
5
10
  SOURCE_KEY = 'source'
6
11
 
7
12
  attr_accessor :parent
@@ -10,6 +15,11 @@ module Expressir
10
15
  attach_parent_to_children
11
16
  end
12
17
 
18
+ def model_instance_variables
19
+ skip_variables = [FILE_KEY, PARENT_KEY, CHILDREN_BY_ID_KEY].map{|x| "@#{x}".to_sym}
20
+ instance_variables.select{|x| !skip_variables.include?(x)}
21
+ end
22
+
13
23
  def path
14
24
  return id if is_a? Statements::Alias or is_a? Statements::Repeat or is_a? Expressions::QueryExpression
15
25
 
@@ -28,7 +38,7 @@ module Expressir
28
38
  end
29
39
 
30
40
  def attach_parent_to_children
31
- instance_variables.select{|x| x != :@parent}.each do |variable|
41
+ model_instance_variables.each do |variable|
32
42
  value = instance_variable_get(variable)
33
43
 
34
44
  if value.is_a? Array
@@ -57,7 +67,7 @@ module Expressir
57
67
  # find in current scope
58
68
  current_node = current_scope
59
69
  path_parts.each do |current_path|
60
- current_node = current_node.children.find{|x| x.id and x.id.downcase == current_path}
70
+ current_node = current_node.children_by_id[current_path]
61
71
  break unless current_node
62
72
  end
63
73
  target_node = current_node
@@ -75,20 +85,33 @@ module Expressir
75
85
  []
76
86
  end
77
87
 
88
+ def children_by_id
89
+ @children_by_id ||= children.select{|x| x.id}.map{|x| [x.id.downcase, x]}.to_h
90
+ end
91
+
92
+ def reset_children_by_id
93
+ @children_by_id = nil
94
+ end
95
+
78
96
  def to_hash(options = {})
79
- skip_empty = options[:skip_empty]
97
+ root_path = options[:root_path]
80
98
  formatter = options[:formatter]
99
+ include_empty = options[:include_empty] || !options[:skip_empty] # TODO: remove skip_empty
81
100
 
82
101
  hash = {}
83
102
  hash[CLASS_KEY] = self.class.name
103
+ if self.is_a? Schema and file
104
+ hash[FILE_KEY] = root_path ? Pathname.new(file).relative_path_from(root_path).to_s : file
105
+ end
84
106
 
85
- instance_variables.select{|x| x != :@parent}.each_with_object(hash) do |variable, result|
107
+ model_instance_variables.each do |variable|
86
108
  key = variable.to_s.sub(/^@/, '')
87
109
  value = instance_variable_get(variable)
110
+ empty = value.nil? || (value.is_a?(Array) && value.count == 0)
88
111
 
89
- # skip empty values (nil, empty array)
90
- if !skip_empty or !(value.nil? or (value.is_a? Array and value.count == 0))
91
- result[key] = if value.is_a? Array
112
+ # skip empty values
113
+ if !empty or include_empty
114
+ hash[key] = if value.is_a? Array
92
115
  value.map do |value|
93
116
  if value.is_a? ModelElement
94
117
  value.to_hash(options)
@@ -104,28 +127,35 @@ module Expressir
104
127
  end
105
128
  end
106
129
 
107
- if formatter
130
+ if self.class.method_defined? :source and formatter
108
131
  hash[SOURCE_KEY] = formatter.format(self)
109
132
  end
110
133
 
111
134
  hash
112
135
  end
113
136
 
114
- def self.from_hash(hash)
137
+ def self.from_hash(hash, options = {})
138
+ root_path = options[:root_path]
139
+
115
140
  node_class = hash[CLASS_KEY]
116
- node_options = hash.select{|x| x != CLASS_KEY}.each_with_object({}) do |(variable, value), result|
141
+ node_options = {}
142
+ if node_class == 'Expressir::Model::Schema' and hash[FILE_KEY]
143
+ node_options[FILE_KEY.to_sym] = root_path ? File.expand_path("#{root_path}/#{hash[FILE_KEY]}") : hash[FILE_KEY]
144
+ end
145
+
146
+ hash.select{|x| x != CLASS_KEY && x != FILE_KEY}.each do |variable, value|
117
147
  key = variable.to_sym
118
148
 
119
- result[key] = if value.is_a? Array
149
+ node_options[key] = if value.is_a? Array
120
150
  value.map do |value|
121
151
  if value.is_a? Hash
122
- self.from_hash(value)
152
+ self.from_hash(value, options)
123
153
  else
124
154
  value
125
155
  end
126
156
  end
127
157
  elsif value.is_a? Hash
128
- self.from_hash(value)
158
+ self.from_hash(value, options)
129
159
  else
130
160
  value
131
161
  end