wirb 1.0.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/wirb.rb CHANGED
@@ -1,135 +1,90 @@
1
- require File.dirname(__FILE__) + '/wirb/version'
2
- require File.dirname(__FILE__) + '/wirb/colorizer'
3
- require File.dirname(__FILE__) + '/wirb/tokenizer'
4
- require 'yaml'
5
-
6
- class << Wirb
7
- def running?() @running end
8
-
9
- @running = false
10
-
11
- # Start colorizing results, will hook into irb if IRB is defined
12
- def start
13
- require File.dirname(__FILE__) + '/wirb/irb' if defined?(IRB) && defined?(IRB::Irb) && !IRB::Irb.instance_methods.include?(:prompt_non_fancy)
14
- @running = true
15
- rescue LoadError
16
- warn "Couldn't activate Wirb"
17
- end
18
- alias activate start
19
- alias enable start
20
-
21
- # Stop colorizing
22
- def stop
23
- @running = false
24
- end
25
- alias deactivate stop
26
- alias disable stop
27
-
28
- # extend getter & setter for colorizer & schema
29
- def colorizer
30
- @colorizer ||= Wirb::Colorizer::Paint
31
- end
1
+ require_relative 'wirb/version'
2
+ require_relative 'wirb/tokenizer'
3
+ require_relative 'wirb/schema_builder'
4
+ require_relative 'wirb/inspector'
5
+ require_relative 'wirb/irb' if defined?(IRB)
32
6
 
33
- def colorizer=(col)
34
- @colorizer = col
35
- end
7
+ require 'yaml'
8
+ require 'paint'
9
+ require 'timeout'
36
10
 
37
- # Convenience method, permits simplified syntax like:
38
- # Wirb.load_colorizer :HighLine
39
- def load_colorizer(colorizer_name)
40
- # @colorizer = Wirb::Colorizer.const_get(colorizer_name, false)
41
- @colorizer = eval "Wirb::Colorizer::#{colorizer_name}"
42
- compatible_colorizer?(@colorizer)
43
- @colorizer
44
- end
45
11
 
46
- def schema
47
- @schema || load_schema
48
- end
12
+ module Wirb
13
+ class << self
14
+ def running?
15
+ defined?(IRB) && IRB.CurrentContext &&
16
+ IRB.CurrentContext.inspect_mode == :wirb
17
+ end
49
18
 
50
- def schema=(val)
51
- @schema = val
52
- end
19
+ def timeout
20
+ @timeout ||= 3
21
+ end
53
22
 
54
- # Loads a color schema from a yaml file
55
- # If first argument is a String: path to yaml file
56
- # If first argument is a Symbol: bundled schema
57
- def load_schema!(yaml_path = :classic_paint)
58
- if yaml_path.is_a? Symbol # bundled themes
59
- schema_name = yaml_path.to_s
60
- schema_yaml = YAML.load_file(File.join(Gem.datadir('wirb'), schema_name + '.yml'))
61
- else
62
- schema_name = File.basename(yaml_path).gsub(/\.yml$/, '')
63
- schema_yaml = YAML.load_file(yaml_path)
23
+ def schema
24
+ @schema ||= SchemaBuilder.load_schema_from_yaml
64
25
  end
65
26
 
66
- if schema_yaml.is_a?(Hash)
67
- @schema = Hash[ schema_yaml.map{ |k,v|
68
- [k.to_s.to_sym, Array( v )]
69
- } ]
70
- @schema[:name] = schema_name.to_sym
71
- @schema[:colorizer].map!(&:to_sym)
72
- else
73
- raise LoadError, "Could not load the Wirb schema at: #{yaml_path}"
27
+ def schema=(val)
28
+ @schema = val
74
29
  end
75
30
 
76
- @schema
77
- end
31
+ def load_schema(name)
32
+ @schema = SchemaBuilder.load_schema_from_yaml(name)
33
+ end
78
34
 
79
- # Loads a color schema from a yaml file and sets colorizer to first suggested one in schema
80
- def load_schema(yaml_path = :classic_paint)
81
- load_schema! yaml_path
82
- load_colorizer schema[:colorizer].first
83
- @schema
84
- end
35
+ def original_inspect_mode
36
+ @original_inspect_mode
37
+ end
85
38
 
86
- # Return the escape code for a given color
87
- def get_color(*keys)
88
- colorizer.color(*keys)
89
- end
90
- alias color get_color
91
-
92
- # Colorize a string
93
- def colorize_string(string, *colors)
94
- colorizer.run(string, *colors)
95
- end
39
+ def start
40
+ require_relative 'wirb/irb'
41
+ @original_inspect_mode =
42
+ IRB.conf[:INSPECT_MODE] ||
43
+ IRB.CurrentContext && IRB.CurrentContext.inspect_mode ||
44
+ true
45
+ IRB.conf[:INSPECT_MODE] = :wirb
46
+ IRB.CurrentContext.inspect_mode = :wirb if IRB.CurrentContext
47
+ true
48
+ end
49
+ alias activate start
50
+ alias enable start
51
+
52
+ def stop
53
+ if running?
54
+ IRB.conf[:INSPECT_MODE] = @original_inspect_mode
55
+ IRB.CurrentContext.inspect_mode = @original_inspect_mode if IRB.CurrentContext
56
+ true
57
+ end
58
+ end
59
+ alias deactivate stop
60
+ alias disable stop
96
61
 
