@@ -9,11 +9,14 @@ module Translation
9
9
# the parser gem, and overrides the parse* methods to parse with prism and
10
10
# then translate.
11
11
class Parser < ::Parser ::Base
12
+ Diagnostic = ::Parser ::Diagnostic # :nodoc:
13
+ private_constant :Diagnostic
14
+
12
15
# The parser gem has a list of diagnostics with a hard-coded set of error
13
16
# messages. We create our own diagnostic class in order to set our own
14
17
# error messages.
15
- class Diagnostic < :: Parser :: Diagnostic
16
- # The message generated by prism.
18
+ class PrismDiagnostic < Diagnostic
19
+ # This is the cached message coming from prism.
17
20
attr_reader :message
18
21
19
22
# Initialize a new diagnostic with the given message and location.
@@ -112,20 +115,109 @@ def valid_warning?(warning)
112
115
true
113
116
end
114
117
118
+ # Build a diagnostic from the given prism parse error.
119
+ def error_diagnostic ( error , offset_cache )
120
+ location = error . location
121
+ diagnostic_location = build_range ( location , offset_cache )
122
+
123
+ case error . type
124
+ when :argument_block_multi
125
+ Diagnostic . new ( :error , :block_and_blockarg , { } , diagnostic_location , [ ] )
126
+ when :argument_formal_constant
127
+ Diagnostic . new ( :error , :formal_argument , { } , diagnostic_location , [ ] )
128
+ when :argument_formal_class
129
+ Diagnostic . new ( :error , :argument_cvar , { } , diagnostic_location , [ ] )
130
+ when :argument_formal_global
131
+ Diagnostic . new ( :error , :argument_gvar , { } , diagnostic_location , [ ] )
132
+ when :argument_formal_ivar
133
+ Diagnostic . new ( :error , :argument_ivar , { } , diagnostic_location , [ ] )
134
+ when :argument_no_forwarding_amp
135
+ Diagnostic . new ( :error , :no_anonymous_blockarg , { } , diagnostic_location , [ ] )
136
+ when :argument_no_forwarding_star
137
+ Diagnostic . new ( :error , :no_anonymous_restarg , { } , diagnostic_location , [ ] )
138
+ when :begin_lonely_else
139
+ location = location . copy ( length : 4 )
140
+ diagnostic_location = build_range ( location , offset_cache )
141
+ Diagnostic . new ( :error , :useless_else , { } , diagnostic_location , [ ] )
142
+ when :class_name , :module_name
143
+ Diagnostic . new ( :error , :module_name_const , { } , diagnostic_location , [ ] )
144
+ when :class_in_method
145
+ Diagnostic . new ( :error , :class_in_def , { } , diagnostic_location , [ ] )
146
+ when :def_endless_setter
147
+ Diagnostic . new ( :error , :endless_setter , { } , diagnostic_location , [ ] )
148
+ when :embdoc_term
149
+ Diagnostic . new ( :error , :embedded_document , { } , diagnostic_location , [ ] )
150
+ when :incomplete_variable_class , :incomplete_variable_class_3_3_0
151
+ location = location . copy ( length : location . length + 1 )
152
+ diagnostic_location = build_range ( location , offset_cache )
153
+
154
+ Diagnostic . new ( :error , :cvar_name , { name : location . slice } , diagnostic_location , [ ] )
155
+ when :incomplete_variable_instance , :incomplete_variable_instance_3_3_0
156
+ location = location . copy ( length : location . length + 1 )
157
+ diagnostic_location = build_range ( location , offset_cache )
158
+
159
+ Diagnostic . new ( :error , :ivar_name , { name : location . slice } , diagnostic_location , [ ] )
160
+ when :invalid_variable_global , :invalid_variable_global_3_3_0
161
+ Diagnostic . new ( :error , :gvar_name , { name : location . slice } , diagnostic_location , [ ] )
162
+ when :module_in_method
163
+ Diagnostic . new ( :error , :module_in_def , { } , diagnostic_location , [ ] )
164
+ when :numbered_parameter_ordinary
165
+ Diagnostic . new ( :error , :ordinary_param_defined , { } , diagnostic_location , [ ] )
166
+ when :numbered_parameter_outer_scope
167
+ Diagnostic . new ( :error , :numparam_used_in_outer_scope , { } , diagnostic_location , [ ] )
168
+ when :parameter_circular
169
+ Diagnostic . new ( :error , :circular_argument_reference , { var_name : location . slice } , diagnostic_location , [ ] )
170
+ when :parameter_name_repeat
171
+ Diagnostic . new ( :error , :duplicate_argument , { } , diagnostic_location , [ ] )
172
+ when :parameter_numbered_reserved
173
+ Diagnostic . new ( :error , :reserved_for_numparam , { name : location . slice } , diagnostic_location , [ ] )
174
+ when :singleton_for_literals
175
+ Diagnostic . new ( :error , :singleton_literal , { } , diagnostic_location , [ ] )
176
+ when :string_literal_eof
177
+ Diagnostic . new ( :error , :string_eof , { } , diagnostic_location , [ ] )
178
+ when :unexpected_token_ignore
179
+ Diagnostic . new ( :error , :unexpected_token , { token : location . slice } , diagnostic_location , [ ] )
180
+ when :write_target_in_method
181
+ Diagnostic . new ( :error , :dynamic_const , { } , diagnostic_location , [ ] )
182
+ else
183
+ PrismDiagnostic . new ( error . message , :error , error . type , diagnostic_location )
184
+ end
185
+ end
186
+
187
+ # Build a diagnostic from the given prism parse warning.
188
+ def warning_diagnostic ( warning , offset_cache )
189
+ diagnostic_location = build_range ( warning . location , offset_cache )
190
+
191
+ case warning . type
192
+ when :ambiguous_first_argument_plus
193
+ Diagnostic . new ( :warning , :ambiguous_prefix , { prefix : "+" } , diagnostic_location , [ ] )
194
+ when :ambiguous_first_argument_minus
195
+ Diagnostic . new ( :warning , :ambiguous_prefix , { prefix : "-" } , diagnostic_location , [ ] )
196
+ when :ambiguous_prefix_star
197
+ Diagnostic . new ( :warning , :ambiguous_prefix , { prefix : "*" } , diagnostic_location , [ ] )
198
+ when :ambiguous_slash
199
+ Diagnostic . new ( :warning , :ambiguous_regexp , { } , diagnostic_location , [ ] )
200
+ when :dot_dot_dot_eol
201
+ Diagnostic . new ( :warning , :triple_dot_at_eol , { } , diagnostic_location , [ ] )
202
+ when :duplicated_hash_key
203
+ # skip, parser does this on its own
204
+ else
205
+ PrismDiagnostic . new ( warning . message , :warning , warning . type , diagnostic_location )
206
+ end
207
+ end
208
+
115
209
# If there was a error generated during the parse, then raise an
116
210
# appropriate syntax error. Otherwise return the result.
117
211
def unwrap ( result , offset_cache )
118
212
result . errors . each do |error |
119
213
next unless valid_error? ( error )
120
-
121
- location = build_range ( error . location , offset_cache )
122
- diagnostics . process ( Diagnostic . new ( error . message , :error , :prism_error , location ) )
214
+ diagnostics . process ( error_diagnostic ( error , offset_cache ) )
123
215
end
216
+
124
217
result . warnings . each do |warning |
125
218
next unless valid_warning? ( warning )
126
-
127
- location = build_range ( warning . location , offset_cache )
128
- diagnostics . process ( Diagnostic . new ( warning . message , :warning , :prism_warning , location ) )
219
+ diagnostic = warning_diagnostic ( warning , offset_cache )
220
+ diagnostics . process ( diagnostic ) if diagnostic
129
221
end
130
222
131
223
result
0 commit comments