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.
- checksums.yaml +4 -4
- data/{CHANGELOG.rdoc → CHANGELOG.md} +51 -25
- data/COPYING.txt +5 -5
- data/README.md +75 -0
- data/data/wirb/{classic_paint.yml → classic.yml} +11 -42
- data/data/wirb/colorless.yml +10 -27
- data/data/wirb/gray.yml +103 -0
- data/lib/wirb.rb +69 -114
- data/lib/wirb/inspector.rb +10 -0
- data/lib/wirb/irb.rb +3 -12
- data/lib/wirb/schema_builder.rb +44 -0
- data/lib/wirb/tokenizer.rb +404 -430
- data/lib/wirb/version.rb +1 -1
- data/lib/wirb/wp.rb +3 -7
- data/spec/spec_helper.rb +5 -122
- data/spec/tokenizer_enumerator_spec.rb +580 -37
- data/spec/tokenizer_misc_spec.rb +55 -53
- data/spec/tokenizer_number_spec.rb +30 -28
- data/spec/tokenizer_object_spec.rb +67 -31
- data/wirb.gemspec +8 -20
- metadata +33 -48
- data/.gemtest +0 -0
- data/README.rdoc +0 -79
- data/data/wirb/classic_wirb0.yml +0 -72
- data/lib/wirb/colorizer.rb +0 -26
- data/lib/wirb/colorizer/highline.rb +0 -16
- data/lib/wirb/colorizer/paint.rb +0 -11
- data/lib/wirb/colorizer/wirb0.rb +0 -53
- data/lib/wirb/colorizer/wirb0_highline.rb +0 -73
- data/lib/wirb/colorizer/wirb0_paint.rb +0 -71
- data/lib/wirb/colorizer/wirble.rb +0 -30
- data/spec/colorizer_highline_spec.rb +0 -23
- data/spec/colorizer_paint_spec.rb +0 -33
- data/spec/colorizer_spec.rb +0 -67
- data/spec/colorizer_wirb0_highline_spec.rb +0 -78
- data/spec/colorizer_wirb0_paint_spec.rb +0 -35
- data/spec/colorizer_wirb0_spec.rb +0 -11
- data/spec/colorizer_wirble_spec.rb +0 -24
- data/spec/tokenizer_rubygems_spec.rb +0 -84
data/lib/wirb.rb
CHANGED
@@ -1,135 +1,90 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
19
|
+
def timeout
|
20
|
+
@timeout ||= 3
|
21
|
+
end
|
53
22
|
|
54
|
-
|
55
|
-
|
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
|
-
|
67
|
-
@schema =
|
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
|
-
|
77
|
-
|
31
|
+
def load_schema(name)
|
32
|
+
@schema = SchemaBuilder.load_schema_from_yaml(name)
|
33
|
+
end
|
78
34
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
load_colorizer schema[:colorizer].first
|
83
|
-
@schema
|
84
|
-
end
|
35
|
+
def original_inspect_mode
|
36
|
+
@original_inspect_mode
|
37
|
+
end
|
85
38
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
98
|
-
def colorize_result(string, custom_schema = schema)
|
99
|
-
if @running
|
62
|
+
def colorize_result(string, _deprecated = nil)
|
100
63
|
check = ''
|
101
|
-
colorful =
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
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
|
data/lib/wirb/irb.rb
CHANGED
@@ -1,13 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../wirb' unless defined? Wirb
|
2
|
+
require 'irb'
|
2
3
|
|
3
|
-
|
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
|
data/lib/wirb/tokenizer.rb
CHANGED
@@ -1,500 +1,474 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
when
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
93
|
-
|
94
|
-
|
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[:
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
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
|
-
|
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
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
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
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
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
|
-
|
177
|
-
|
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
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
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
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
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
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
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
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
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
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
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
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
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
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
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
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
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
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
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
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
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
|
-
|
371
|
-
|
372
|
-
|
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[:
|
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
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
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
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
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
|
-
|
404
|
-
|
405
|
-
|
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
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
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
|
-
|
455
|
-
|
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
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
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
|
-
|
477
|
-
@token = ''
|
478
|
-
set_state[:object_line]
|
459
|
+
raise "unknown state #{@state[-1]} #{@state.inspect}"
|
479
460
|
end
|
480
461
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
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
|
-
|
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
|
|