97
- # Colorize a result string
98
- def colorize_result(string, custom_schema = schema)
99
- if @running
62
+ def colorize_result(string, _deprecated = nil)
100
63
  check = ''
101
- colorful = tokenize(string).map do |kind, token|
102
- check << token
103
- colorize_string token, *Array( custom_schema[kind] )
104
- end.join
64
+ colorful = ''
65
+ begin
66
+ Tokenizer.run(string).each{ |kind, token|
67
+ check << token
68
+ colorful << Paint[token, *Array( schema[kind] )]
69
+ }
70
+ rescue
71
+ p $!, $!.backtrace[0] if $VERBOSE
72
+ end
105
73
 
106
74
  # always display the correct inspect string!
107
75
  check == string ? colorful : string
108
- else
109
- string
110
76
  end
111
- end
112
- alias colorize_code colorize_result
113
- alias colorize_ruby colorize_result
114
-
115
- private
116
77
 
117
- def compatible_colorizer?(col)
118
- short_col = col.to_s.sub(/^.*::(.*?)$/, '\1').to_sym
119
- if !col
120
- warn "No colorizer selected!"
121
- false
122
- elsif !Array( @schema[:colorizer] ).include?(short_col)
123
- warn "Your current color schema does not support this colorizer:\n" +
124
- " #{ short_col }\n" +
125
- "The following colorizeres are supported with this schema (use Wirb.load_colorizer :Name):\n " +
126
- Array( @schema[:colorizer] ).join("\n ")
127
- false
128
- else
129
- true
78
+ def colorize_result_with_timeout(string)
79
+ if timeout.to_i == 0
80
+ colorize_result(string)
81
+ else
82
+ Timeout.timeout(timeout) do
83
+ colorize_result(string)
84
+ end
85
+ end
86
+ rescue Timeout::Error
87
+ string
130
88
  end
131
89
  end
132
-
133
90
  end
134
-
135
- # J-_-L
@@ -0,0 +1,10 @@
1
+ module Wirb
2
+ INSPECTOR = proc{ |value|
3
+ if defined?(value.inspect)
4
+ Wirb.colorize_result_with_timeout(value.inspect)
5
+ else
6
+ "(Object doesn't support #inspect)"
7
+ end
8
+ }
9
+ end
10
+
data/lib/wirb/irb.rb CHANGED
@@ -1,13 +1,4 @@
1
- require File.dirname(__FILE__) + '/../wirb' unless defined? Wirb
1
+ require_relative '../wirb' unless defined? Wirb
2
+ require 'irb'
2
3
 
