Class: IRB::Source::Reflector

Inherits:
Ripper::SexpBuilder
  • Object
show all
Defined in:
lib/irb/source.rb

Constant Summary collapse

UNEXPECTED_END =
"syntax error, unexpected $end"
INCREASE_LEVEL_KEYWORDS =
%w{ class module def begin if unless case while for do }
TERMINATE_KEYWORDS =
%w{ exit quit }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ Reflector

Returns a new instance of Reflector.



72
73
74
75
76
# File 'lib/irb/source.rb', line 72

def initialize(source)
  super
  @level = 0
  @code_block = !parse.nil?
end

Instance Attribute Details

#levelObject (readonly)

Returns the code block indentation level.

Reflector.new("").level # => 0
Reflector.new("class Foo").level # => 1
Reflector.new("class Foo; def foo").level # => 2
Reflector.new("class Foo; def foo; end").level # => 1
Reflector.new("class Foo; def foo; end; end").level # => 0


85
86
87
# File 'lib/irb/source.rb', line 85

def level
  @level
end

#syntax_errorObject (readonly)

Returns the actual syntax error message if one occurs.



88
89
90
# File 'lib/irb/source.rb', line 88

def syntax_error
  @syntax_error
end

Instance Method Details

#code_block?Boolean

Returns whether or not the source is a valid code block, but does not take syntax errors into account. In short, it’s a valid code block if after parsing the level is at zero.

For example, this is not a valid full code block:

def foo; p :ok

This however is:

def foo; p :ok; end

Returns:

  • (Boolean)


101
102
103
# File 'lib/irb/source.rb', line 101

def code_block?
  @code_block
end

#on_embexpr_beg(token) ⇒ Object

:nodoc:



164
165
166
167
# File 'lib/irb/source.rb', line 164

def on_embexpr_beg(token) #:nodoc:
  @level += 1
  super
end

#on_ident(token) ⇒ Object

:nodoc:



169
170
171
172
173
174
175
# File 'lib/irb/source.rb', line 169

def on_ident(token) #:nodoc:
  if @level == 0 && TERMINATE_KEYWORDS.include?(token)
    @terminate = true
  else
    super
  end
end

#on_kw(token) ⇒ Object

:nodoc:



144
145
146
147
148
149
150
151
152
# File 'lib/irb/source.rb', line 144

def on_kw(token) #:nodoc:
  case token
  when *INCREASE_LEVEL_KEYWORDS
    @level += 1
  when "end"
    @level -= 1
  end
  super
end

#on_lbrace(token) ⇒ Object

:nodoc:



177
178
179
180
# File 'lib/irb/source.rb', line 177

def on_lbrace(token) #:nodoc:
  @level += 1
  super
end

#on_lbracket(token) ⇒ Object

:nodoc:



154
155
156
157
# File 'lib/irb/source.rb', line 154

def on_lbracket(token) #:nodoc:
  @level += 1
  super
end

#on_parse_error(error) ⇒ Object

:nodoc:



135
136
137
138
139
# File 'lib/irb/source.rb', line 135

def on_parse_error(error) #:nodoc:
  if code_block? || !error.start_with?(UNEXPECTED_END)
    @syntax_error = error
  end
end

#on_rbrace(token) ⇒ Object

:nodoc:



182
183
184
185
# File 'lib/irb/source.rb', line 182

def on_rbrace(token) #:nodoc:
  @level -= 1
  super
end

#on_rbracket(token) ⇒ Object

:nodoc:



159
160
161
162
# File 'lib/irb/source.rb', line 159

def on_rbracket(token) #:nodoc:
  @level -= 1
  super
end

#syntax_error?Boolean

Returns whether or not the source contains a syntax error. However, it ignores a syntax error resulting in a code block not ending yet.

For example, this contains a syntax error:

def; foo

This does not:

def foo

Returns:

  • (Boolean)


115
116
117
# File 'lib/irb/source.rb', line 115

def syntax_error?
  !@syntax_error.nil?
end

#terminate?Boolean

Returns whether or not the source contains a call to toplevel quit or exit, namely if the current session should be terminated

For example, this would terminate the session

def foo; end; quit

This does not:

def foo; quit; end

Returns:

  • (Boolean)


129
130
131
# File 'lib/irb/source.rb', line 129

def terminate?
  !@terminate.nil?
end