defmastership 1.0.16 → 1.0.18

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitlab-ci.yml +50 -7
  4. data/.rubocop.yml +14 -6
  5. data/Gemfile +51 -1
  6. data/Rakefile +16 -47
  7. data/bin/defmastership +12 -9
  8. data/config/mutant.yml +23 -3
  9. data/defmastership.gemspec +22 -27
  10. data/features/definition_checksum.feature +31 -1
  11. data/features/export.feature +43 -1
  12. data/features/rename_included_files.feature +28 -0
  13. data/lib/defmastership/batch_modifier.rb +17 -12
  14. data/lib/defmastership/change_ref_modifier.rb +89 -5
  15. data/lib/defmastership/comment_filter.rb +1 -1
  16. data/lib/defmastership/constants.rb +5 -4
  17. data/lib/defmastership/csv_formatter.rb +20 -16
  18. data/lib/defmastership/csv_formatter_body.rb +18 -15
  19. data/lib/defmastership/csv_formatter_header.rb +1 -1
  20. data/lib/defmastership/definition.rb +58 -19
  21. data/lib/defmastership/document.rb +109 -74
  22. data/lib/defmastership/matching_line.rb +17 -0
  23. data/lib/defmastership/modifier.rb +42 -0
  24. data/lib/defmastership/modifier_factory.rb +12 -0
  25. data/lib/defmastership/parsing_state.rb +15 -9
  26. data/lib/defmastership/rename_included_files_modifier.rb +172 -5
  27. data/lib/defmastership/set_join_hack.rb +11 -0
  28. data/lib/defmastership/update_def_checksum_modifier.rb +8 -13
  29. data/lib/defmastership/update_def_modifier.rb +49 -0
  30. data/lib/defmastership/update_def_version_modifier.rb +56 -15
  31. data/lib/defmastership/version.rb +1 -1
  32. data/lib/defmastership.rb +7 -17
  33. data/spec/spec_helper.rb +4 -2
  34. data/spec/unit/{defmastership → def_mastership}/batch_modifier_spec.rb +42 -39
  35. data/spec/unit/{defmastership/change_ref_line_modifier_spec.rb → def_mastership/change_ref_modifier_spec.rb} +44 -66
  36. data/spec/unit/{defmastership → def_mastership}/csv_formatter_body_spec.rb +61 -32
  37. data/spec/unit/{defmastership → def_mastership}/csv_formatter_header_spec.rb +2 -2
  38. data/spec/unit/{defmastership → def_mastership}/csv_formatter_spec.rb +81 -86
  39. data/spec/unit/{defmastership → def_mastership}/definition_parser_spec.rb +2 -2
  40. data/spec/unit/{defmastership → def_mastership}/definition_spec.rb +17 -7
  41. data/spec/unit/{defmastership → def_mastership}/document_spec.rb +108 -53
  42. data/spec/unit/def_mastership/matching_line_spec.rb +37 -0
  43. data/spec/unit/def_mastership/modifier_factory_spec.rb +37 -0
  44. data/spec/unit/def_mastership/modifier_spec.rb +83 -0
  45. data/spec/unit/{defmastership → def_mastership}/parsing_state_spec.rb +16 -16
  46. data/spec/unit/{defmastership/rename_included_files_line_modifier_spec.rb → def_mastership/rename_included_files_modifier_spec.rb} +72 -36
  47. data/spec/unit/{defmastership/comment_filter_spec.rb → def_mastership/string_spec.rb} +1 -1
  48. data/spec/unit/def_mastership/update_def_checksum_modifier_spec.rb +107 -0
  49. data/spec/unit/def_mastership/update_def_modifier_spec.rb +119 -0
  50. data/spec/unit/def_mastership/update_def_version_modifier_spec.rb +159 -0
  51. data/spec/unit/{defmastership_spec.rb → def_mastership_spec.rb} +1 -1
  52. data/tasks/console.rake +8 -0
  53. data/tasks/package.task +9 -0
  54. data/tasks/smelling_code.rake +38 -0
  55. data/tasks/test.rake +45 -0
  56. metadata +37 -145
  57. data/lib/defmastership/change_ref_line_modifier.rb +0 -82
  58. data/lib/defmastership/line_modifier_base.rb +0 -29
  59. data/lib/defmastership/modifier_base.rb +0 -29
  60. data/lib/defmastership/rename_included_files_line_modifier.rb +0 -126
  61. data/lib/defmastership/update_def_checksum_line_modifier.rb +0 -38
  62. data/lib/defmastership/update_def_version_line_modifier.rb +0 -58
  63. data/spec/unit/defmastership/change_ref_modifier_spec.rb +0 -76
  64. data/spec/unit/defmastership/rename_included_files_modifier_spec.rb +0 -67
  65. data/spec/unit/defmastership/update_def_checksum_line_modifier_spec.rb +0 -78
  66. data/spec/unit/defmastership/update_def_checksum_modifier_spec.rb +0 -75
  67. data/spec/unit/defmastership/update_def_version_line_modifier_spec.rb +0 -127
  68. data/spec/unit/defmastership/update_def_version_modifier_spec.rb +0 -80
