Class: Pedant::CheckContainsUnreachableCode

Inherits:
Check
  • Object
show all
Defined in:
lib/pedant/checks/contains_unreachable_code.rb

Instance Attribute Summary

Attributes inherited from Check

#result

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Check

all, depends, #fail, #fatal, friendly_name, inherited, #initialize, initialize!, list, #pass, provides, ready?, #report, #skip, #warn

Constructor Details

This class inherits a constructor from Pedant::Check

Class Method Details

.requiresObject



29
30
31
# File 'lib/pedant/checks/contains_unreachable_code.rb', line 29

def self.requires
  super + [:trees]
end

Instance Method Details

#check(file, tree) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/pedant/checks/contains_unreachable_code.rb', line 33

def check(file, tree)
  def check_statements(file, list)
    list.each do |node|
      # Check if the Node is capable of jumping out of the Block, without
      # resuming where it left off (i.e., Call). The exception is exit(),
      # which is a builtin Function that terminates execution.
      if node.is_a?(Nasl::Break) || node.is_a?(Nasl::Continue) || node.is_a?(Nasl::Return) || (node.is_a?(Nasl::Call) && node.name.ident.name == 'exit' && node.name.indexes == [])
        # If this is not the final node in the list, then there is
        # absolutely no way for the later nodes to be accessed.
        if node != list.last
          report(:error, "#{file} contains unreachable code.")
          return fail
        end
      end
    end
  end

  # Unreachable statements occur only when there are sequential lists of
  # instructions. In layers deeper than the outermost level of indentation,
  # this only occurs in Blocks.
  tree.all(:Block).each { |blk| check_statements(file, blk.body) }

  # The main body of a file is not a Block, so it must be considered
  # separately.
  check_statements(file, tree)
end

#check_statements(file, list) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/pedant/checks/contains_unreachable_code.rb', line 34

def check_statements(file, list)
  list.each do |node|
    # Check if the Node is capable of jumping out of the Block, without
    # resuming where it left off (i.e., Call). The exception is exit(),
    # which is a builtin Function that terminates execution.
    if node.is_a?(Nasl::Break) || node.is_a?(Nasl::Continue) || node.is_a?(Nasl::Return) || (node.is_a?(Nasl::Call) && node.name.ident.name == 'exit' && node.name.indexes == [])
      # If this is not the final node in the list, then there is
      # absolutely no way for the later nodes to be accessed.
      if node != list.last
        report(:error, "#{file} contains unreachable code.")
        return fail
      end
    end
  end
end

#runObject



60
61
62
63
64
65
66
# File 'lib/pedant/checks/contains_unreachable_code.rb', line 60

def run
  # This check will pass by default.
  pass

  # Run this check on the tree from every file.
  @kb[:trees].each { |file, tree| check(file, tree) }
end