parser 2.1.0.pre1 → 2.1.0.pre2
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.md +12 -0
- data/lib/parser.rb +1 -52
- data/lib/parser/base.rb +5 -7
- data/lib/parser/builders/default.rb +12 -20
- data/lib/parser/diagnostic.rb +23 -5
- data/lib/parser/diagnostic/engine.rb +3 -2
- data/lib/parser/lexer.rl +27 -37
- data/lib/parser/lexer/literal.rb +3 -7
- data/lib/parser/messages.rb +64 -0
- data/lib/parser/ruby18.y +12 -12
- data/lib/parser/ruby19.y +11 -11
- data/lib/parser/ruby20.y +10 -10
- data/lib/parser/ruby21.y +10 -10
- data/lib/parser/source/rewriter.rb +4 -2
- data/lib/parser/version.rb +1 -1
- data/test/parse_helper.rb +5 -2
- data/test/test_diagnostic.rb +5 -5
- data/test/test_diagnostic_engine.rb +6 -6
- data/test/test_lexer.rb +8 -0
- metadata +45 -44
data/lib/parser/lexer/literal.rb
CHANGED
@@ -44,8 +44,8 @@ module Parser
|
|
44
44
|
delimiter = coerce_encoding(delimiter)
|
45
45
|
|
46
46
|
unless TYPES.include?(str_type)
|
47
|
-
|
48
|
-
|
47
|
+
lexer.send(:diagnostic, :error, :unexpected_percent_str,
|
48
|
+
{ :type => str_type }, @lexer.send(:range, str_s, str_s + 2))
|
49
49
|
end
|
50
50
|
|
51
51
|
# String type. For :'foo', it is :'
|
@@ -157,11 +157,7 @@ module Parser
|
|
157
157
|
|
158
158
|
@buffer_e = te
|
159
159
|
|
160
|
-
|
161
|
-
@buffer << string.encode(@lexer.encoding)
|
162
|
-
else
|
163
|
-
@buffer << string
|
164
|
-
end
|
160
|
+
@buffer << string
|
165
161
|
end
|
166
162
|
|
167
163
|
def flush_string
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Parser
|
2
|
+
##
|
3
|
+
# Diagnostic messages (errors, warnings and notices) that can be generated.
|
4
|
+
#
|
5
|
+
# @see Diagnostic
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
#
|
9
|
+
MESSAGES = {
|
10
|
+
# Lexer errors
|
11
|
+
:unicode_point_too_large => 'invalid Unicode codepoint (too large)',
|
12
|
+
:invalid_escape => 'invalid escape character syntax',
|
13
|
+
:incomplete_escape => 'incomplete character syntax',
|
14
|
+
:invalid_hex_escape => 'invalid hex escape',
|
15
|
+
:invalid_unicode_escape => 'invalid Unicode escape',
|
16
|
+
:unterminated_unicode => 'unterminated Unicode escape',
|
17
|
+
:escape_eof => 'escape sequence meets end of file',
|
18
|
+
:string_eof => 'unterminated string meets end of file',
|
19
|
+
:regexp_options => 'unknown regexp options: %{options}',
|
20
|
+
:cvar_name => "`%{name}' is not allowed as a class variable name",
|
21
|
+
:ivar_name => "`%{name}' is not allowed as an instance variable name",
|
22
|
+
:trailing_in_number => "trailing `%{character}' in number",
|
23
|
+
:empty_numeric => 'numeric literal without digits',
|
24
|
+
:invalid_octal => 'invalid octal digit',
|
25
|
+
:no_dot_digit_literal => 'no .<digit> floating literal anymore; put 0 before dot',
|
26
|
+
:bare_backslash => 'bare backslash only allowed before newline',
|
27
|
+
:unexpected => "unexpected `%{character}'",
|
28
|
+
:embedded_document => 'embedded document meets end of file (and they embark on a romantic journey)',
|
29
|
+
|
30
|
+
# Lexer warnings
|
31
|
+
:invalid_escape_use => 'invalid character syntax; use ?%{escape}',
|
32
|
+
:ambiguous_literal => 'ambiguous first argument; parenthesize arguments or add whitespace to the right',
|
33
|
+
:ambiguous_prefix => "`%{prefix}' interpreted as argument prefix",
|
34
|
+
|
35
|
+
# Parser errors
|
36
|
+
:nth_ref_alias => 'cannot define an alias for a back-reference variable',
|
37
|
+
:begin_in_method => 'BEGIN in method',
|
38
|
+
:backref_assignment => 'cannot assign to a back-reference variable',
|
39
|
+
:invalid_assignment => 'cannot assign to a keyword',
|
40
|
+
:module_name_const => 'class or module name must be a constant literal',
|
41
|
+
:unexpected_token => 'unexpected token %{token}',
|
42
|
+
:argument_const => 'formal argument cannot be a constant',
|
43
|
+
:argument_ivar => 'formal argument cannot be an instance variable',
|
44
|
+
:argument_gvar => 'formal argument cannot be a global variable',
|
45
|
+
:argument_cvar => 'formal argument cannot be a class variable',
|
46
|
+
:duplicate_argument => 'duplicate argument name',
|
47
|
+
:empty_symbol => 'empty symbol literal',
|
48
|
+
:odd_hash => 'odd number of entries for a hash',
|
49
|
+
:singleton_literal => 'cannot define a singleton method for a literal',
|
50
|
+
:dynamic_const => 'dynamic constant assignment',
|
51
|
+
:module_in_def => 'module definition in method body',
|
52
|
+
:class_in_def => 'class definition in method body',
|
53
|
+
:unexpected_percent_str => '%{type}: unknown type of percent-literal',
|
54
|
+
:block_and_blockarg => 'both block argument and literal block are passed',
|
55
|
+
:masgn_as_condition => 'multiple assignment in conditional context',
|
56
|
+
|
57
|
+
# Parser warnings
|
58
|
+
:useless_else => 'else without rescue is useless',
|
59
|
+
|
60
|
+
# Rewriter diagnostics
|
61
|
+
:invalid_action => 'cannot %{action}',
|
62
|
+
:clobbered => 'clobbered by: %{action}',
|
63
|
+
}.freeze
|
64
|
+
end
|
data/lib/parser/ruby18.y
CHANGED
@@ -55,7 +55,7 @@ rule
|
|
55
55
|
ensure_t, ensure_ = val[3]
|
56
56
|
|
57
57
|
if rescue_bodies.empty? && !else_.nil?
|
58
|
-
diagnostic :warning, :useless_else, else_t
|
58
|
+
diagnostic :warning, :useless_else, nil, else_t
|
59
59
|
end
|
60
60
|
|
61
61
|
result = @builder.begin_body(val[0],
|
@@ -108,7 +108,7 @@ rule
|
|
108
108
|
}
|
109
109
|
| kALIAS tGVAR tNTH_REF
|
110
110
|
{
|
111
|
-
diagnostic
|
111
|
+
diagnostic :error, :nth_ref_alias, nil, val[2]
|
112
112
|
}
|
113
113
|
| kUNDEF undef_list
|
114
114
|
{
|
@@ -143,7 +143,7 @@ rule
|
|
143
143
|
| klBEGIN tLCURLY compstmt tRCURLY
|
144
144
|
{
|
145
145
|
if in_def?
|
146
|
-
diagnostic
|
146
|
+
diagnostic :error, :begin_in_method, nil, val[0]
|
147
147
|
end
|
148
148
|
|
149
149
|
result = @builder.preexe(val[0], val[1], val[2], val[3])
|
@@ -468,7 +468,7 @@ rule
|
|
468
468
|
|
469
469
|
cname: tIDENTIFIER
|
470
470
|
{
|
471
|
-
diagnostic
|
471
|
+
diagnostic :error, :module_name_const, nil, val[0]
|
472
472
|
}
|
473
473
|
| tCONSTANT
|
474
474
|
|
@@ -573,11 +573,11 @@ rule
|
|
573
573
|
}
|
574
574
|
| primary_value tCOLON2 tCONSTANT tOP_ASGN arg
|
575
575
|
{
|
576
|
-
diagnostic
|
576
|
+
diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ]
|
577
577
|
}
|
578
578
|
| tCOLON3 tCONSTANT tOP_ASGN arg
|
579
579
|
{
|
580
|
-
diagnostic
|
580
|
+
diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ]
|
581
581
|
}
|
582
582
|
| backref tOP_ASGN arg
|
583
583
|
{
|
@@ -1126,7 +1126,7 @@ rule
|
|
1126
1126
|
bodystmt kEND
|
1127
1127
|
{
|
1128
1128
|
if in_def?
|
1129
|
-
diagnostic
|
1129
|
+
diagnostic :error, :class_in_def, nil, val[0]
|
1130
1130
|
end
|
1131
1131
|
|
1132
1132
|
lt_t, superclass = val[2]
|
@@ -1159,7 +1159,7 @@ rule
|
|
1159
1159
|
bodystmt kEND
|
1160
1160
|
{
|
1161
1161
|
if in_def?
|
1162
|
-
diagnostic
|
1162
|
+
diagnostic :error, :module_in_def, nil, val[0]
|
1163
1163
|
end
|
1164
1164
|
|
1165
1165
|
result = @builder.def_module(val[0], val[1],
|
@@ -1768,19 +1768,19 @@ xstring_contents: # nothing
|
|
1768
1768
|
|
1769
1769
|
f_norm_arg: tCONSTANT
|
1770
1770
|
{
|
1771
|
-
diagnostic
|
1771
|
+
diagnostic :error, :argument_const, nil, val[0]
|
1772
1772
|
}
|
1773
1773
|
| tIVAR
|
1774
1774
|
{
|
1775
|
-
diagnostic
|
1775
|
+
diagnostic :error, :argument_ivar, nil, val[0]
|
1776
1776
|
}
|
1777
1777
|
| tGVAR
|
1778
1778
|
{
|
1779
|
-
diagnostic
|
1779
|
+
diagnostic :error, :argument_gvar, nil, val[0]
|
1780
1780
|
}
|
1781
1781
|
| tCVAR
|
1782
1782
|
{
|
1783
|
-
diagnostic
|
1783
|
+
diagnostic :error, :argument_cvar, nil, val[0]
|
1784
1784
|
}
|
1785
1785
|
| tIDENTIFIER
|
1786
1786
|
{
|
data/lib/parser/ruby19.y
CHANGED
@@ -82,7 +82,7 @@ rule
|
|
82
82
|
ensure_t, ensure_ = val[3]
|
83
83
|
|
84
84
|
if rescue_bodies.empty? && !else_.nil?
|
85
|
-
diagnostic :warning, :useless_else, else_t
|
85
|
+
diagnostic :warning, :useless_else, nil, else_t
|
86
86
|
end
|
87
87
|
|
88
88
|
result = @builder.begin_body(val[0],
|
@@ -135,7 +135,7 @@ rule
|
|
135
135
|
}
|
136
136
|
| kALIAS tGVAR tNTH_REF
|
137
137
|
{
|
138
|
-
diagnostic
|
138
|
+
diagnostic :error, :nth_ref_alias, nil, val[2]
|
139
139
|
}
|
140
140
|
| kUNDEF undef_list
|
141
141
|
{
|
@@ -528,7 +528,7 @@ rule
|
|
528
528
|
|
529
529
|
cname: tIDENTIFIER
|
530
530
|
{
|
531
|
-
diagnostic
|
531
|
+
diagnostic :error, :module_name_const, nil, val[0]
|
532
532
|
}
|
533
533
|
| tCONSTANT
|
534
534
|
|
@@ -645,11 +645,11 @@ rule
|
|
645
645
|
}
|
646
646
|
| primary_value tCOLON2 tCONSTANT tOP_ASGN arg
|
647
647
|
{
|
648
|
-
diagnostic
|
648
|
+
diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ]
|
649
649
|
}
|
650
650
|
| tCOLON3 tCONSTANT tOP_ASGN arg
|
651
651
|
{
|
652
|
-
diagnostic
|
652
|
+
diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ]
|
653
653
|
}
|
654
654
|
| backref tOP_ASGN arg
|
655
655
|
{
|
@@ -1088,7 +1088,7 @@ rule
|
|
1088
1088
|
bodystmt kEND
|
1089
1089
|
{
|
1090
1090
|
if in_def?
|
1091
|
-
diagnostic
|
1091
|
+
diagnostic :error, :class_in_def, nil, val[0]
|
1092
1092
|
end
|
1093
1093
|
|
1094
1094
|
lt_t, superclass = val[2]
|
@@ -1121,7 +1121,7 @@ rule
|
|
1121
1121
|
bodystmt kEND
|
1122
1122
|
{
|
1123
1123
|
if in_def?
|
1124
|
-
diagnostic
|
1124
|
+
diagnostic :error, :module_in_def, nil, val[0]
|
1125
1125
|
end
|
1126
1126
|
|
1127
1127
|
result = @builder.def_module(val[0], val[1],
|
@@ -1952,19 +1952,19 @@ keyword_variable: kNIL
|
|
1952
1952
|
|
1953
1953
|
f_bad_arg: tCONSTANT
|
1954
1954
|
{
|
1955
|
-
diagnostic
|
1955
|
+
diagnostic :error, :argument_const, nil, val[0]
|
1956
1956
|
}
|
1957
1957
|
| tIVAR
|
1958
1958
|
{
|
1959
|
-
diagnostic
|
1959
|
+
diagnostic :error, :argument_ivar, nil, val[0]
|
1960
1960
|
}
|
1961
1961
|
| tGVAR
|
1962
1962
|
{
|
1963
|
-
diagnostic
|
1963
|
+
diagnostic :error, :argument_gvar, nil, val[0]
|
1964
1964
|
}
|
1965
1965
|
| tCVAR
|
1966
1966
|
{
|
1967
|
-
diagnostic
|
1967
|
+
diagnostic :error, :argument_cvar, nil, val[0]
|
1968
1968
|
}
|
1969
1969
|
|
1970
1970
|
f_norm_arg: f_bad_arg
|
data/lib/parser/ruby20.y
CHANGED
@@ -82,7 +82,7 @@ rule
|
|
82
82
|
ensure_t, ensure_ = val[3]
|
83
83
|
|
84
84
|
if rescue_bodies.empty? && !else_.nil?
|
85
|
-
diagnostic :warning, :useless_else, else_t
|
85
|
+
diagnostic :warning, :useless_else, nil, else_t
|
86
86
|
end
|
87
87
|
|
88
88
|
result = @builder.begin_body(val[0],
|
@@ -117,7 +117,7 @@ rule
|
|
117
117
|
| klBEGIN tLCURLY top_compstmt tRCURLY
|
118
118
|
{
|
119
119
|
if in_def?
|
120
|
-
diagnostic
|
120
|
+
diagnostic :error, :begin_in_method, nil, val[0]
|
121
121
|
end
|
122
122
|
|
123
123
|
result = @builder.preexe(val[0], val[1], val[2], val[3])
|
@@ -145,7 +145,7 @@ rule
|
|
145
145
|
}
|
146
146
|
| kALIAS tGVAR tNTH_REF
|
147
147
|
{
|
148
|
-
diagnostic
|
148
|
+
diagnostic :error, :nth_ref_alias, nil, val[2]
|
149
149
|
}
|
150
150
|
| kUNDEF undef_list
|
151
151
|
{
|
@@ -535,7 +535,7 @@ rule
|
|
535
535
|
|
536
536
|
cname: tIDENTIFIER
|
537
537
|
{
|
538
|
-
diagnostic
|
538
|
+
diagnostic :error, :module_name_const, nil, val[0]
|
539
539
|
}
|
540
540
|
| tCONSTANT
|
541
541
|
|
@@ -1116,7 +1116,7 @@ rule
|
|
1116
1116
|
bodystmt kEND
|
1117
1117
|
{
|
1118
1118
|
if in_def?
|
1119
|
-
diagnostic
|
1119
|
+
diagnostic :error, :class_in_def, nil, val[0]
|
1120
1120
|
end
|
1121
1121
|
|
1122
1122
|
lt_t, superclass = val[2]
|
@@ -1149,7 +1149,7 @@ rule
|
|
1149
1149
|
bodystmt kEND
|
1150
1150
|
{
|
1151
1151
|
if in_def?
|
1152
|
-
diagnostic
|
1152
|
+
diagnostic :error, :module_in_def, nil, val[0]
|
1153
1153
|
end
|
1154
1154
|
|
1155
1155
|
result = @builder.def_module(val[0], val[1],
|
@@ -2075,19 +2075,19 @@ keyword_variable: kNIL
|
|
2075
2075
|
|
2076
2076
|
f_bad_arg: tCONSTANT
|
2077
2077
|
{
|
2078
|
-
diagnostic
|
2078
|
+
diagnostic :error, :argument_const, nil, val[0]
|
2079
2079
|
}
|
2080
2080
|
| tIVAR
|
2081
2081
|
{
|
2082
|
-
diagnostic
|
2082
|
+
diagnostic :error, :argument_ivar, nil, val[0]
|
2083
2083
|
}
|
2084
2084
|
| tGVAR
|
2085
2085
|
{
|
2086
|
-
diagnostic
|
2086
|
+
diagnostic :error, :argument_gvar, nil, val[0]
|
2087
2087
|
}
|
2088
2088
|
| tCVAR
|
2089
2089
|
{
|
2090
|
-
diagnostic
|
2090
|
+
diagnostic :error, :argument_cvar, nil, val[0]
|
2091
2091
|
}
|
2092
2092
|
|
2093
2093
|
f_norm_arg: f_bad_arg
|
data/lib/parser/ruby21.y
CHANGED
@@ -83,7 +83,7 @@ rule
|
|
83
83
|
ensure_t, ensure_ = val[3]
|
84
84
|
|
85
85
|
if rescue_bodies.empty? && !else_.nil?
|
86
|
-
diagnostic :warning, :useless_else, else_t
|
86
|
+
diagnostic :warning, :useless_else, nil, else_t
|
87
87
|
end
|
88
88
|
|
89
89
|
result = @builder.begin_body(val[0],
|
@@ -117,7 +117,7 @@ rule
|
|
117
117
|
stmt_or_begin: stmt
|
118
118
|
| klBEGIN tLCURLY top_compstmt tRCURLY
|
119
119
|
{
|
120
|
-
diagnostic
|
120
|
+
diagnostic :error, :begin_in_method, nil, val[0]
|
121
121
|
}
|
122
122
|
|
123
123
|
stmt: kALIAS fitem
|
@@ -142,7 +142,7 @@ rule
|
|
142
142
|
}
|
143
143
|
| kALIAS tGVAR tNTH_REF
|
144
144
|
{
|
145
|
-
diagnostic
|
145
|
+
diagnostic :error, :nth_ref_alias, nil, val[2]
|
146
146
|
}
|
147
147
|
| kUNDEF undef_list
|
148
148
|
{
|
@@ -527,7 +527,7 @@ rule
|
|
527
527
|
|
528
528
|
cname: tIDENTIFIER
|
529
529
|
{
|
530
|
-
diagnostic
|
530
|
+
diagnostic :error, :module_name_const, nil, val[0]
|
531
531
|
}
|
532
532
|
| tCONSTANT
|
533
533
|
|
@@ -1106,7 +1106,7 @@ rule
|
|
1106
1106
|
bodystmt kEND
|
1107
1107
|
{
|
1108
1108
|
if in_def?
|
1109
|
-
diagnostic
|
1109
|
+
diagnostic :error, :class_in_def, nil, val[0]
|
1110
1110
|
end
|
1111
1111
|
|
1112
1112
|
lt_t, superclass = val[2]
|
@@ -1139,7 +1139,7 @@ rule
|
|
1139
1139
|
bodystmt kEND
|
1140
1140
|
{
|
1141
1141
|
if in_def?
|
1142
|
-
diagnostic
|
1142
|
+
diagnostic :error, :module_in_def, nil, val[0]
|
1143
1143
|
end
|
1144
1144
|
|
1145
1145
|
result = @builder.def_module(val[0], val[1],
|
@@ -2062,19 +2062,19 @@ keyword_variable: kNIL
|
|
2062
2062
|
|
2063
2063
|
f_bad_arg: tCONSTANT
|
2064
2064
|
{
|
2065
|
-
diagnostic
|
2065
|
+
diagnostic :error, :argument_const, nil, val[0]
|
2066
2066
|
}
|
2067
2067
|
| tIVAR
|
2068
2068
|
{
|
2069
|
-
diagnostic
|
2069
|
+
diagnostic :error, :argument_ivar, nil, val[0]
|
2070
2070
|
}
|
2071
2071
|
| tGVAR
|
2072
2072
|
{
|
2073
|
-
diagnostic
|
2073
|
+
diagnostic :error, :argument_gvar, nil, val[0]
|
2074
2074
|
}
|
2075
2075
|
| tCVAR
|
2076
2076
|
{
|
2077
|
-
diagnostic
|
2077
|
+
diagnostic :error, :argument_cvar, nil, val[0]
|
2078
2078
|
}
|
2079
2079
|
|
2080
2080
|
f_norm_arg: f_bad_arg
|
@@ -118,13 +118,15 @@ module Parser
|
|
118
118
|
if (clobber_action = clobbered?(action.range))
|
119
119
|
# cannot replace 3 characters with "foobar"
|
120
120
|
diagnostic = Diagnostic.new(:error,
|
121
|
-
|
121
|
+
:invalid_action,
|
122
|
+
{ :action => action },
|
122
123
|
action.range)
|
123
124
|
@diagnostics.process(diagnostic)
|
124
125
|
|
125
126
|
# clobbered by: remove 3 characters
|
126
127
|
diagnostic = Diagnostic.new(:note,
|
127
|
-
|
128
|
+
:clobbered,
|
129
|
+
{ :action => clobber_action },
|
128
130
|
clobber_action.range)
|
129
131
|
@diagnostics.process(diagnostic)
|
130
132
|
|
data/lib/parser/version.rb
CHANGED
data/test/parse_helper.rb
CHANGED
@@ -129,10 +129,13 @@ module ParseHelper
|
|
129
129
|
|
130
130
|
emitted_diagnostic = @diagnostics.first
|
131
131
|
|
132
|
-
level,
|
133
|
-
|
132
|
+
level, reason, arguments = diagnostic
|
133
|
+
arguments ||= {}
|
134
|
+
message = Parser::MESSAGES[reason] % arguments
|
134
135
|
|
135
136
|
assert_equal level, emitted_diagnostic.level
|
137
|
+
assert_equal reason, emitted_diagnostic.reason
|
138
|
+
assert_equal arguments, emitted_diagnostic.arguments
|
136
139
|
assert_equal message, emitted_diagnostic.message
|
137
140
|
|
138
141
|
parse_source_map_descriptions(source_maps) \
|