3
- class IRB::Irb
4
- alias :output_value_without_wirb :output_value
5
-
6
- def output_value
7
- if @context.inspect?
8
- printf @context.return_format, ::Wirb.colorize_result( @context.last_value.inspect )
9
- else
10
- printf @context.return_format, @context.last_value
11
- end
12
- end
13
- end
4
+ IRB::Inspector.def_inspector(:wirb, &Wirb::INSPECTOR)
@@ -0,0 +1,44 @@
1
+ module Wirb
2
+ module SchemaBuilder
3
+ # Loads a color schema from a yaml file
4
+ # If first argument is a String: path to yaml file
5
+ # If first argument is a Symbol: bundled schema
6
+ def self.load_schema_from_yaml(yaml_path = :classic)
7
+ schema_name, schema_yaml = resolve_schema_yaml(yaml_path)
8
+ raise LoadError, "Could not load the Wirb schema at: #{yaml_path}" unless schema_yaml.is_a?(Hash)
9
+
10
+ schema = normalize_schema(schema_yaml)
11
+ schema[:name] = schema_name.to_sym
12
+ schema
13
+ end
14
+
15
+ def self.resolve_schema_yaml(yaml_path)
16
+ if yaml_path.is_a? Symbol # bundled themes
17
+ [yaml_path.to_s, YAML.load_file(File.join(Gem.datadir('wirb'), "#{yaml_path}.yml"))]
18
+ else
19
+ [File.basename(yaml_path).gsub(/\.yml$/, ''), YAML.load_file(yaml_path)]
20
+ end
21
+ end
22
+
23
+ def self.normalize_schema(schema_yaml)
24
+ normalized_schema = Hash[ schema_yaml.map{ |k,v| [k.to_s.to_sym, Array( v )] } ]
25
+ %w(
26
+ hash
27
+ array
28
+ set
29
+ symbol_string
30
+ string
31
+ regexp
32
+ rational
33
+ complex
34
+ object
35
+ ).each{ |what|
36
+ values = normalized_schema.delete(:"#{what}_delimiter")
37
+ normalized_schema[:"open_#{what}"] = values
38
+ normalized_schema[:"close_#{what}"] = values
39
+ }
40
+
41
+ normalized_schema
42
+ end
43
+ end
44
+ end
@@ -1,500 +1,474 @@
1
- class << Wirb
2
- # This is an extended version of the original wirble tokenizer.
3
- # Many people would say that 400 lines long case statements need refactoring, but
4
- # ...sometimes it is supposed to be this way!
5
- def tokenize(str)
6
- return [] if str.nil?
7
- raise ArgumentError, 'Tokenizer needs an inspect-string' unless str.is_a? String
8
- return enum_for(:tokenize, str) unless block_given?
9
-
10
- chars = str.split(//)
11
-
12
- @state, @token, i = [], '', 0
13
- @passed, snapshot = '', nil # exception handling
14
-
15
- # helpers
16
- pass_custom_state = lambda{ |kind, *options|
17
- yield kind, @token unless @token.empty?
18
- @passed << @token
19
- @state.pop if options.include?(:remove)
20
- @token = '' unless options.include?(:keep_token)
21
- @repeat = true if options.include?(:repeat)
22
- }
23
-
24
- pass_state = lambda{ |*options| pass_custom_state[ @state[-1], *options ] }
25
-
26
- pass = lambda{ |kind, string| @passed << string; yield kind, string }
27
-
28
- set_state = lambda{ |state, *options|
29
- @state[-1] = state
30
- @repeat = true if options.include? :repeat
31
- }
32
-
33
- get_state = lambda{ |state| @state[-1] == state }
34
-
35
- get_previous_state =
36
- lambda{ |state| @state[-2] == state }
37
-
38
- push_state = lambda{ |state, *options|
39
- @state << state
40
- @repeat = true if options.include? :repeat
41
- }
42
-
43
- pop_state = lambda{ |*options|
44
- @state.pop
45
- @repeat = true if options.include? :repeat
46
- }
47
-
48
- # action!
49
- while i <= chars.size
50
- @repeat = false
51
- llc, lc, c, nc = lc, c, chars[i], chars[i+1]
52
-
53
- # warn "char = #{c} state = #{@state*':'}"
54
-
55
- case @state[-1]
56
- when nil, :hash, :array, :enumerator, :set, :variable # default state
57
- case c
58
- when '"' then push_state[:string]
59
- when '/' then push_state[:regexp]
60
- when '#' then push_state[:object]
61
- when /[A-Z]/ then push_state[:class, :repeat]
62
- when /[a-z]/ then push_state[:keyword, :repeat]
63
- when /[0-9-]/ then push_state[:number, :repeat]
64
- when '.' then push_state[:range, :repeat]
65
- when /[~=]/ then push_state[:gem_requirement_condition, :repeat]
66
-
67
- when /\s/
68
- if get_state[:variable]
69
- pop_state[:repeat]
70
- else
71
- pass[:whitespace, c]
72
- end
1
+ module Wirb
2
+ module Tokenizer
3
+ def self.run(str)
4
+ return [] if str.nil?
5
+ raise ArgumentError, 'Tokenizer needs an inspect-string' unless str.is_a? String
6
+ return enum_for(:run, str) unless block_given?
7
+
8
+ chars = str.split('')
9
+
10
+ @state, @token, i = [], '', 0
11
+ @passed, snapshot = '', nil # exception handling
12
+
13
+ # helpers
14
+ pass_custom_state = lambda{ |kind, *options|
15
+ yield kind, @token unless @token.empty?
16
+ @passed << @token
17
+ @state.pop if options.include?(:remove)
18
+ @token = '' unless options.include?(:keep_token)
19
+ @repeat = true if options.include?(:repeat)
20
+ }
21
+
22
+ pass_state = lambda{ |*options|
23
+ pass_custom_state[ @state[-1], *options ]
24
+ }
25
+
26
+ pass = lambda{ |kind, string|
27
+ @passed << string
28
+ yield kind, string
29
+ }
30
+
31
+ set_state = lambda{ |state, *options|
32
+ @state[-1] = state
33
+ @repeat = true if options.include? :repeat
34
+ }
35
+
36
+ get_state = lambda{ |state| @state[-1] == state }
37
+
38
+ get_previous_state =
39
+ lambda{ |state| @state[-2] == state }
40
+
41
+ push_state = lambda{ |state, *options|
42
+ @state << state
43
+ @repeat = true if options.include? :repeat
44
+ }
45
+
46
+ pop_state = lambda{ |*options|
47
+ @state.pop
48
+ @repeat = true if options.include? :repeat
49
+ }
50
+
51
+ # action!
52
+ while i <= chars.size
53
+ @repeat = false
54
+ llc, lc, c, nc = lc, c, chars[i], chars[i+1]
55
+
56
+ # warn "char = #{c} state = #{@state*':'}"
57
+
58
+ case @state[-1]
59
+ when nil, :hash, :array, :enumerator, :set, :variable # default state
60
+ case c
61
+ when '"' then push_state[:string]
62
+ when '/' then push_state[:regexp]
63
+ when '#' then push_state[:object]
64
+ when /[A-Z]/ then push_state[:class, :repeat]
65
+ when /[a-z]/ then push_state[:word, :repeat]
66
+ when /[0-9-]/ then push_state[:number, :repeat]
67
+ when '.' then push_state[:range, :repeat]
68
+ when /\=/ then push_state[:equal, :repeat]
69
+
70
+ when /\s/
71
+ if get_state[:variable]
72
+ pop_state[:repeat]
73
+ else
74
+ pass[:whitespace, c]
75
+ end
73
76
 
74
- when ','
75
- if get_state[:variable]
76
- pop_state[:repeat]
77
- else
78
- pass[:comma, ',']
79
- @refers_seen[-1] = false if get_state[:hash]
80
- end
77
+ when ','
78
+ if get_state[:variable]
79
+ pop_state[:repeat]
80
+ else
81
+ pass[:comma, ',']
82
+ @refers_seen[-1] = false if get_state[:hash]
83
+ end
81
84
 
82
- when ':'
83
- if get_state[:enumerator]
84
- set_state[:object_description, :repeat]
85
- else
86
- push_state[:symbol]
87
- end
88
-
89
- when '>'
90
- if get_state[:variable]
85
+ when ':'
86
+ if get_state[:enumerator]
87
+ set_state[:object_description, :repeat]
88
+ else
89
+ push_state[:symbol]
90
+ end
91
+
92
+ when '>'
91
93
  pop_state[:repeat]
92
- elsif @token == '' && nc =~ /[= ]/
93
- push_state[:gem_requirement_condition, :repeat]
94
- end
95
- when '('
96
- peek = chars[i+1..-1].join
97
- if peek =~ /^-?(?:Infinity|NaN|[0-9.e]+)[+-](?:Infinity|NaN|[0-9.e]+)\*?i\)/
98
- push_state[:complex, :repeat]
99
- elsif nc =~ /[0-9-]/
100
- if @passed =~ /Complex$/ # cheat for old 1.8
94
+ when '('
95
+ peek = chars[i+1..-1].join
96
+ if peek =~ /^-?(?:Infinity|NaN|[0-9.e]+)[+-](?:Infinity|NaN|[0-9.e]+)\*?i\)/
101
97
  push_state[:complex, :repeat]