@@ -1,15 +1,99 @@
1
1
  # Copyright (c) 2020 Jerome Arbez-Gindre
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'defmastership/constants'
5
+ require 'defmastership/modifier'
6
+
4
7
  module DefMastership
5
- # Change all refs of a given project
6
- class ChangeRefModifier < ModifierBase
7
- def replacements
8
+ # Change references from temporary to definitive with multiple RefChangers
9
+ class ChangeRefModifier
10
+ include Modifier
11
+
12
+ REGEXP_FROM = {
13
+ definition: {
14
+ before: DMRegexp::DEF_BEFORE_REF,
15
+ after: DMRegexp::DEF_AFTER_REF
16
+ },
17
+ iref: {
18
+ before: DMRegexp::IREF_DEF_BEF,
19
+ after: DMRegexp::IREF_DEF_AFT
20
+ }
21
+ }.freeze
22
+
23
+ private_constant :REGEXP_FROM
24
+
25
+ def self.replacement_methods
8
26
  %i[replace_refdef replace_irefs]
9
27
  end
10
28
 
11
- def new_line_modifier(config, _adoc_texts)
12
- ChangeRefLineModifier.from_config(config)
29
+ def self.default_config
30
+ {
31
+ from_regexp: '',
32
+ to_template: '',
33
+ next_ref: 0
34
+ }
35
+ end
36
+
37
+ def initialize(config)
38
+ @parsing_state = ParsingState.new
39
+
40
+ setup_modifier_module(config)
41
+ end
42
+
43
+ def replace(method, line)
44
+ public_send(:"replace_#{method}", line)
45
+ end
46
+
47
+ def replace_refdef(line)
48
+ if @parsing_state.enabled?(line)
49
+ do_replace_refdef(line)
50
+ else
51
+ line
52
+ end
53
+ end
54
+
55
+ def replace_irefs(line)
56
+ changes.reduce(line) do |res_line, (from, to)|
57
+ res_line.gsub(Helper.regexp_from(:iref, from)) do
58
+ Helper.text_with(Regexp.last_match, to)
59
+ end
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def do_replace_refdef(line)
66
+ line.sub(Helper.regexp_from(:definition, from_regexp)) do
67
+ replacement_from(Regexp.last_match)
68
+ end
69
+ end
70
+
71
+ def replacement_from(match)
72
+ replacement = to_template % hmerge(match)
73
+ changes << [match[:from], replacement]
74
+ config[:next_ref] += 1
75
+ Helper.text_with(match, replacement)
76
+ end
77
+
78
+ def hmerge(match)
79
+ config.merge(match.named_captures.transform_keys(&:to_sym))
80
+ end
81
+
82
+ # Helper functions
83
+ module Helper
84
+ def self.regexp_from(const, from)
85
+ regexps = REGEXP_FROM.fetch(const)
86
+ regexp_str =
87
+ "(?<before>#{regexps[:before]})" \
88
+ "(?<from>#{from})" \
89
+ "#{DMRegexp::DEF_VERSION_AND_CHECKSUM}" \
90
+ "(?<after>#{regexps[:after]})"
91
+ Regexp.new(regexp_str, Regexp::EXTENDED)
92
+ end
93
+
94
+ def self.text_with(match, replacement)
95
+ match[:before] + replacement + (match[:version_and_checksum] || '') + match[:after]
96
+ end
13
97
  end
