Class: SeeingIsBelieving::SyntaxAnalyzer

Inherits:
Ripper::SexpBuilder
  • Object
show all
Defined in:
lib/seeing_is_believing/syntax_analyzer.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.begin_and_end_comments_are_complete?(code) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
55
56
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 52

def self.begin_and_end_comments_are_complete?(code)
  code.scan(/^=(?:begin|end)$/)
      .each_slice(2)
      .all? { |b, e| b == '=begin' && e == '=end' }
end

.ends_in_comment?(code) ⇒ Boolean

COMMENTS

Returns:

  • (Boolean)


116
117
118
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 116

def self.ends_in_comment?(code)
  code =~ /^=end\Z/ || parsed(code.lines.to_a.last.to_s).has_comment?
end

.here_doc?(code) ⇒ Boolean

HERE DOCS

Returns:

  • (Boolean)


143
144
145
146
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 143

def self.here_doc?(code)
  instance = parsed code
  instance.has_heredoc? && code.scan("\n").size.next <= instance.here_doc_last_line_number
end

.parsed(code) ⇒ Object

HELPERS



8
9
10
11
12
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 8

def self.parsed(code)
  instance = new code
  instance.parse
  instance
end

.unclosed_comment?(code) ⇒ Boolean

Returns:

  • (Boolean)


120
121
122
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 120

def self.unclosed_comment?(code)
  !begin_and_end_comments_are_complete?(code)
end

.unclosed_regexp?(code) ⇒ Boolean

REGEXPS

Returns:

  • (Boolean)


92
93
94
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 92

def self.unclosed_regexp?(code)
  parsed(code).unclosed_regexp?
end

.unclosed_string?(code) ⇒ Boolean

STRINGS

Returns:

  • (Boolean)


68
69
70
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 68

def self.unclosed_string?(code)
  parsed(code).unclosed_string?
end

.valid_ruby?(code) ⇒ Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 48

def self.valid_ruby?(code)
  parsed(code).valid_ruby? && begin_and_end_comments_are_complete?(code)
end

.will_return?(code) ⇒ Boolean

this is conspicuosuly inferior, but I can’t figure out how to actually parse it see: www.ruby-forum.com/topic/4409633

Returns:

  • (Boolean)


137
138
139
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 137

def self.will_return?(code)
  /(^|\s)return.*?\Z$/ =~ code
end

Instance Method Details

#ends_match?(beginning, ending) ⇒ Boolean

We have to do this b/c Ripper sometimes calls on_tstring_end even when the string doesn’t get ended e.g. SyntaxAnalyzer.new(‘“a’).parse

Returns:

  • (Boolean)


16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 16

def ends_match?(beginning, ending)
  return false unless beginning && ending
  return beginning == ending if beginning.size == 1
  case beginning[-1]
  when '<' then '>' == ending
  when '(' then ')' == ending
  when '[' then ']' == ending
  when '{' then '}' == ending
  else
    beginning[-1] == ending
  end
end

#has_comment?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 124

def has_comment?
  @has_comment
end

#has_heredoc?Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 165

def has_heredoc?
  heredocs.any?
end

#here_doc_last_line_numberObject



169
170
171
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 169

def here_doc_last_line_number
  heredocs.last.last
end

#heredocsObject



148
149
150
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 148

def heredocs
  @heredocs ||= []
end

#invalid_ruby?Boolean

Returns:

  • (Boolean)


62
63
64
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 62

def invalid_ruby?
  @has_error || unclosed_string? || unclosed_regexp?
end

#on_commentObject



128
129
130
131
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 128

def on_comment(*)
  @has_comment = true
  super
end

#on_heredoc_beg(beginning) ⇒ Object



152
153
154
155
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 152

def on_heredoc_beg(beginning)
  heredocs << [beginning]
  super
end

#on_heredoc_end(ending) ⇒ Object



157
158
159
160
161
162
163
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 157

def on_heredoc_end(ending)
  result      = super
  line_number = result.last.first
  doc = heredocs.find { |(beginning)| beginning.include? ending.strip }
  doc << ending << line_number
  result
end

#on_regexp_beg(beginning) ⇒ Object



100
101
102
103
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 100

def on_regexp_beg(beginning)
  regexp_opens.push beginning
  super
end

#on_regexp_end(ending) ⇒ Object



105
106
107
108
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 105

def on_regexp_end(ending)
  regexp_opens.pop if ends_match? regexp_opens.last, ending
  super
end

#on_tstring_beg(beginning) ⇒ Object



76
77
78
79
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 76

def on_tstring_beg(beginning)
  string_opens.push beginning
  super
end

#on_tstring_end(ending) ⇒ Object



81
82
83
84
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 81

def on_tstring_end(ending)
  string_opens.pop if ends_match? string_opens.last, ending
  super
end

#regexp_opensObject



96
97
98
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 96

def regexp_opens
  @regexp_opens ||= []
end

#string_opensObject



72
73
74
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 72

def string_opens
  @string_opens ||= []
end

#unclosed_regexp?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 110

def unclosed_regexp?
  regexp_opens.any?
end

#unclosed_string?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 86

def unclosed_string?
  string_opens.any?
end

#valid_ruby?Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/seeing_is_believing/syntax_analyzer.rb', line 58

def valid_ruby?
  !invalid_ruby?
end