98
+ elsif nc =~ /[0-9-]/
99
+ if @passed =~ /Complex$/ # cheat for old 1.8
100
+ push_state[:complex, :repeat]
101
+ else
102
+ push_state[:rational, :repeat]
103
+ end
102
104
  else
103
- push_state[:rational, :repeat]
105
+ push_state[:object_description, :repeat]
106
+ open_brackets = 0
104
107
  end
105
- else
106
- push_state[:object_description, :repeat]
107
- open_brackets = 0
108
- end
109
-
110
- when '{'
111
- if get_state[:set]
112
- pass[:open_set, '{']; push_state[nil] # {{ means set-hash
113
- else
114
- pass[:open_hash, '{']; push_state[:hash]
115
- @refers_seen ||= []
116
- @refers_seen.push false
117
- end
118
108
 
119
- when '['
120
- pass[:open_array, '[']; push_state[:array]
121
-
122
- when ']'
123
- if get_state[:array]
124
- pass[:close_array, ']']
109
+ when '{'
110
+ if get_state[:set]
111
+ pass[:open_set, '{']; push_state[nil] # {{ means set-hash
112
+ else
113
+ pass[:open_hash, '{']; push_state[:hash]
114
+ @refers_seen ||= []
115
+ @refers_seen.push false
116
+ end
117
+
118
+ when '['
119
+ pass[:open_array, '[']; push_state[:array]
120
+
121
+ when ']'
122
+ if get_state[:array]
123
+ pass[:close_array, ']']
124
+ pop_state[]
125
+ pop_state[] if get_state[:enumerator]
126
+ end
127
+
128
+ when '}'
129
+ if get_state[:hash]
130
+ pass[:close_hash, '}']
131
+ @refers_seen.pop
132
+ elsif get_previous_state[:set]
133
+ pass[:close_set, '}']
134
+ pop_state[] # remove extra nil state
135
+ end
125
136
  pop_state[]
126
137
  pop_state[] if get_state[:enumerator]
127
- end
128
-
129
- when '}'
130
- if get_state[:hash]
131
- pass[:close_hash, '}']
132
- @refers_seen.pop
133
- elsif get_previous_state[:set]
134
- pass[:close_set, '}']
135
- pop_state[] # remove extra nil state
136
- end
137
- pop_state[]
138
- pop_state[] if get_state[:enumerator]
139
138
 
140
- when '<'
141
- if nc =~ /[= ]/
142
- push_state[:gem_requirement_condition, :repeat]
143
- else # MAYBE slightly refactoring
139
+ when '<'
144
140
  pass[:open_object, '<']
145
141
  push_state[:object]
146
142
  push_state[:object_class]
147
143
  open_brackets = 0
148
144
  end
149
145
 