14
98
  end
15
99
  end
@@ -5,6 +5,6 @@
5
5
  # not.
6
6
  class String
7
7
  def commented?
8
- !match(DefMastership::DMRegexp::SINGLE_LINE_COMMENT).nil?
8
+ !!match(DefMastership::DMRegexp::SINGLE_LINE_COMMENT)
9
9
  end
10
10
  end
@@ -3,6 +3,7 @@
3
3
 
4
4
  module DefMastership
5
5
  # set of regexp of added asciidoctor constructions
6
+ # This module smells of :reek:TooManyConstants
6
7
  module DMRegexp
7
8
  SINGLE_LINE_COMMENT = %r{^//[^/]}.freeze
8
9
 
@@ -27,8 +28,8 @@ module DefMastership
27
28
  Regexp::EXTENDED
28
29
  )
29
30
 
30
- VARIABLE_DEF = /^\s*:(?<varname>[\w:_-]+):\s*
31
- \s*(?<value>\S.*\S)\s*$/x.freeze
31
+ VARIABLE_DEF = /^\s*:(?<varname>[\w:_-]+):\s+
32
+ (?<value>\S.*\S)\s*$/x.freeze
32
33
 
33
34
  VARIABLE_USE = /{(?<varname>[\w:_-]+)}/x.freeze
34
35
 
@@ -37,7 +38,7 @@ module DefMastership
37
38
  EREF_DEF = /^\s*
38
39
  defs:eref\[
39
40
  \s*(?<refname>[\w:_-]+)\s*,
40
- \s*\[(?<extrefs>[^\]]+)\]\s*\]/x.freeze
41
+ \s*\[\s*(?<extrefs>[^\]]+?)\s*\]\s*\]/x.freeze
41
42
  BLOCK = /^--\s*$/.freeze
42
43
 
43
44
  IREF_DEF_BEF = 'defs:iref\[\s*'
@@ -61,7 +62,7 @@ module DefMastership
61
62
  INCLUDE_KEYWORD = '\binclude::'
62
63
  INCLUDE_PATH = '(?<path>.*/)?'
63
64
  INCLUDE_FILENAME = '(?<filename>[^\\/]+)'
64
- INCLUDE_OPTIONS = '\[(?<options>[\]]*)\]'
65
+ INCLUDE_OPTIONS = '\[(?<options>[^\]]*)\]'
65
66
 
