class PuppetLint::Data
A singleton class storing all the information about the manifest being analysed.
@api public
Attributes
Get/Set the full expanded path to the manifest file being checked.
@api private
Get/Set the full expanded path to the manifest file being checked.
@api private
Get/Set the raw manifest data, split by n.
@api private
Get/Set the full expanded path to the manifest file being checked.
@api private
Public Class Methods
Source
# File lib/puppet-lint/data.rb, line 436 def array_indexes @array_indexes ||= begin arrays = [] tokens.each_with_index do |token, token_idx| next unless token.type == :LBRACK real_idx = 0 tokens[token_idx + 1..].each_with_index do |cur_token, cur_token_idx| real_idx = token_idx + 1 + cur_token_idx break if cur_token.type == :RBRACK end # Ignore resource references next if token.prev_code_token && token.prev_code_token.type == :CLASSREF arrays << { start: token_idx, end: real_idx, tokens: tokens[token_idx..real_idx] } end arrays end end
Calculate the positions of all array values within ‘tokens` Array.
Returns an Array of Hashes, each containing:
:start - An Integer position in the `tokens` Array pointing to the first Token of an array value :end - An Integer position in the `tokens` Array pointing to the last Token of an array value :tokens - An Array consisting of all the Token objects that make up the array value.
@api private
Source
# File lib/puppet-lint/data.rb, line 286 def class_indexes @class_indexes ||= definition_indexes(:CLASS) end
Calculate the positions of all class definitions within the ‘tokens` Array.
Returns an Array of Hashes, each containing:
:start - An Integer position in the `tokens` Array pointing to the first Token of a class definition. :end - An Integer position in the `tokens` Array pointing to the last Token of a class definition. :tokens - An Array consisting of all the Token objects that make up the class definition.
@api private
Source
# File lib/puppet-lint/data.rb, line 183 def classref?(token) current_token = token while (current_token = current_token.prev_code_token) return true if current_token.type == :CLASSREF return false if current_token.type == :NAME end end
Determine if the given token contains a CLASSREF in the token chain..
@param [PuppetLint::Lexer::Token] token
@api private
Source
# File lib/puppet-lint/data.rb, line 513 def defaults_indexes @defaults_indexes ||= begin defaults = [] tokens.each_with_index do |token, token_idx| next unless token.type == :CLASSREF next unless token.next_code_token && token.next_code_token.type == :LBRACE real_idx = 0 tokens[token_idx + 1..].each_with_index do |cur_token, cur_token_idx| real_idx = token_idx + 1 + cur_token_idx break if cur_token.type == :RBRACE end defaults << { start: token_idx, end: real_idx, tokens: tokens[token_idx..real_idx] } end defaults end end
Calculate the positions of all defaults declarations within ‘tokens` Array.
Returns an Array of Hashes, each containing:
:start - An Integer position in the `tokens` Array pointing to the first Token of the defaults declaration :end - An Integer position in the `tokens` Array pointing to the last Token of the defaults declaration :tokens - An Array consisting of all the Token objects that make up the defaults declaration.
@api private
Source
# File lib/puppet-lint/data.rb, line 302 def defined_type_indexes @defined_type_indexes ||= definition_indexes(:DEFINE) end
Calculate the positions of all defined type definitions within the ‘tokens` Array.
Returns an Array of Hashes, each containing:
:start - An Integer position in the `tokens` Array pointing to the first Token of a defined type definition. :end - An Integer position in the `tokens` Array pointing to the last Token of a defined type definition. :tokens - An Array consisting of all the Token objects that make up the defined type.
@api private
Source
# File lib/puppet-lint/data.rb, line 334 def definition_indexes(type) result = [] tokens.each_with_index do |token, i| next unless token.type == type brace_depth = 0 paren_depth = 0 in_params = false inherited_class = nil tokens[i + 1..].each_with_index do |definition_token, j| case definition_token.type when :INHERITS inherited_class = definition_token.next_code_token when :LPAREN in_params = true if paren_depth.zero? paren_depth += 1 when :RPAREN in_params = false if paren_depth == 1 paren_depth -= 1 when :LBRACE brace_depth += 1 when :RBRACE brace_depth -= 1 if brace_depth.zero? && !in_params && (token.next_code_token.type != :LBRACE) result << { start: i, end: i + j + 1, tokens: tokens[i..(i + j + 1)], param_tokens: param_tokens(tokens[i..(i + j + 1)]), type: type, name_token: token.next_code_token, inherited_token: inherited_class } break end end end end result end
Calculate the positions of all the specified defintion types within the ‘tokens` Array.
Returns an Array of Hashes, each containing:
:start - An Integer position in the `tokens` Array pointing to the first Token of a definition. :end - An Integer position in the `tokens` Array pointing to the last Token of a definition. :tokens - An Array consisting of all the Token objects that make up the definition.
@api private
Source
# File lib/puppet-lint/data.rb, line 120 def delete(token) token.next_token.prev_token = token.prev_token unless token.next_token.nil? token.prev_token.next_token = token.next_token unless token.prev_token.nil? unless formatting_tokens.include?(token.type) token.prev_code_token.next_code_token = token.next_code_token unless token.prev_code_token.nil? token.next_code_token.prev_code_token = token.prev_code_token unless token.next_code_token.nil? end tokens.delete(token) end
Remove a token
@param [PuppetLint::Lexer::Token] token
@api public
Source
# File lib/puppet-lint/data.rb, line 258 def find_resource_param_tokens(resource_tokens) param_tokens = [] iter_token = resource_tokens.first.prev_token until iter_token.nil? iter_token = iter_token.next_token_of(:NAME) break unless resource_tokens.include?(iter_token) param_tokens << iter_token if iter_token && iter_token.next_code_token.type == :FARROW end param_tokens end
Find all the Token objects representing the parameter names in a resource definition.
@param [Array] resource_tokens
An Array of Token objects that comprise the resource definition.
@return [Array]
@api private
Source
# File lib/puppet-lint/data.rb, line 239 def find_resource_type_token(index) lbrace_idx = tokens[0..index].rindex do |token| token.type == :LBRACE && token.prev_code_token.type != :QMARK end raise PuppetLint::SyntaxError, tokens[index] if lbrace_idx.nil? tokens[lbrace_idx].prev_code_token end
Find the Token representing the type of a resource definition.
@param [Integer] index
The Integer pointing to the start of the resource in the `tokens` array.
@return [PuppetLint::Lexer::Token]
@api private
Source
# File lib/puppet-lint/data.rb, line 582 def formatting_tokens @formatting_tokens ||= PuppetLint::Lexer::FORMATTING_TOKENS end
Retrieves a list of token types that are considered to be formatting tokens (whitespace, newlines, etc).
@return [Array]
@api private
Source
# File lib/puppet-lint/data.rb, line 386 def function_indexes @function_indexes ||= begin functions = [] tokens.each_with_index do |token, token_idx| next unless token.type == :FUNCTION_NAME next unless token_idx.zero? || (token_idx == 1 && tokens[0].type == :WHITESPACE) || [:NEWLINE, :INDENT].include?(token.prev_token.type) || # function in a function (token.prev_code_token && token.prev_code_token.type == :LPAREN) # Hash key next if token.next_code_token && token.next_code_token.type == :FARROW level = 0 real_idx = 0 in_paren = false tokens[token_idx + 1..].each_with_index do |cur_token, cur_token_idx| break if level.zero? && in_paren break if level.zero? && cur_token.type == :NEWLINE if cur_token.type == :LPAREN level += 1 in_paren = true end level -= 1 if cur_token.type == :RPAREN real_idx = token_idx + 1 + cur_token_idx end functions << { start: token_idx, end: real_idx, tokens: tokens[token_idx..real_idx] } end functions end end
Calculate the positions of all function calls within ‘tokens` Array.
Returns an Array of Hashes, each containing:
:start - An Integer position in the `tokens` Array pointing to the first Token of a function call :end - An Integer position in the `tokens` Array pointing to the last Token of a function call :tokens - An Array consisting of all the Token objects that make up the function call.
@api private
Source
# File lib/puppet-lint/data.rb, line 473 def hash_indexes @hash_indexes ||= begin hashes = [] tokens.each_with_index do |token, token_idx| next unless token.type == :LBRACE next unless token.prev_code_token next unless [:EQUALS, :ISEQUAL, :FARROW, :LPAREN].include?(token.prev_code_token.type) level = 0 real_idx = 0 tokens[token_idx + 1..].each_with_index do |cur_token, cur_token_idx| real_idx = token_idx + 1 + cur_token_idx level += 1 if cur_token.type == :LBRACE level -= 1 if cur_token.type == :RBRACE break if level.negative? end hashes << { start: token_idx, end: real_idx, tokens: tokens[token_idx..real_idx] } end hashes end end
Calculate the positions of all hash values within ‘tokens` Array.
Returns an Array of Hashes, each containing:
:start - An Integer position in the `tokens` Array pointing to the first Token of an hash value :end - An Integer position in the `tokens` Array pointing to the last Token of an hash value :tokens - An Array consisting of all the Token objects that make up the hash value.
@api private
Source
# File lib/puppet-lint/data.rb, line 593 def ignore_overrides @ignore_overrides ||= {} end
Retrieves a Hash of Sets. Each key is a check name Symbol and the Set of Integers returned lists all the lines that the check results should be ignored on.
@return [Hash[Symbol, Set]]
@api private
Source
# File lib/puppet-lint/data.rb, line 81 def insert(index, token) current_token = tokens[index - 1] token.next_token = current_token.next_token token.prev_token = current_token current_token.next_token.prev_token = token unless current_token.next_token.nil? unless formatting_tokens.include?(token.type) current_token.next_token.prev_code_token = token unless current_token.next_token.nil? next_nf_idx = tokens[index..].index { |r| !formatting_tokens.include?(r.type) } unless next_nf_idx.nil? next_nf_token = tokens[index + next_nf_idx] token.next_code_token = next_nf_token next_nf_token.prev_code_token = token end end if formatting_tokens.include?(current_token.type) prev_nf_idx = tokens[0..index - 1].rindex { |r| !formatting_tokens.include?(r.type) } unless prev_nf_idx.nil? prev_nf_token = tokens[prev_nf_idx] token.prev_code_token = prev_nf_token prev_nf_token.next_code_token = token end else token.prev_code_token = current_token end current_token.next_token = token current_token.next_code_token = token unless formatting_tokens.include?(token.type) tokens.insert(index, token) end
Add new token.
@param [Integer] index @param [PuppetLint::Lexer::Token] token
@api public
Source
# File lib/puppet-lint/data.rb, line 318 def node_indexes @node_indexes ||= definition_indexes(:NODE) end
Calculate the positions of all node definitions within the ‘tokens` Array.
Returns an Array of Hashes, each containing:
:start - An Integer position in the `tokens` Array pointing to the first Token of a defined type definition. :end - An Integer position in the `tokens` Array pointing to the last Token of a defined type definition. :tokens - An Array consisting of all the Token objects that make up the defined type.
@api private
Source
# File lib/puppet-lint/data.rb, line 548 def param_tokens(these_tokens) depth = 0 lparen_idx = nil rparen_idx = nil these_tokens.each_with_index do |token, i| if token.type == :LPAREN depth += 1 lparen_idx = i if depth == 1 elsif token.type == :RPAREN depth -= 1 if depth.zero? rparen_idx = i break end elsif token.type == :LBRACE && depth.zero? # no parameters break end end if lparen_idx.nil? || rparen_idx.nil? nil else these_tokens[(lparen_idx + 1)..(rparen_idx - 1)] end end
Finds all the tokens that make up the defined type or class definition parameters.
@param [Array] these_tokens
An Array of PuppetLint::Lexer::Token objects that make up the defined type or class definition.
@return [Array, nil] objects or nil if it takes
no parameters.
@api private
Source
# File lib/puppet-lint/data.rb, line 604 def parse_control_comments @ignore_overrides.each_key { |check| @ignore_overrides[check].clear } comment_token_types = Set[:COMMENT, :MLCOMMENT, :SLASH_COMMENT] comment_tokens = tokens.select do |token| comment_token_types.include?(token.type) end control_comment_tokens = comment_tokens.select do |token| token.value.strip =~ %r{\Alint:(ignore:[\w\d]+|endignore)} end stack = [] control_comment_tokens.each do |token| comment_data = [] reason = [] comment_words = token.value.strip.split(%r{\s+}) comment_words.each_with_index do |word, i| if %r{\Alint:(ignore|endignore)}.match?(word) comment_data << word else # Once we reach the first non-controlcomment word, assume the rest # of the words are the reason. reason = comment_words[i..] break end end stack_add = [] comment_data.each do |control| split_control = control.split(':') command = split_control[1] if command == 'ignore' check = split_control[2].to_sym if token.prev_token && !Set[:NEWLINE, :INDENT].include?(token.prev_token.type) # control comment at the end of the line, override applies to # a single line only (ignore_overrides[check] ||= {})[token.line] = reason.join(' ') else stack_add << [token.line, reason.join(' '), check] end else top_override = stack.pop if top_override.nil? # TODO: refactor to provide a way to expose problems from # PuppetLint::Data via the normal problem reporting mechanism. warn "WARNING: lint:endignore comment with no opening lint:ignore:<check> comment found on line #{token.line}" else top_override.each do |start| next if start.nil? (start[0]..token.line).each do |i| (ignore_overrides[start[2]] ||= {})[i] = start[1] end end end end end stack << stack_add unless stack_add.empty? end stack.each do |control| warn "WARNING: lint:ignore:#{control[0][2]} comment on line #{control[0][0]} with no closing lint:endignore comment" end end
Parses all COMMENT, MLCOMMENT and SLASH_COMMENT tokens looking for control comments (comments that enable or disable checks). Builds the contents of the ‘ignore_overrides` hash.
@return [nil]
@api private
Source
# File lib/puppet-lint/data.rb, line 138 def path=(val) @path = val if val.nil? @fullpath = nil @filename = nil else @fullpath = File.expand_path(val, ENV.fetch('PWD', nil)) @filename = File.basename(val) end end
Store the path to the manifest file and populate fullpath and filename.
@param [String] val The path to the file
@return [nil]
@api private
Source
# File lib/puppet-lint/data.rb, line 200 def resource_indexes @resource_indexes ||= begin marker = 0 result = [] tokens.select { |t| t.type == :COLON }.each do |colon_token| next unless colon_token.next_code_token && colon_token.next_code_token.type != :LBRACE next if classref?(colon_token) rel_start_idx = tokens[marker..].index(colon_token) break if rel_start_idx.nil? start_idx = rel_start_idx + marker end_token = colon_token.next_token_of([:SEMIC, :RBRACE]) rel_end_idx = tokens[start_idx..].index(end_token) raise PuppetLint::SyntaxError, colon_token if rel_end_idx.nil? marker = rel_end_idx + start_idx result << { start: start_idx + 1, end: marker, tokens: tokens[start_idx..marker], type: find_resource_type_token(start_idx), param_tokens: find_resource_param_tokens(tokens[start_idx..marker]) } end result end end
Calculate the positions of all resource declarations within the tokenised manifest. These positions only point to the content of the resource declarations, they do not include resource types or titles.
@return [Array[Hash[Symbol, Integer]]] each hash contains :start and
:end pointing to the first and last {PuppetLint::Lexer::Token} of a resource declaration
@api private
Source
# File lib/puppet-lint/data.rb, line 42 def ruby1? @ruby1 = RbConfig::CONFIG['MAJOR'] == '1' if @ruby1.nil? @ruby1 end
@api private
Source
# File lib/puppet-lint/data.rb, line 154 def title_tokens @title_tokens ||= begin result = [] tokens.each_index do |token_idx| if tokens[token_idx].type == :COLON # gather a list of tokens that are resource titles if tokens[token_idx - 1].type == :RBRACK array_start_idx = tokens.rindex do |r| r.type == :LBRACK end title_array_tokens = tokens[(array_start_idx + 1)..(token_idx - 2)] result += title_array_tokens.select do |token| { STRING: true, NAME: true }.include?(token.type) end else next_token = tokens[token_idx].next_code_token result << tokens[token_idx - 1] unless next_token.type == :LBRACE end end end result end end
Retrieve a list of tokens that represent resource titles
@return [Array]
@api private
Source
# File lib/puppet-lint/data.rb, line 52 def tokens calling_method = if ruby1? begin caller[0][%r{`.*'}][1..-2] # rubocop:disable Performance/Caller rescue NoMethodError caller[1][%r{`.*'}][1..-2] # rubocop:disable Performance/Caller end else begin caller(0..0).first[%r{[`'].*'}][1..-2] rescue NoMethodError caller(1..1).first[%r{[`'].*'}][1..-2] end end calling_method.gsub!(/^.*[#\.]/, "") if calling_method == 'check' @tokens.dup else @tokens end end
Get the tokenised manifest.
@return [Array]
@api public
Source
# File lib/puppet-lint/data.rb, line 28 def tokens=(tokens) @tokens = tokens @title_tokens = nil @resource_indexes = nil @class_indexes = nil @defined_type_indexes = nil @node_indexes = nil @function_indexes = nil @array_indexes = nil @hash_indexes = nil @defaults_indexes = nil end
Store the tokenised manifest.
@param [Array] tokens The Array of PuppetLint::Lexer::Token
objects to store. @return [nil]
@api private