150
- # else
151
- # warn "ignoring char #{c.inspect}" if @debug
152
- end
153
-
154
- when :class
155
- next set_state[:time, :repeat] if c == ' ' # Ruby 1.8 default timestamp
156
- case c
157
- when /[a-z0-9_]/i
158
- @token << c
159
- else
160
- if @token =~ /^(Infinity|NaN)$/
161
- set_state[:special_number, :repeat]
162
- elsif c ==':' && nc == ':'
163
- pass_state[]
164
- pass[:class_separator, '::']
165
- elsif !(c == ':' && lc == ':')
166
- pass_state[:remove, :repeat]
146
+ when :class
147
+ case c
148
+ when /[a-z0-9_]/i
149
+ @token << c
150
+ else
151
+ if @token =~ /^(Infinity|NaN)$/
152
+ set_state[:special_number, :repeat]
153
+ elsif c ==':' && nc == ':'
154
+ pass_state[]
155
+ pass[:class_separator, '::']
156
+ elsif !(c == ':' && lc == ':')
157
+ pass_state[:remove, :repeat]
158
+ end
167
159
  end
168
- end
169
160
 
170
- when :symbol
171
- case c
172
- when /"/
173
- if lc == '$' && llc == ':'
161
+ when :symbol
162
+ case c
163
+ when /"/
164
+ if lc == '$' && llc == ':'
165
+ @token << c
166
+ else
167
+ pass[:symbol_prefix, ':']
168
+ set_state[:symbol_string]
169
+ end
170
+ when /[^"., }\])=]/
174
171
  @token << c
175
172
  else
176
- pass[:symbol_prefix, ':']
177
- set_state[:symbol_string]
173
+ if c == ']' && lc == '['
174
+ @token << c
175
+ elsif c == '=' && nc != '>'
176
+ @token << c
177
+ elsif c =~ /[.,]/ && lc == '$' && llc == ':'
178
+ @token << c
179
+ else
180
+ pass[:symbol_prefix, ':']
181
+ pass_state[:remove, :repeat]
182
+ end
178
183
  end
179
- when /[^"., }\])=]/
180
- @token << c
181
- else
182
- if c == ']' && lc == '['
184
+
185
+ when :symbol_string
186
+ if c == '"' && ( !( @token =~ /\\+$/; $& ) || $&.size % 2 == 0 ) # see string
187
+ pass[:open_symbol_string, '"']
188
+ pass_state[:remove]
189
+ pass[:close_symbol_string, '"']
190
+ else
183
191
  @token << c
184
- elsif c == '=' && nc != '>'
192
+ end
193
+
194
+ when :string
195
+ if c == '"' && ( !( @token =~ /\\+$/; $& ) || $&.size % 2 == 0 ) # allow escaping of " and
196
+ pass[:open_string, '"'] # work around \\
197
+ pass_state[:remove]
198
+ pass[:close_string, '"']
199
+ else
185
200
  @token << c
186
- elsif c =~ /[.,]/ && lc == '$' && llc == ':'
201
+ end
202
+
203
+ when :regexp
204
+ if c == '/' && ( !( @token =~ /\\+$/; $& ) || $&.size % 2 == 0 ) # see string
205
+ pass[:open_regexp, '/']
206
+ pass_state[:remove]
207
+ pass[:close_regexp, '/']
208
+ push_state[:regexp_flags]
209
+ else
210
+ @token << c
211
+ end
212
+
213
+ when :regexp_flags
214
+ if c =~ /[a-z]/i #*%w[m i x o n e u s]
187
215
  @token << c
188
216
  else
189
- pass[:symbol_prefix, ':']
190
217
  pass_state[:remove, :repeat]
191
218
  end
192
- end
193
-
194
- when :symbol_string
195
- if c == '"' && ( !( @token =~ /\\+$/; $& ) || $&.size % 2 == 0 ) # see string
196
- pass[:open_symbol_string, '"']
197
- pass_state[:remove]
198
- pass[:close_symbol_string, '"']
199
- else
200
- @token << c
201
- end
202
-
203
- when :string
204
- if c == '"' && ( !( @token =~ /\\+$/; $& ) || $&.size % 2 == 0 ) # allow escaping of " and
205
- pass[:open_string, '"'] # work around \\
206
- pass_state[:remove]
207
- pass[:close_string, '"']
208
- else
209
- @token << c
210
- end
211
219
 
212
- when :regexp
213
- if c == '/' && ( !( @token =~ /\\+$/; $& ) || $&.size % 2 == 0 ) # see string
214
- pass[:open_regexp, '/']
215
- pass_state[:remove]
216
- pass[:close_regexp, '/']
217
- push_state[:regexp_flags]
218
- else
219
- @token << c
220
- end
221
-
222
- when :regexp_flags
223
- if c =~ /[a-z]/i #*%w[m i x o n e u s]
224
- @token << c
225
- else
226
- pass_state[:remove, :repeat]
227
- end
220
+ when :word
221
+ if c =~ /[a-z0-9_]/i
222
+ @token << c
223
+ pass_custom_state[@token.to_sym, :remove] if %w[nil false true].include?(@token)
224
+ else
225
+ pass_state[:remove, :repeat]
226
+ end
228
227
 
229
- when :keyword
230
- if c =~ /[a-z0-9_]/i
231
- @token << c
232
- pass_custom_state[@token.to_sym, :remove] if %w[nil false true].include?(@token)
233
- else
234
- pass_state[:remove, :repeat]
235
- end
228
+ when :number
229
+ if c == '-' && @token != '' && @token[-1] != 'e'
230
+ set_state[:time, :repeat]
231
+ elsif c =~ /[IN]/
232
+ set_state[:special_number, :repeat]
233
+ elsif c =~ /[0-9e.*i+-]/ && !(c == '.' && nc == '.')
234
+ @token << c
235
+ else
236
+ pass_state[:remove, :repeat]
237
+ end
236
238
 
237
- when :number
238
- if c == '-' && @token != '' && @token[-1] != 'e'
239
- set_state[:time, :repeat]
240
- elsif c =~ /[IN]/
241
- set_state[:special_number, :repeat]
242
- elsif c =~ /[0-9e.*i+-]/ && !(c == '.' && nc == '.')
243
- @token << c
244
- elsif c == '/' # ruby 1.8 mathn
245
- pass_state[]
246
- pass[:rational_separator, '/']
247
- else
248
- pass_state[:remove, :repeat]
249
- end
239
+ when :time # via regex, state needs to be triggered somewhere else
240
+ peek = chars[i..-1].join
241
+ if [
242
+ /^\d+-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:[+-]\d{4}|[a-z]{3})/i, # 1.9 / UTC
243
+ ].any?{ |regex|
244
+ ( @token + peek ) =~ regex
245
+ } # found, adjust parsing-pointer:
246
+ i = i + $&.size - @token.size - 1
247
+ @token = $&
248
+ pass_state[:remove]
249
+ else
250
+ @token << c
251
+ pop_state[:remove]
252
+ end
250
253
 
251
- when :time # via regex, state needs to be triggered somewhere else
252
- peek = chars[i..-1].join
253
- if [
254
- /^\d+-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:[+-]\d{4}|[a-z]{3})/i, # 1.9 / UTC
255
- /^[a-z]{3} [a-z]{3} \d{2} \d{2}:\d{2}:\d{2} (?:[+-]\d{4}|[a-z]{3}) \d{4}/i, # 1.8
256
- #/^\d+-\d{2}-\d{2}/, # simple date
257
- ].any?{ |regex|
258
- ( @token + peek ) =~ regex
259
- } # found, adjust parsing-pointer:
260
- i = i + $&.size - @token.size - 1
261
- @token = $&
262
- pass_state[:remove]
263
- else
264
- @token << c
265
- pop_state[:remove]
266
- end
254
+ when :special_number # like time, refactor if code is needed a third time
255
+ peek = chars[i..-1].join
256
+ if [
257
+ /^[-+]?Infinity/,
258
+ /^[-+]?NaN/,
259
+ ].any?{ |regex|
260
+ ( @token + peek ) =~ regex
261
+ } # found, adjust parsing-pointer:
262
+ i = i + $&.size - @token.size - 1
263
+ @token = $&
264
+ pass_state[]
265
+ set_state[:number]
266
+ else
267
+ # TODO verify...
268
+ @token << c
269
+ set_state[:number]
270
+ end
267
271
 