66
67
  INCLUDE = Regexp.new(
67
68
  INCLUDE_KEYWORD + INCLUDE_PATH + INCLUDE_FILENAME + INCLUDE_OPTIONS,
@@ -2,48 +2,52 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require('csv')
5
- require('defmastership/csv_formatter_header')
6
5
  require('defmastership/csv_formatter_body')
6
+ require('defmastership/csv_formatter_header')
7
7
 
8
8
  module DefMastership
9
9
  # to export a CSV file
10
10
  class CSVFormatter
11
- def initialize(doc, sep = ',')
11
+ def initialize(doc, sep)
12
12
  @doc = doc
13
13
  @sep = sep
14
14
  end
15
15
 
16
16
  def export_to(output_file)
17
17
  column_list = build_column_list
18
- CSV.open(output_file, 'w:ISO-8859-1', { col_sep: @sep }) do |csv|
18
+ CSV.open(output_file, 'w:ISO-8859-1', col_sep: @sep) do |csv|
19
19
  csv << header(column_list)
20
- @doc.definitions.each { |definition| csv << body(definition, column_list) }
20
+ export_definitions_in(csv, column_list)
21
21
  end
22
22
  end
23
23
 
24
24
  private
25
25
 
26
+ def export_definitions_in(csv, column_list)
27
+ @doc.definitions.each { |definition| csv << body(definition, column_list) }
28
+ end
29
+
26
30
  def header(column_list)
27
31
  header_formatter = CSVFormatterHeader.new(@doc)
28
32
  header_line = column_list.map { |part| header_formatter.public_send(part) }
29
- header_line.reduce(:+)
33
+ header_line.flatten
30
34
  end
31
35
 
32
36
  def body(definition, column_list)
33
- body_formatter = CSVFormatterBody.new(@doc)
34
- body_line = column_list.map { |part| body_formatter.public_send(part, definition) }
35
- body_line.reduce(:+)
37
+ body_formatter = CSVFormatterBody.new(@doc, definition)
38
+ body_line = column_list.map { |part| body_formatter.public_send(part) }
39
+ body_line.flatten
36
40
  end
37
41
 
38
42
  def build_column_list
39
- column_list = [:fixed]
40
- column_list += [:wrong_explicit_checksum] if @doc.wrong_explicit_checksum?
41
- column_list += [:explicit_version] if @doc.explicit_version?
42
- column_list += [:labels] unless @doc.labels.empty?
43
- column_list += [:eref] unless @doc.eref.empty?
44
- column_list += [:iref] if @doc.iref
45
- column_list += [:attributes] unless @doc.attributes.empty?
46
- column_list
43
+ [
44
+ [:wrong_explicit_checksum, @doc.wrong_explicit_checksum?],
45
+ [:explicit_version, @doc.explicit_version?],
46
+ [:labels, !@doc.labels.empty?],
47
+ [:eref, !@doc.eref.empty?],
48
+ [:iref, @doc.iref],
49
+ [:attributes, !@doc.attributes.empty?]
50
+ ].reduce([:fixed]) { |acc, elem| acc + (elem.fetch(1) ? [elem.first] : []) }
47
51
  end
48
52
  end
49
53
  end
@@ -3,41 +3,44 @@
3
3
 
4
4
  require('csv')
5
5
 
6
+ require('defmastership/set_join_hack')
7
+
6
8
  module DefMastership
7
9
  # format lines per definition
8
10
  class CSVFormatterBody
9
- def initialize(doc)
11
+ def initialize(doc, definition)
10
12
  @doc = doc
13
+ @definition = definition
11
14
  end
12
15
 
13
- def fixed(definition)
14
- [definition.type, definition.reference, definition.value, definition.sha256]
16
+ def fixed
17
+ [@definition.type, @definition.reference, @definition.value, @definition.sha256_short]
15
18
  end
16
19
 
17
- def wrong_explicit_checksum(definition)
18
- wrong_explicit_checksum = definition.wrong_explicit_checksum
20
+ def wrong_explicit_checksum
21
+ wrong_explicit_checksum = @definition.wrong_explicit_checksum
19
22
  wrong_explicit_checksum ? [wrong_explicit_checksum] : ['']
20
23
  end
21
24
 
22
- def explicit_version(definition)
23
- explicit_version = definition.explicit_version
25
+ def explicit_version
26
+ explicit_version = @definition.explicit_version
24
27
  explicit_version ? [explicit_version] : ['']
25
28
  end
26
29
 
27
- def labels(definition)
28
- [definition.labels.to_a.join("\n")]
30
+ def labels
31
+ [@definition.labels.join("\n")]
29
32
  end
30
33
 
31
- def eref(definition)
32
- @doc.eref.map { |key, _| definition.eref[key].join("\n") }
34
+ def eref
35
+ @doc.eref.map { |key,| @definition.eref.fetch(key, []).join("\n") }
33
36
  end
34
37
 
35
- def iref(definition)
36
- [definition.iref.join("\n")]
38
+ def iref
39
+ [@definition.iref.join("\n")]
37
40
  end
38
41
 
39
- def attributes(definition)
40
- @doc.attributes.map { |key, _| definition.attributes[key] }
42
+ def attributes
43
+ @doc.attributes.map { |key,| @definition.attributes.fetch(key, '') }
41
44
  end
42
45
  end
43
46
  end
@@ -27,7 +27,7 @@ module DefMastership
27
27
  end
28
28
 
29
29
  def eref
30
- @doc.eref.map { |_, ref| ref[:prefix] }
30
+ @doc.eref.map { |_, ref| ref.fetch(:prefix) }
31
31
  end
32
32
 
33
33
  def iref
@@ -3,51 +3,90 @@
3
3
 
4
4
  require 'digest'
5
5
 
6
+ # Contains the content of a DefMastership definition
6
7
  module DefMastership
8
+ BUILD_FROM_MATCH = {
9
+ type: ->(match) { match[:type] },
10
+ reference: ->(match) { match[:reference] },
11
+ lines: ->(_) { [] },
12
+ labels: lambda do |match|
13
+ labels = Set.new
14
+ labels.merge(match[:labels].split(/\s*,\s*/).to_set) if match[:labels]
15
+ labels
16
+ end,
17
+ eref: ->(_) { Hash.new([]) },
18
+ iref: ->(_) { [] },
19
+ attributes: ->(_) { {} },
20
+ explicit_checksum: ->(match) { match[:explicit_checksum] },
21
+ explicit_version: ->(match) { match[:explicit_version] }
22
+ }.freeze
23
+
24
+ private_constant :BUILD_FROM_MATCH
25
+
26
+ # Class to host data of Definition class
27
+ DefinitionData = Struct.new(
28
+ :type,
29
+ :reference,
30
+ :lines,
31
+ :labels,
32
+ :eref,
33
+ :iref,
34
+ :attributes,
35
+ :explicit_checksum,
36
+ :explicit_version
37
+ )
38
+
39
+ private_constant :DefinitionData
40
+
7
41
  # DefMastership definition: contains all data of a definition
8
42
  class Definition
9
- attr_reader :type, :reference, :lines, :labels, :eref, :iref, :attributes, :explicit_version
43
+ extend Forwardable
44
+ def_delegators :@data,
45
+ :type,
46
+ :reference,
47
+ :lines,
48
+ :labels,
49
+ :eref,
50
+ :iref,
51
+ :attributes,
52
+ :explicit_checksum,
53
+ :explicit_version
10
54
 
11
55
  def initialize(match)
12
- @type = match[:type]
13
- @reference = match[:reference]
14
- @lines = []
15
- @labels = Set.new
16
- @labels.merge(match[:labels].split(/\s*,\s*/).to_set) if match[:labels]
17
- @eref = Hash.new([])
18
- @iref = []
19
- @attributes = {}
20
- @explicit_checksum = match[:explicit_checksum]
21
- @explicit_version = match[:explicit_version]
56
+ @data = DefinitionData.new(
57
+ *BUILD_FROM_MATCH.transform_values { |lamb| lamb.call(match) }
58
+ .fetch_values(*DefinitionData.members)
59
+ )
22
60
  end
23
61
 
24
62
  def <<(new_line)
25
- @lines << new_line
63
+ lines << new_line
26
64
  self
27
65
  end
28
66
 
29
67
  def value
30
- @lines.join("\n")
68
+ lines.join("\n")
31
69
  end
32
70
 
33
- def sha256
34
- "~#{Digest::SHA2.new(256).hexdigest(value).chars.last(8).join}"
71
+ def sha256_short
72
+ "~#{Digest::SHA2.hexdigest(value).chars.last(8).join}"
35
73
  end
36
74
 
37
75
  def wrong_explicit_checksum
38
- @explicit_checksum if @explicit_checksum != sha256
76
+ explicit_checksum unless explicit_checksum.eql?(sha256_short)
39
77
  end
40
78
 
41
79
  def add_eref(refname, extrefs)
42
- @eref[refname] = extrefs.strip.split(/\s*,\s*/)
80
+ eref[refname] = extrefs.strip.split(/\s*,\s*/)
43
81
  end
44
82
 
45
83
  def add_iref(ref)
46
- @iref << ref
84
+ iref << ref
47
85
  end
48
86
 
49
87
  def set_attribute(key, value)
50
- @attributes[key] = value
88
+ attributes[key] = value
51
89
  end
52
90
  end
91
+ public_constant :Definition
53
92
  end
@@ -2,21 +2,87 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require('asciidoctor')
5
+ require('defmastership/matching_line')
5
6
 
7
+ # Contains the content of a DefMastership document: mainly definitions
6
8
  module DefMastership
7
- # Contains the content of a DefMastership document: mainly definitions
9
+ # Class to host data of Document class
10
+ DocumentData = Struct.new(
11
+ :definitions,
12
+ :labels,
13
+ :eref,
14
+ :iref,
15
+ :attributes,
16
+ :variables
17
+ )
18
+
19
+ private_constant :DocumentData
20
+
21
+ PARSER_ACTIONS = {
22
+ add_new_definition: lambda { |matching_line|
23
+ definition = Definition.new(matching_line.match)
24
+ labels.merge(definition.labels)
25
+ definitions << definition
26
+ matching_line.line
27
+ },
28
+ add_line: lambda { |matching_line|
29
+ line = matching_line.line
30
+ definitions.last << line
31
+ line
32
+ },
33
+ new_eref_setup: lambda { |matching_line|
34
+ refname = matching_line[:refname].to_sym
35
+ eref[refname] ||= {}
36
+ eref[refname][matching_line[:symb].to_sym] = matching_line[:value]
37
+ matching_line.line
38
+ },
39
+ new_eref_def: lambda { |matching_line|
40
+ definitions.last.add_eref(matching_line[:refname].to_sym, matching_line[:extrefs])
41
+ matching_line.line
42
+ },
43
+ new_iref_def: lambda { |matching_line|
44
+ self.iref = true
45
+ line = matching_line.line
46
+ line.scan(DMRegexp::IREF_DEF) do |_|
47
+ definitions.last.add_iref(Regexp.last_match[:intref])
48
+ end
49
+ line
50
+ },
51
+ new_attribute_conf: lambda { |matching_line|
52
+ attributes[matching_line[:attr].to_sym] = matching_line[:prefix]
53
+ matching_line.line
54
+ },
55
+ new_attribute_value: lambda { |matching_line|
56
+ definitions.last.set_attribute(matching_line[:attr].to_sym, matching_line[:value])
57
+ matching_line.line
58
+ },
59
+ new_variable_def: lambda { |matching_line|
60
+ variables[matching_line[:varname].to_sym] = matching_line[:value]
61
+ matching_line.line
62
+ },
63
+ new_variable_use: lambda { |matching_line|
64
+ line = matching_line.line
65
+ line.scan(DMRegexp::VARIABLE_USE) do |_|
66
+ varname = Regexp.last_match[:varname]
67
+ value = variables[varname.to_sym]
68
+
69
+ next unless value
70
+
71
+ line = line.gsub("{#{varname}}", value)
72
+ end
73
+ line
74
+ }
75
+ }.freeze
76
+
77
+ private_constant :PARSER_ACTIONS
8
78
 
9
79
  # Reflects document structure from a definition point of view
10
80
  class Document
11
- attr_reader :definitions, :labels, :eref, :iref, :attributes, :variables
81
+ extend Forwardable
82
+ def_delegators :@data, :definitions, :labels, :eref, :iref, :attributes, :variables
12
83
 
13
84
  def initialize
14
- @definitions = []
15
- @labels = Set.new
16
- @eref = {}
17
- @iref = false
18
- @attributes = {}
19
- @variables = {}
85
+ @data = DocumentData.new([], Set.new, {}, false, {}, {})
20
86
  @parsing_state = ParsingState.new
21
87
  @definition_parser = DefinitionParser.new(self)
22
88
  end
@@ -26,7 +92,7 @@ module DefMastership
26
92
  if @parsing_state.enabled?(line)
27
93
  apply_filters(line)
28
94
  else
29
- generate_event(:new_line, nil, line)
95
+ generate_event(:new_line, MatchingLine.new(nil, line))
30
96
  end
31
97
  end
32
98
  end
@@ -36,96 +102,65 @@ module DefMastership
36
102
  end
37
103
 
38
104
  def wrong_explicit_checksum?
39
- @definitions.reduce(false) do |res, definition|
40
- res || !definition.wrong_explicit_checksum.nil?
105
+ definitions.reduce(false) do |res, definition|
106
+ res || !!definition.wrong_explicit_checksum
41
107
  end
42
108
  end
43
109
 
44
110
  def explicit_version?
45
- @definitions.reduce(false) do |res, definition|
46
- res || !definition.explicit_version.nil?
111
+ definitions.reduce(false) do |res, definition|
112
+ res || !!definition.explicit_version
47
113
  end
48
114
  end
49
115
 
50
- def add_new_definition(match, line)
51
- definition = Definition.new(match)
52
- @labels.merge(definition.labels)
53
- @definitions << definition
54
- line
55
- end
56
-
57
- def ref_to_def(ref)
58
- @definitions.find { |definition| definition.reference == ref }
59
- end
116
+ def method_missing(method_name, *args)
117
+ action = PARSER_ACTIONS[method_name]
118
+ return instance_exec(*args, &action) if action
60
119
 
61
- def add_line(_match, line)
62
- @definitions.last << line
63
- line
120
+ super
64
121
  end
65
122
 
66
- def new_eref_setup(match, line)
67
- @eref[match[:refname].to_sym] ||= {}
68
- @eref[match[:refname].to_sym][match[:symb].to_sym] = match[:value]
69
- line
123
+ # This method smells of :reek:UtilityFunction
124
+ def respond_to_missing?(method_name, *_args)
125
+ PARSER_ACTIONS.key?(method_name)
70
126
  end
71
127
 
72
- def new_eref_def(match, line)
73
- @definitions.last.add_eref(match[:refname].to_sym, match[:extrefs])
74
- line
75
- end
76
-
77
- def new_iref_def(_match, line)
78
- @iref = true
79
- line.scan(DMRegexp::IREF_DEF) do |_|
80
- @definitions.last.add_iref(Regexp.last_match[:intref])
81
- end
82
- line
128
+ def ref_to_def(ref)
129
+ definitions.find { |definition| definition.reference == ref }
83
130
  end
84
131
 
85
- def new_attribute_conf(match, line)
86
- @attributes[match[:attr].to_sym] = match[:prefix]
87
- line
132
+ def iref=(value)
133
+ @data.iref = value
88
134
  end
89
135
 
90
- def new_attribute_value(match, line)
91
- @definitions.last.set_attribute(match[:attr].to_sym, match[:value])
92
- line
93
- end
136
+ private
94
137
 
95
- def new_variable_def(match, line)
96
- @variables[match[:varname].to_sym] = match[:value]
97
- line
138
+ def apply_filters(line)
139
+ Helper.reduce_filters_until_consumed(line) do |event, match, updated_line|
140
+ generate_event(event, MatchingLine.new(match, updated_line))
141
+ end
98
142
  end
99
143
 
100
- def new_variable_use(_match, line)
101
- line.scan(DMRegexp::VARIABLE_USE) do |_|
102
- varname = Regexp.last_match[:varname]
103
- next if @variables[varname.to_sym].nil?
104
-
105
- line = line.gsub("{#{varname}}", @variables[varname.to_sym])
144
+ def generate_event(event, matching_line)
145
+ if PARSER_ACTIONS.key?(event)
146
+ public_send(event, matching_line)
147
+ else
148
+ @definition_parser.public_send(event, matching_line)
106
149
  end
107
- line
108
150
  end
109
151
 
110
- private
111
-
112
- def apply_filters(line)
113
- FILTERS.each do |filter|
114
- next unless line.match(filter.regexp)
152
+ # Helper functions
153
+ module Helper
154
+ def self.reduce_filters_until_consumed(line)
155
+ FILTERS.reduce(line) do |res, filter|
156
+ next res unless line.match(filter.regexp)
115
157
 
116
- line = generate_event(filter.event, Regexp.last_match, line)
158
+ res = yield(filter.event, Regexp.last_match, res)
159
+ break if filter.consumed_line
117
160
 
118
- break if filter.consumed_line
119
- end
120
- end
121
-
122
- def generate_event(event, match, line)
123
- if respond_to?(event)
124
- line = public_send(event, match, line)
125
- else
126
- @definition_parser.public_send(event, match, line)
161
+ res
162
+ end
127
163
  end
128
- line
129
164
  end
130
165
  end
131
166
  end
@@ -0,0 +1,17 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ module DefMastership
5
+ # a composite class
6
+ MatchingLine =
7
+ Struct.new(:match, :line) do
8
+ def [](key)
9
+ value = match[key]
10
+ return value if value
11
+
12
+ super
13
+ end
14
+ end
15
+
16
+ public_constant :MatchingLine
17
+ end