defmastership 1.0.16 → 1.0.18

Sign up to get free protection for your applications and to get access to all the features.
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