268
- when :special_number # like time, refactor if code is needed a third time
269
- peek = chars[i..-1].join
270
- if [
271
- /^[-+]?Infinity/,
272
- /^[-+]?NaN/,
273
- ].any?{ |regex|
274
- ( @token + peek ) =~ regex
275
- } # found, adjust parsing-pointer:
276
- i = i + $&.size - @token.size - 1
277
- @token = $&
278
- pass_state[]
279
- set_state[:number]
280
- else
281
- # TODO verify...
282
- @token << c
283
- set_state[:number]
284
- end
285
-
286
- when :range
287
- if c == '.'
288
- @token << c
289
- else
290
- pass_state[:remove, :repeat]
291
- end
272
+ when :range
273
+ if c == '.'
274
+ @token << c
275
+ else
276
+ pass_state[:remove, :repeat]
277
+ end
292
278
 
293
- when :rational
294
- case c
295
- when '('
296
- pass[:open_rational, '(']
297
- when /[0-9-]/
298
- push_state[:number, :repeat]
299
- when '/', ','
300
- pass[:rational_separator, c]
301
- when ' '
302
- pass[:whitespace, c]
303
- when ')'
304
- pass[:close_rational, ')']
305
- pop_state[]
306
- end
279
+ when :rational
280
+ case c
281
+ when '('
282
+ pass[:open_rational, '(']
283
+ when /[0-9-]/
284
+ push_state[:number, :repeat]
285
+ when '/', ','
286
+ pass[:rational_separator, c]
287
+ when ' '
288
+ pass[:whitespace, c]
289
+ when ')'
290
+ pass[:close_rational, ')']
291
+ pop_state[]
292
+ end
307
293
 
