class YamlLint::Linter::KeyOverlapDetector
Detects duplicate keys in Psych parsed data
Attributes
overlapping_keys[R]
Public Class Methods
new()
click to toggle source
Setup class variables
# File lib/yamllint/linter.rb, line 133 def initialize @seen_keys = Set.new @key_components = [] @last_key = [''] @overlapping_keys = Set.new @complex_type = [] @array_positions = [] end
Public Instance Methods
parse(psych_parse_data)
click to toggle source
Get the data and send it off for duplicate key validation
# File lib/yamllint/linter.rb, line 143 def parse(psych_parse_data) data_start = psych_parse_data.handler.root.children[0] parse_recurse(data_start) end
Private Instance Methods
add_value(value, key)
click to toggle source
Add a key / value pair
# File lib/yamllint/linter.rb, line 219 def add_value(value, key) YamlLint.logger.debug { "add_value: #{value.inspect}, #{key.inspect}" } case @complex_type.last when :hash @key_components.push(key) check_for_overlap! @key_components.pop when :array @key_components.push(@array_positions.last) check_for_overlap! @array_positions[-1] += 1 @key_components.pop end end
array_end(key)
click to toggle source
Tear down the array
# File lib/yamllint/linter.rb, line 210 def array_end(key) YamlLint.logger.debug { "array_end: #{key.inspect}" } @key_components.pop @complex_type.pop @array_positions.pop end
array_start(key)
click to toggle source
Setup a new array
# File lib/yamllint/linter.rb, line 199 def array_start(key) YamlLint.logger.debug { "array_start: #{key.inspect}" } complex_type_start(key) @complex_type.push(:array) @array_positions.push(0) check_for_overlap! end
check_for_overlap!()
click to toggle source
Check for key overlap
# File lib/yamllint/linter.rb, line 236 def check_for_overlap! full_key = @key_components.dup YamlLint.logger.debug { "Checking #{full_key.join('.')} for overlap" } return if @seen_keys.add?(full_key) YamlLint.logger.debug { "Overlapping key #{full_key.join('.')}" } @overlapping_keys << full_key end
complex_type_start(key)
click to toggle source
Setup common hash and array elements
# File lib/yamllint/linter.rb, line 246 def complex_type_start(key) case @complex_type.last when :hash @key_components.push(key) when :array @key_components.push(@array_positions.last) @array_positions[-1] += 1 end end
hash_end(key)
click to toggle source
Tear down a hash
# File lib/yamllint/linter.rb, line 191 def hash_end(key) YamlLint.logger.debug { "hash_end: #{key.inspect}" } @key_components.pop @complex_type.pop end
hash_start(key)
click to toggle source
Setup a new hash
# File lib/yamllint/linter.rb, line 181 def hash_start(key) YamlLint.logger.debug { "hash_start: #{key.inspect}" } complex_type_start(key) @complex_type.push(:hash) check_for_overlap! end
parse_recurse(psych_parse_data, is_sequence = false)
click to toggle source
Recusively check for duplicate keys
# File lib/yamllint/linter.rb, line 151 def parse_recurse(psych_parse_data, is_sequence = false) is_key = false psych_parse_data.children.each do |n| case n.class.to_s when 'Psych::Nodes::Scalar' is_key = !is_key unless is_sequence @last_key.push(n.value) if is_key add_value(n.value, @last_key.last) unless is_key msg = "Scalar: #{n.value}, key: #{is_key}, last_key: #{@last_key}" YamlLint.logger.debug { msg } @last_key.pop if !is_key && !is_sequence when 'Psych::Nodes::Sequence' YamlLint.logger.debug { "Sequence: #{n.children}" } array_start(@last_key.last) parse_recurse(n, true) array_end(@last_key.last) is_key = false @last_key.pop when 'Psych::Nodes::Mapping' YamlLint.logger.debug { "Mapping: #{n.children}" } hash_start(@last_key.last) parse_recurse(n) hash_end(@last_key.last) is_key = false @last_key.pop end end end