Class: Bashcov::Lexer

Inherits:
Object
  • Object
show all
Defined in:
lib/bashcov/lexer.rb

Overview

Simple lexer which analyzes Bash files in order to get information for coverage

Constant Summary collapse

IGNORE_START_WITH =

Lines starting with one of these tokens are irrelevant for coverage

%w(# function).freeze
IGNORE_END_WITH =

Lines ending with one of these tokens are irrelevant for coverage

%w|(|.freeze
IGNORE_IS =

Lines containing only one of these keywords are irrelevant for coverage

%w(esac if then else elif fi while do done { } ;;).freeze

Instance Method Summary collapse

Constructor Details

#initialize(filename, coverage) ⇒ Lexer

Returns a new instance of Lexer.

Parameters:

  • filename (String)

    File to analyze

  • coverage (Hash)

    Coverage with executed lines marked

Raises:

  • (ArgumentError)

    if the given filename is invalid.



21
22
23
24
25
26
27
28
# File 'lib/bashcov/lexer.rb', line 21

def initialize(filename, coverage)
  @filename = filename
  @coverage = coverage

  unless File.file?(@filename) # rubocop:disable Style/GuardClause
    raise ArgumentError, "#{@filename} is not a file"
  end
end

Instance Method Details

#complete_coveragevoid

This method returns an undefined value.

Process and complete initial coverage.



32
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
59
# File 'lib/bashcov/lexer.rb', line 32

def complete_coverage
  lines = File.read(@filename).lines

  lines.each_with_index do |line, lineno|
    # heredoc
    mark_multiline(
      lines, lineno,
      /\A[^\n]+<<-?'?(\w+)'?\s*$.*\1/m
    )

    # multiline string concatenated with backslashes
    mark_multiline(
      lines, lineno,
      /\A[^\n]+\\$(\s*['"][^'"]*['"]\s*\\$){1,}\s*['"][^'"]*['"]\s*$/
    )

    # multiline string concatenated with newlines
    %w(' ").each do |char|
      mark_multiline(
        lines, lineno,
        /\A[^\n]+\s+#{char}[^#{char}]*#{char}/m,
        forward: false
      )
    end

    mark_line(line, lineno)
  end
end