308
- when :complex
309
- case c
310
- when '('
311
- pass[:open_complex, '(']
312
- when /[0-9+-]/
313
- push_state[:number, :repeat]
314
- when ','
315
- pass[:number, c] # complex_separator
316
- when ' '
317
- pass[:whitespace, c]
318
- when ')'
319
- pass[:close_complex, ')']
320
- pop_state[]
321
- end
294
+ when :complex
295
+ case c
296
+ when '('
297
+ pass[:open_complex, '(']
298
+ when /[0-9+-]/
299
+ push_state[:number, :repeat]
300
+ when ','
301
+ pass[:number, c] # complex_separator
302
+ when ' '
303
+ pass[:whitespace, c]
304
+ when ')'
305
+ pass[:close_complex, ')']
306
+ pop_state[]
307
+ end
322
308
 
323
- when :object
324
- case c
325
- when '<'
326
- pass[:open_object, '#<']
327
- push_state[:object_class]
328
- open_brackets = 0
329
- when '>'
330
- pass[:close_object, '>']
331
- pop_state[]
332
- pop_state[] if get_state[:enumerator]
333
- end
309
+ when :object
310
+ case c
311
+ when '<'
312
+ pass[:open_object, '#<']
313
+ push_state[:object_class]
314
+ open_brackets = 0
315
+ when '>'
316
+ pass[:close_object, '>']
317
+ pop_state[]
318
+ pop_state[] if get_state[:enumerator]
319
+ end
334
320
 
335
- when :object_class
336
- case c
337
- when /[a-z0-9_]/i
338
- @token << c
339
- when '>'
340
- pass_state[:remove, :repeat]
341
- else
342
- if c == ':' && nc == ':'
343
- pass_state[]
344
- pass[:class_separator, '::']
345
- elsif !(c == ':' && lc == ':')
346
- pass_state[:keep_token]
347
- pass[:object_description_prefix, c]
348
-
349
- @token = @token.downcase
350
- if %w[set instructionsequence].include?(@token)
351
- set_state[@token.to_sym]
352
- else
353
- set_state[:object_description]
354
- if %w[enumerator].include?(@token) && RUBY_VERSION >= '1.9'
355
- push_state[@token.to_sym]
321
+ when :object_class
322
+ case c
323
+ when /[a-z0-9_]/i
324
+ @token << c
325
+ when '>'
326
+ pass_state[:remove, :repeat]
327
+ else
328
+ if c == ':' && nc == ':'
329
+ pass_state[]
330
+ pass[:class_separator, '::']
331
+ elsif c != ':' || lc != ':'
332
+ pass_state[:keep_token]
333
+ pass[:object_description_prefix, c]
334
+
335
+ @token = @token.downcase
336
+ if %w[set instructionsequence].include?(@token)
337
+ set_state[@token.to_sym]
338
+ else
339
+ set_state[:object_description]
340
+ if @token == "enumerator" && RUBY_ENGINE != "rbx"
341
+ push_state[:enumerator]
342
+ end
356
343
  end
344
+ @token = ''
357
345
  end
358
- @token = ''
359
346
  end
360
- end
361
347
 
362
- when :object_description
363
- case c
364
- when '>', nil
365
- if open_brackets == 0
366
- pass_state[:remove, :repeat]
367
- else
368
- open_brackets -= 1
348
+ when :object_description
349
+ case c
350
+ when '>', nil
351
+ if open_brackets == 0
352
+ pass_state[:remove, :repeat]
353
+ else
354
+ open_brackets -= 1
355
+ @token << c
356
+ end
357
+ when '#'
358
+ if nc == '<'
359
+ pass_state[]
360
+ push_state[:object]
361
+ else
362
+ @token << c
363
+ end
364
+ when '<'
365
+ open_brackets += 1
369
366
  @token << c
370
- end
371
- when '#'
372
- if nc == '<'
367
+ when '@'
368
+ if nc =~ /[a-z_]/i
369
+ pass_state[]
370
+ push_state[:object_variable]
371
+ else
372
+ @token << c
373
+ end
374
+ when '"'
373
375
  pass_state[]
374
- push_state[:object]
376
+ push_state[:string]
377
+ when /[0-9]/
378
+ if c == '0' && nc == 'x'
379
+ pass_state[:repeat]
380
+ push_state[:object_address]
381
+ else
382
+ # push_state[:number, :repeat]
383
+ @token << c
384
+ end
375
385
  else
376
386
  @token << c
377
387
  end
378
- when '<'
379
- open_brackets += 1
380
- @token << c
381
- when '@'
382
- if nc =~ /[a-z]/i
383
- pass_state[]
384
- push_state[:object_variable]
388
+
389
+ when :object_variable
390
+ if c =~ /[a-z0-9_]/i
391
+ @token << c
385
392
  else
393
+ pass[:object_variable_prefix, '@']
394
+ pass_state[:remove]
395
+ pass[:object_description, '=']
396
+ push_state[:variable]
397
+ end
398
+
399
+ when :object_address
400
+ if c =~ /[x0-9a-f]/
386
401
  @token << c
402
+ else
403
+ if c == '@'
404
+ pass_state[:remove]
405
+ push_state[:object_line]
406
+ pass[:object_line_prefix, '@']
407
+ else
408
+ pass_state[:remove, :repeat]
409
+ end
387
410
  end
