Skip to content

Commit

Permalink
Implement the check
Browse files Browse the repository at this point in the history
As both the datatype definition as the parameter default can contain
comma's we cannot rely on the `:COMMA` token to find the boundaries but
have to count parenthesis instead. This is done using a simple state
machine.

Code inspired by some of checks built in to `puppet-lint` and
`puppet-lint-param-docs`.
  • Loading branch information
bas smit committed Mar 4, 2018
1 parent 36a5517 commit c6e5086
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions lib/puppet-lint/plugins/check_parameter_types.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
PuppetLint.new_check(:parameter_types) do
def check
(class_indexes + defined_type_indexes).each do |idx|
next if idx[:param_tokens].nil?
# https://github.com/puppetlabs/puppet-specifications/blob/master/language/catalog_expressions.md
# Each individual parameter in the parameter list must start with
# either a datatype or a variable name, so testing whether the parameter is typed
# is easy.
state = :ST_BEGIN
paren_stack = []
data_stack = []
idx[:param_tokens].each do |token|
next if [ :NEWLINE, :WHITESPACE, :INDENT, :COMMENT, :MLCOMMENT, :SLASH_COMMENT].include?(token.type)

case state
when :ST_BEGIN
paren_stack = []
data_stack = []
if (token.type == :TYPE) or (token.value =~ /^[A-Z]/)
state = :ST_SKIP_TYPE
elsif token.type == :VARIABLE
notify :warning, {
:message => "missing datatype for parameter #{idx[:name_token].value}::#{token.value}",
:line => token.line,
:column => token.column
}
state = :ST_SKIP
end
# skip over the parameter default which can contain complex data types with variable references
# so a simple comma check isn't enough, brackets must be counted.
when :ST_SKIP
if token.type == :LPAREN
paren_stack.push(true)
elsif token.type == :RPAREN
paren_stack.pop
elsif token.type == :LBRACE || token.type == :LBRACK
data_stack.push(true)
elsif token.type == :RBRACE || token.type == :RBRACK
data_stack.pop
elsif token.type == :COMMA && data_stack.empty? && paren_stack.empty?
state = :ST_BEGIN
end
# Datatypes cannot have variables so when a variable is found it must be
# end of the data type
when :ST_SKIP_TYPE
if token.type == :VARIABLE
state = :ST_SKIP
end
end
end
end
end
end

0 comments on commit c6e5086

Please sign in to comment.