Module: LintFu::Mixins::SexpInstanceMethods

Defined in:
lib/lint_fu/mixins/sexp_instance_methods.rb

Constant Summary collapse

WHOLE_LINE_COMMENT =
/^\s*#/

Instance Method Summary collapse

Instance Method Details

#blessingsObject



150
151
152
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 150

def blessings
  @blessings ||= Blessing.parse(self.preceding_comments, self)
end

#constant?Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 62

def constant?
  typ = self[0]

  case typ
    when :true, :false, :lit, :str
      return true
    when :array, :arglist
      contents = self[1..-1]
      return false if contents.empty?
      contents.each { |sexp| return false unless sexp.constant? }
      return true
    when :hash
      result = {}
      key, value = nil, nil
      flipflop = false
      self[1..-1].each do |token|
        if flipflop
          value = token
          return false unless key.constant? && value.constant?
        else
          key = token
        end
        flipflop = !flipflop
      end
      return true
    else
      return false
  end
end

#deep_cloneObject



10
11
12
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 10

def deep_clone
  Marshal.load(Marshal.dump(self))
end

#find_all_recursively(results = nil, &test) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 103

def find_all_recursively(results=nil, &test)
  results ||= []
  results << self if test.call(self)

  self.each do |child|
    child.find_all_recursively(results, &test) if (Sexp === child)
  end

  return nil if results.empty?
  return results
end

#find_recursively(&test) ⇒ Object



92
93
94
95
96
97
98
99
100
101
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 92

def find_recursively(&test)
  return self if test.call(self)

  self.each do |child|
    found = child.find_recursively(&test) if (Sexp === child)
    return found if found
  end

  return nil
end

#fingerprintObject

Return a version of this Sexp that preserves the structure of the original, but with any specific names, quantities or other values replaced with nil. The fingerprint of a given chunk of code will tend to remain the same over time, even if variable names or other inconsequential details are changed.



18
19
20
21
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 18

def fingerprint
  #TODO actually implement this method
  self
end

#preceding_comment_rangeObject



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 115

def preceding_comment_range
  unless @preceding_comment_range
    cont = File.readlines(self.file)

    comments = ''

    max_line = self.line - 1 - 1
    max_line = 0 if max_line < 0
    min_line = max_line

    while cont[min_line] =~ WHOLE_LINE_COMMENT && min_line >= 0
      min_line -= 1
    end

    if cont[max_line] =~ WHOLE_LINE_COMMENT
      min_line +=1 unless min_line == max_line
      @preceding_comment_range = FileRange.new(self.file, min_line+1, max_line+1, cont[min_line..max_line])
    else
      @preceding_comment_range = FileRange::NONE
    end
  end

  if @preceding_comment_range == FileRange::NONE
    return nil
  else
    return @preceding_comment_range
  end
end

#preceding_commentsObject



144
145
146
147
148
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 144

def preceding_comments
  range = preceding_comment_range
  return [] unless range
  return range.content
end

#to_ruby(options = {}) ⇒ Object

Translate a sexp containing a Ruby data literal (string, int, array, hash, etc) into the equivalent Ruby object.



30
31
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
60
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 30

def to_ruby(options={})
  typ = self[0]

  case typ
    when :true
      return true
    when :false
      return false
    when :lit, :str
      return self[1]
    when :array, :arglist
      return self[1..-1].collect { |x| x.to_ruby(options) }
    when :hash
      result = {}
      key, value = nil, nil
      flipflop = false
      self[1..-1].each do |token|
        if flipflop
          value = token
          result[key.to_ruby(options)] = value.to_ruby(options)
        else
          key = token
        end
        flipflop = !flipflop
      end
      return result
    else
      return options[:partial] if options.has_key?(:partial)
      raise TranslationFailure.new("Cannot convert Sexp to Ruby object (expression at #{self.file}:#{self.line}): " + self.to_s)
  end
end

#to_ruby_stringObject

Generate a human-readable description for this sexp that is similar to source code.



24
25
26
# File 'lib/lint_fu/mixins/sexp_instance_methods.rb', line 24

def to_ruby_string
  Ruby2Ruby.new.process(self.deep_clone)
end