388
- when '"'
389
- pass_state[]
390
- push_state[:string]
391
- when /[0-9]/
392
- if c == '0' && nc == 'x'
393
- pass_state[:repeat]
394
- push_state[:object_address]
411
+
412
+ when :object_line
413
+ if c == ':' && nc =~ /[0-9]/
414
+ @token << ':'
415
+ pass_state[:remove]
416
+ push_state[:object_line_number]
417
+ elsif c == '>' # e.g. RubyVM
418
+ pass_state[:remove, :repeat]
395
419
  else
396
- # push_state[:number, :repeat]
397
420
  @token << c
398
421
  end
399
- else
400
- @token << c
401
- end
402
422
 
403
- when :object_variable
404
- if c =~ /[a-z0-9_]/i
405
- @token << c
406
- else
407
- pass[:object_variable_prefix, '@']
408
- pass_state[:remove]
409
- pass[:object_description, '=']
410
- push_state[:variable]
411
- end
412
-
413
- when :object_address
414
- if c =~ /[x0-9a-f]/
415
- @token << c
416
- else
417
- if c == '@'
418
- pass_state[:remove]
419
- push_state[:object_line]
420
- pass[:object_line_prefix, '@']
423
+ when :object_line_number
424
+ if c =~ /[0-9]/
425
+ @token << c
421
426
  else
422
427
  pass_state[:remove, :repeat]
423
428
  end
424
- end
425
429
 
426
- when :object_line
427
- if c == ':' && nc =~ /[0-9]/
428
- @token << ':'
429
- pass_state[:remove]
430
- push_state[:object_line_number]
431
- elsif c == '>' # e.g. RubyVM
432
- pass_state[:remove, :repeat]
433
- else
434
- @token << c
435
- end
436
-
437
- when :object_line_number
438
- if c =~ /[0-9]/
439
- @token << c
440
- else
441
- pass_state[:remove, :repeat]
442
- end
443
-
444
- when :gem_requirement_condition
445
- if c == '>' && lc == '='
446
- @token = ''; pop_state[] # TODO in pass helper
447
- if get_state[:hash]
448
- if nc == '=' || @refers_seen[-1]
430
+ when :equal
431
+ if c == '>' && lc == '='
432
+ @token = ''; pop_state[] # TODO in pass helper
433
+ if get_state[:hash]
434
+ if nc == '=' || @refers_seen[-1]
435
+ pass[:symbol, '=>']
436
+ else
437
+ pass[:refers, '=>']
438
+ @refers_seen[-1] = true
439
+ end
440
+ else # MAYBE remove this <=> cheat
449
441
  pass[:symbol, '=>']
450
- else
451
- pass[:refers, '=>']
452
- @refers_seen[-1] = true
453
442
  end
454
- else # MAYBE remove this <=> cheat
455
- pass[:symbol, '=>']
443
+ elsif c =~ /\S/
444
+ @token << c
445
+ else
446
+ pass[:whitespace, c]
456
447
  end
457
- elsif c =~ /[^\s]/
458
- @token << c
459
- else
460
- pass_state[:remove]
461
- pass[:whitespace, c]
462
- push_state[:gem_requirement_version]
463
- end
464
448
 
465
- when :gem_requirement_version
466
- if c =~ /[0-9a-z.]/i
467
- @token << c
468
- else
469
- pass_state[:remove, :repeat]
470
- end
449
+ when :instructionsequence # RubyVM
450
+ if c =~ /[^@]/i
451
+ @token << c
452
+ else
453
+ pass[:object_line_prefix, @token + '@']
454
+ @token = ''
455
+ set_state[:object_line]
456
+ end
471
457
 
472
- when :instructionsequence # RubyVM
473
- if c =~ /[^@]/i
474
- @token << c
475
458
  else
476
- pass[:object_line_prefix, @token + '@']
477
- @token = ''
478
- set_state[:object_line]
459
+ raise "unknown state #{@state[-1]} #{@state.inspect}"
479
460
  end
480
461
 
481
-
482
- # else
483
- # raise "unknown state #{@state[-1]} #{@state.inspect}"
484
- end
462
+ # next round
463
+ if !@repeat
464
+ i += 1
465
+ elsif snapshot && Marshal.load(snapshot) == [@state, @token, llc, lc, c, nc] # loop protection
466
+ raise "This might be a WIRB bug, please open an issue at:\nhttps://github.com/janlelis/wirb/issues/new"
467
+ end
485
468
 
486
- # next round :)
487
- if !@repeat
488
- i += 1
489
- elsif snapshot && Marshal.load(snapshot) == [@state, @token, llc, lc, c, nc] # loop protection
490
- raise 'Wirb Bug :/'
469
+ snapshot = Marshal.dump([@state, @token, llc, lc, c, nc])
491
470
  end
492
-
493
- snapshot = Marshal.dump([@state, @token, llc, lc, c, nc])
494
471
  end
495
- rescue
496
- p$!, $!.backtrace[0] if $VERBOSE
497
- pass[:default, str.sub(@passed, '')]
498
472
  end
499
473
  end
500
474