gloss 0.0.1 → 0.0.6
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/.gitattributes +3 -0
- data/.github/workflows/crystal_specs.yml +26 -0
- data/.github/workflows/ruby_specs.yml +33 -0
- data/.gitignore +2 -1
- data/.rspec +1 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +26 -34
- data/LICENSE +21 -0
- data/README.md +59 -7
- data/Rakefile +4 -0
- data/exe/gloss +15 -1
- data/ext/gloss/Makefile +27 -5
- data/ext/gloss/extconf.rb +3 -25
- data/ext/gloss/{src/lib → lib}/cr_ruby.cr +0 -0
- data/ext/gloss/lib/rbs_types.cr +3 -0
- data/ext/gloss/spec/parser_spec.cr +124 -0
- data/ext/gloss/spec/spec_helper.cr +2 -0
- data/ext/gloss/src/cr_ast.cr +129 -31
- data/ext/gloss/src/gloss.cr +12 -18
- data/ext/gloss/src/lexer.cr +59 -1
- data/ext/gloss/src/parser.cr +548 -254
- data/ext/gloss/src/rb_ast.cr +153 -27
- data/gloss.gemspec +1 -0
- data/lib/gloss.rb +4 -1
- data/lib/gloss/builder.rb +607 -409
- data/lib/gloss/cli.rb +64 -24
- data/lib/gloss/config.rb +16 -10
- data/lib/gloss/errors.rb +13 -7
- data/lib/gloss/initializer.rb +11 -6
- data/lib/gloss/logger.rb +34 -0
- data/lib/gloss/parser.rb +35 -0
- data/lib/gloss/scope.rb +8 -3
- data/lib/gloss/source.rb +18 -15
- data/lib/gloss/type_checker.rb +96 -0
- data/lib/gloss/version.rb +6 -1
- data/lib/gloss/watcher.rb +63 -19
- data/lib/gloss/writer.rb +18 -12
- data/sig/gloss.rbs +3 -0
- data/sig/listen.rbs +1 -0
- data/src/lib/gloss/builder.gl +546 -0
- data/src/lib/gloss/cli.gl +55 -0
- data/src/lib/gloss/config.gl +21 -0
- data/src/lib/gloss/errors.gl +11 -0
- data/src/lib/gloss/initializer.gl +20 -0
- data/src/lib/gloss/logger.gl +26 -0
- data/src/lib/gloss/parser.gl +31 -0
- data/src/lib/gloss/scope.gl +9 -0
- data/src/lib/gloss/source.gl +32 -0
- data/src/lib/gloss/type_checker.gl +101 -0
- data/src/lib/gloss/version.gl +3 -0
- data/src/lib/gloss/watcher.gl +67 -0
- data/src/lib/gloss/writer.gl +33 -0
- metadata +42 -6
- data/lib/gloss.bundle.dwarf +0 -0
- data/src/lib/hrb/initializer.gl +0 -22
- data/src/lib/hrb/watcher.gl +0 -32
data/ext/gloss/src/lexer.cr
CHANGED
@@ -115,7 +115,7 @@ module Crystal
|
|
115
115
|
case next_char
|
116
116
|
when '='
|
117
117
|
next_char :"<<="
|
118
|
-
when '-'
|
118
|
+
when '-', '~'
|
119
119
|
has_single_quote = false
|
120
120
|
found_closing_single_quote = false
|
121
121
|
|
@@ -1182,5 +1182,63 @@ module Crystal
|
|
1182
1182
|
|
1183
1183
|
@token
|
1184
1184
|
end
|
1185
|
+
|
1186
|
+
def check_heredoc_start
|
1187
|
+
return nil unless current_char == '<' && next_char == '<' && {'-', '~'}.includes?(next_char)
|
1188
|
+
|
1189
|
+
has_single_quote = false
|
1190
|
+
found_closing_single_quote = false
|
1191
|
+
|
1192
|
+
char = next_char
|
1193
|
+
start_here = current_pos
|
1194
|
+
|
1195
|
+
if char == '\''
|
1196
|
+
has_single_quote = true
|
1197
|
+
char = next_char
|
1198
|
+
start_here = current_pos
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
return nil unless ident_part?(char)
|
1202
|
+
|
1203
|
+
end_here = 0
|
1204
|
+
|
1205
|
+
while true
|
1206
|
+
char = next_char
|
1207
|
+
case
|
1208
|
+
when char == '\r'
|
1209
|
+
if peek_next_char == '\n'
|
1210
|
+
end_here = current_pos
|
1211
|
+
next_char
|
1212
|
+
break
|
1213
|
+
else
|
1214
|
+
return nil
|
1215
|
+
end
|
1216
|
+
when char == '\n'
|
1217
|
+
end_here = current_pos
|
1218
|
+
break
|
1219
|
+
when ident_part?(char)
|
1220
|
+
# ok
|
1221
|
+
when char == '\0'
|
1222
|
+
return nil
|
1223
|
+
else
|
1224
|
+
if char == '\'' && has_single_quote
|
1225
|
+
found_closing_single_quote = true
|
1226
|
+
end_here = current_pos
|
1227
|
+
next_char
|
1228
|
+
break
|
1229
|
+
elsif has_single_quote
|
1230
|
+
# wait until another quote
|
1231
|
+
else
|
1232
|
+
end_here = current_pos
|
1233
|
+
break
|
1234
|
+
end
|
1235
|
+
end
|
1236
|
+
end
|
1237
|
+
|
1238
|
+
return nil if has_single_quote && !found_closing_single_quote
|
1239
|
+
|
1240
|
+
here = string_range(start_here, end_here)
|
1241
|
+
Token::DelimiterState.new(:heredoc, here, here, allow_escapes: !has_single_quote)
|
1242
|
+
end
|
1185
1243
|
end
|
1186
1244
|
end
|
data/ext/gloss/src/parser.cr
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
require "compiler/crystal/syntax/*"
|
2
2
|
require "./lexer"
|
3
|
+
require "./cr_ast"
|
3
4
|
|
4
5
|
module Gloss
|
6
|
+
def self.parse_string(string : String)
|
7
|
+
tree = Gloss::Parser.parse string
|
8
|
+
tree.to_rb.to_json
|
9
|
+
end
|
10
|
+
|
5
11
|
class Parser < Crystal::Parser
|
6
12
|
parse_operator :or_keyword, :and_keyword, "Or.new left, right", ":or"
|
7
13
|
parse_operator :and_keyword, :prefix, "And.new left, right", ":and"
|
@@ -11,10 +17,10 @@ module Gloss
|
|
11
17
|
line = @line_number
|
12
18
|
column = @token.column_number
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
Crystal::ArrayLiteral.new([] of Crystal::ASTNode)
|
20
|
+
next_token_skip_space
|
21
|
+
next_token_skip_space_or_newline
|
22
|
+
of = nil
|
23
|
+
Crystal::ArrayLiteral.new([] of Crystal::ASTNode).at_end(of)
|
18
24
|
end
|
19
25
|
|
20
26
|
def new_hash_literal(entries, line, column, end_location, allow_of = true)
|
@@ -86,255 +92,543 @@ module Gloss
|
|
86
92
|
types
|
87
93
|
end
|
88
94
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
95
|
+
|
96
|
+
def parse_arg(args, extra_assigns, parentheses, found_default_value, found_splat, found_double_splat, allow_restrictions)
|
97
|
+
if @token.type == :"&"
|
98
|
+
next_token_skip_space_or_newline
|
99
|
+
block_arg = parse_block_arg(extra_assigns)
|
100
|
+
skip_space_or_newline
|
101
|
+
# When block_arg.name is empty, this is an anonymous argument.
|
102
|
+
# An anonymous argument should not conflict other arguments names.
|
103
|
+
# (In fact `args` may contain anonymous splat argument. See #9108).
|
104
|
+
# So check is skipped.
|
105
|
+
unless block_arg.name.empty?
|
106
|
+
conflict_arg = args.any?(&.name.==(block_arg.name))
|
107
|
+
conflict_double_splat = found_double_splat && found_double_splat.name == block_arg.name
|
108
|
+
if conflict_arg || conflict_double_splat
|
109
|
+
raise "duplicated argument name: #{block_arg.name}", block_arg.location.not_nil!
|
110
|
+
end
|
111
|
+
end
|
112
|
+
return Crystal::Parser::ArgExtras.new(block_arg, false, false, false)
|
113
|
+
end
|
114
|
+
|
115
|
+
if found_double_splat
|
116
|
+
raise "only block argument is allowed after double splat"
|
117
|
+
end
|
118
|
+
|
119
|
+
splat = false
|
120
|
+
double_splat = false
|
121
|
+
arg_location = @token.location
|
122
|
+
allow_external_name = true
|
123
|
+
|
124
|
+
case @token.type
|
125
|
+
when :"*"
|
126
|
+
if found_splat
|
127
|
+
unexpected_token
|
128
|
+
end
|
129
|
+
|
130
|
+
splat = true
|
131
|
+
allow_external_name = false
|
132
|
+
next_token_skip_space
|
133
|
+
when :"**"
|
134
|
+
double_splat = true
|
135
|
+
allow_external_name = false
|
136
|
+
next_token_skip_space
|
137
|
+
else
|
138
|
+
# not a splat
|
139
|
+
end
|
140
|
+
|
141
|
+
found_space = false
|
142
|
+
|
143
|
+
if splat && (@token.type == :"," || @token.type == :")")
|
144
|
+
arg_name = ""
|
145
|
+
uses_arg = false
|
146
|
+
allow_restrictions = false
|
147
|
+
else
|
148
|
+
arg_location = @token.location
|
149
|
+
arg_name, external_name, found_space, uses_arg = parse_arg_name(arg_location, extra_assigns, allow_external_name: allow_external_name)
|
150
|
+
|
151
|
+
args.each do |arg|
|
152
|
+
if arg.name == arg_name
|
153
|
+
raise "duplicated argument name: #{arg_name}", arg_location
|
154
|
+
end
|
155
|
+
|
156
|
+
if arg.external_name == external_name
|
157
|
+
raise "duplicated argument external name: #{external_name}", arg_location
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
if @token.type == :SYMBOL
|
162
|
+
raise "space required after colon in type restriction", @token
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
default_value = nil
|
167
|
+
restriction = nil
|
168
|
+
keyword_arg = false
|
169
|
+
found_colon = false
|
170
|
+
|
171
|
+
# KEYWORD ARGUMENTS
|
172
|
+
# eg. def abc(a: : String? = "")
|
173
|
+
if @token.type == :":" && !found_space
|
174
|
+
keyword_arg = true
|
175
|
+
next_token_skip_space
|
176
|
+
found_space = true
|
177
|
+
end
|
178
|
+
|
179
|
+
if allow_restrictions && @token.type == :":"
|
180
|
+
if !default_value && !found_space
|
181
|
+
raise "space required before colon in type restriction", @token
|
182
|
+
end
|
183
|
+
|
184
|
+
next_token_skip_space_or_newline
|
185
|
+
|
186
|
+
location = @token.location
|
187
|
+
splat_restriction = false
|
188
|
+
if (splat && @token.type == :"*") || (double_splat && @token.type == :"**")
|
189
|
+
splat_restriction = true
|
190
|
+
next_token
|
191
|
+
end
|
192
|
+
|
193
|
+
restriction = parse_bare_proc_type
|
194
|
+
|
195
|
+
if splat_restriction
|
196
|
+
restriction = splat ? Crystal::Splat.new(restriction) : Crystal::DoubleSplat.new(restriction)
|
197
|
+
restriction.at(location)
|
198
|
+
end
|
199
|
+
found_colon = true
|
200
|
+
end
|
201
|
+
|
202
|
+
if @token.type == :"="
|
203
|
+
raise "splat argument can't have default value", @token if splat
|
204
|
+
raise "double splat argument can't have default value", @token if double_splat
|
205
|
+
|
206
|
+
slash_is_regex!
|
207
|
+
next_token_skip_space_or_newline
|
208
|
+
|
209
|
+
case @token.type
|
210
|
+
when :__LINE__, :__END_LINE__, :__FILE__, :__DIR__
|
211
|
+
default_value = Crystal::MagicConstant.new(@token.type).at(@token.location)
|
212
|
+
next_token
|
213
|
+
else
|
214
|
+
@no_type_declaration += 1
|
215
|
+
default_value = parse_op_assign
|
216
|
+
@no_type_declaration -= 1
|
217
|
+
end
|
218
|
+
|
219
|
+
skip_space
|
220
|
+
else
|
221
|
+
if found_default_value && !found_splat && !splat && !double_splat
|
222
|
+
raise "argument must have a default value", arg_location
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
unless found_colon
|
227
|
+
if @token.type == :SYMBOL
|
228
|
+
raise "the syntax for an argument with a default value V and type T is `arg : T = V`", @token
|
229
|
+
end
|
230
|
+
|
231
|
+
if allow_restrictions && @token.type == :":"
|
232
|
+
raise "the syntax for an argument with a default value V and type T is `arg : T = V`", @token
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
raise "BUG: arg_name is nil" unless arg_name
|
237
|
+
|
238
|
+
arg = Crystal::Arg.new(arg_name, default_value, restriction, external_name: external_name).at(arg_location)
|
239
|
+
arg.keyword_arg = keyword_arg
|
240
|
+
args << arg
|
241
|
+
push_var arg
|
242
|
+
|
243
|
+
Crystal::Parser::ArgExtras.new(nil, !!default_value, splat, !!double_splat)
|
244
|
+
end
|
245
|
+
|
246
|
+
def parse_arg_name(location, extra_assigns, allow_external_name)
|
247
|
+
do_next_token = true
|
248
|
+
found_string_literal = false
|
249
|
+
invalid_internal_name = nil
|
250
|
+
|
251
|
+
if allow_external_name && (@token.type == :IDENT || string_literal_start?)
|
252
|
+
if @token.type == :IDENT
|
253
|
+
if @token.keyword? && invalid_internal_name?(@token.value)
|
254
|
+
invalid_internal_name = @token.dup
|
255
|
+
end
|
256
|
+
external_name = @token.type == :IDENT ? @token.value.to_s : ""
|
257
|
+
next_token
|
258
|
+
else
|
259
|
+
external_name = parse_string_without_interpolation("external name")
|
260
|
+
found_string_literal = true
|
261
|
+
end
|
262
|
+
found_space = @token.type == :SPACE || @token.type == :NEWLINE
|
263
|
+
skip_space
|
264
|
+
do_next_token = false
|
265
|
+
end
|
266
|
+
|
267
|
+
case @token.type
|
268
|
+
when :IDENT
|
269
|
+
if @token.keyword? && invalid_internal_name?(@token.value)
|
270
|
+
raise "cannot use '#{@token}' as an argument name", @token
|
271
|
+
end
|
272
|
+
|
273
|
+
arg_name = @token.value.to_s
|
274
|
+
if arg_name == external_name
|
275
|
+
raise "when specified, external name must be different than internal name", @token
|
276
|
+
end
|
277
|
+
|
278
|
+
uses_arg = false
|
279
|
+
do_next_token = true
|
280
|
+
when :INSTANCE_VAR
|
281
|
+
arg_name = @token.value.to_s[1..-1]
|
282
|
+
if arg_name == external_name
|
283
|
+
raise "when specified, external name must be different than internal name", @token
|
284
|
+
end
|
285
|
+
|
286
|
+
# If it's something like @select, we can't transform it to:
|
287
|
+
#
|
288
|
+
# @select = select
|
289
|
+
#
|
290
|
+
# because if someone uses `to_s` later it will produce invalid code.
|
291
|
+
# So we do something like:
|
292
|
+
#
|
293
|
+
# def method(select __arg0)
|
294
|
+
# @select = __arg0
|
295
|
+
# end
|
296
|
+
if !external_name && invalid_internal_name?(arg_name)
|
297
|
+
arg_name, external_name = temp_arg_name, arg_name
|
298
|
+
end
|
299
|
+
|
300
|
+
ivar = Crystal::InstanceVar.new(@token.value.to_s).at(location)
|
301
|
+
var = Crystal::Var.new(arg_name).at(location)
|
302
|
+
assign = Crystal::Assign.new(ivar, var).at(location)
|
303
|
+
if extra_assigns
|
304
|
+
extra_assigns.push assign
|
305
|
+
else
|
306
|
+
raise "can't use @instance_variable here"
|
307
|
+
end
|
308
|
+
uses_arg = true
|
309
|
+
do_next_token = true
|
310
|
+
when :CLASS_VAR
|
311
|
+
arg_name = @token.value.to_s[2..-1]
|
312
|
+
if arg_name == external_name
|
313
|
+
raise "when specified, external name must be different than internal name", @token
|
314
|
+
end
|
315
|
+
|
316
|
+
# Same case as :INSTANCE_VAR for things like @select
|
317
|
+
if !external_name && invalid_internal_name?(arg_name)
|
318
|
+
arg_name, external_name = temp_arg_name, arg_name
|
319
|
+
end
|
320
|
+
|
321
|
+
cvar = Crystal::ClassVar.new(@token.value.to_s).at(location)
|
322
|
+
var = Crystal::Var.new(arg_name).at(location)
|
323
|
+
assign = Crystal::Assign.new(cvar, var).at(location)
|
324
|
+
if extra_assigns
|
325
|
+
extra_assigns.push assign
|
326
|
+
else
|
327
|
+
raise "can't use @@class_var here"
|
328
|
+
end
|
329
|
+
uses_arg = true
|
330
|
+
do_next_token = true
|
331
|
+
else
|
332
|
+
if external_name
|
333
|
+
if found_string_literal
|
334
|
+
raise "unexpected token: #{@token}, expected argument internal name"
|
335
|
+
end
|
336
|
+
if invalid_internal_name
|
337
|
+
raise "cannot use '#{invalid_internal_name}' as an argument name", invalid_internal_name
|
338
|
+
end
|
339
|
+
arg_name = external_name
|
340
|
+
else
|
341
|
+
raise "unexpected token: #{@token}"
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
if do_next_token
|
346
|
+
next_token
|
347
|
+
found_space = @token.type == :SPACE || @token.type == :NEWLINE
|
348
|
+
end
|
349
|
+
|
350
|
+
skip_space
|
351
|
+
|
352
|
+
{arg_name, external_name, found_space, uses_arg}
|
353
|
+
end
|
354
|
+
|
355
|
+
### USE [] INSTEAD OF CRYSTAL'S ()
|
356
|
+
def parse_type_args(name)
|
357
|
+
return name unless @token.type == :"["
|
358
|
+
|
359
|
+
next_token_skip_space_or_newline
|
360
|
+
args = [] of Crystal::ASTNode
|
361
|
+
if named_tuple_start? || string_literal_start?
|
362
|
+
named_args = parse_named_type_args(:"]")
|
363
|
+
else
|
364
|
+
args << parse_type_splat { parse_type_arg }
|
365
|
+
while @token.type == :","
|
366
|
+
next_token_skip_space_or_newline
|
367
|
+
break if @token.type == :"]" # allow trailing comma
|
368
|
+
args << parse_type_splat { parse_type_arg }
|
369
|
+
end
|
370
|
+
|
371
|
+
has_int = args.any? do |arg|
|
372
|
+
arg.is_a?(Crystal::NumberLiteral) ||
|
373
|
+
arg.is_a?(Crystal::SizeOf) ||
|
374
|
+
arg.is_a?(Crystal::InstanceSizeOf) ||
|
375
|
+
arg.is_a?(Crystal::OffsetOf)
|
376
|
+
end
|
377
|
+
if @token.type == :"->" && !has_int
|
378
|
+
args = [parse_proc_type_output(args, args.first.location)] of Crystal::ASTNode
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
skip_space_or_newline
|
383
|
+
check :"]"
|
384
|
+
end_location = token_end_location
|
385
|
+
next_token
|
386
|
+
|
387
|
+
Crystal::Generic.new(name, args, named_args).at(name).at_end(end_location)
|
388
|
+
end
|
389
|
+
|
390
|
+
def parse_atomic_without_location
|
391
|
+
case @token.type
|
392
|
+
when :"("
|
393
|
+
parse_parenthesized_expression
|
394
|
+
when :"[]"
|
395
|
+
parse_empty_array_literal
|
396
|
+
when :"["
|
397
|
+
parse_array_literal
|
398
|
+
when :"{"
|
399
|
+
parse_hash_or_tuple_literal
|
400
|
+
when :"{{"
|
401
|
+
parse_percent_macro_expression
|
402
|
+
when :"{%"
|
403
|
+
parse_percent_macro_control
|
404
|
+
when :"::"
|
405
|
+
parse_generic_or_global_call
|
406
|
+
when :"->"
|
407
|
+
parse_fun_literal
|
408
|
+
when :"@["
|
409
|
+
parse_annotation
|
410
|
+
when :NUMBER
|
411
|
+
@wants_regex = false
|
412
|
+
node_and_next_token Crystal::NumberLiteral.new(@token.value.to_s, @token.number_kind)
|
413
|
+
when :CHAR
|
414
|
+
node_and_next_token Crystal::CharLiteral.new(@token.value.as(Char))
|
415
|
+
when :STRING, :DELIMITER_START
|
416
|
+
parse_delimiter
|
417
|
+
when :STRING_ARRAY_START
|
418
|
+
parse_string_array
|
419
|
+
when :SYMBOL_ARRAY_START
|
420
|
+
parse_symbol_array
|
421
|
+
when :SYMBOL
|
422
|
+
node_and_next_token Crystal::SymbolLiteral.new(@token.value.to_s)
|
423
|
+
when :GLOBAL
|
424
|
+
new_node_check_type_declaration Crystal::Global
|
425
|
+
when :"$~", :"$?"
|
426
|
+
location = @token.location
|
427
|
+
var = Crystal::Var.new(@token.to_s).at(location)
|
428
|
+
|
429
|
+
old_pos, old_line, old_column = current_pos, @line_number, @column_number
|
430
|
+
@temp_token.copy_from(@token)
|
431
|
+
|
432
|
+
next_token_skip_space
|
433
|
+
|
434
|
+
if @token.type == :"="
|
435
|
+
@token.copy_from(@temp_token)
|
436
|
+
self.current_pos, @line_number, @column_number = old_pos, old_line, old_column
|
437
|
+
|
438
|
+
push_var var
|
439
|
+
node_and_next_token var
|
440
|
+
else
|
441
|
+
@token.copy_from(@temp_token)
|
442
|
+
self.current_pos, @line_number, @column_number = old_pos, old_line, old_column
|
443
|
+
|
444
|
+
node_and_next_token Crystal::Global.new(var.name).at(location)
|
445
|
+
end
|
446
|
+
when :GLOBAL_MATCH_DATA_INDEX
|
447
|
+
value = @token.value.to_s
|
448
|
+
if value_prefix = value.rchop? '?'
|
449
|
+
method = "[]?"
|
450
|
+
value = value_prefix
|
451
|
+
else
|
452
|
+
method = "[]"
|
453
|
+
end
|
454
|
+
location = @token.location
|
455
|
+
node_and_next_token Crystal::Call.new(Crystal::Global.new("$~").at(location), method, Crystal::NumberLiteral.new(value.to_i))
|
456
|
+
when :__LINE__
|
457
|
+
node_and_next_token Crystal::MagicConstant.expand_line_node(@token.location)
|
458
|
+
when :__END_LINE__
|
459
|
+
raise "__END_LINE__ can only be used in default argument value", @token
|
460
|
+
when :__FILE__
|
461
|
+
node_and_next_token Crystal::MagicConstant.expand_file_node(@token.location)
|
462
|
+
when :__DIR__
|
463
|
+
node_and_next_token Crystal::MagicConstant.expand_dir_node(@token.location)
|
464
|
+
when :IDENT
|
465
|
+
# NOTE: Update `Parser#invalid_internal_name?` keyword list
|
466
|
+
# when adding or removing keyword to handle here.
|
467
|
+
case @token.value
|
468
|
+
when :begin
|
469
|
+
check_type_declaration { parse_begin }
|
470
|
+
when :nil
|
471
|
+
check_type_declaration { node_and_next_token Crystal::NilLiteral.new }
|
472
|
+
when :true
|
473
|
+
check_type_declaration { node_and_next_token Crystal::BoolLiteral.new(true) }
|
474
|
+
when :false
|
475
|
+
check_type_declaration { node_and_next_token Crystal::BoolLiteral.new(false) }
|
476
|
+
when :yield
|
477
|
+
check_type_declaration { parse_yield }
|
478
|
+
when :with
|
479
|
+
check_type_declaration { parse_yield_with_scope }
|
480
|
+
when :abstract
|
481
|
+
check_type_declaration do
|
482
|
+
check_not_inside_def("can't use abstract") do
|
483
|
+
doc = @token.doc
|
484
|
+
|
485
|
+
next_token_skip_space_or_newline
|
486
|
+
case @token.type
|
487
|
+
when :IDENT
|
488
|
+
case @token.value
|
489
|
+
when :def
|
490
|
+
parse_def is_abstract: true, doc: doc
|
491
|
+
when :class
|
492
|
+
parse_class_def is_abstract: true, doc: doc
|
493
|
+
when :struct
|
494
|
+
parse_class_def is_abstract: true, is_struct: true, doc: doc
|
495
|
+
else
|
496
|
+
unexpected_token
|
497
|
+
end
|
498
|
+
else
|
499
|
+
unexpected_token
|
500
|
+
end
|
501
|
+
end
|
502
|
+
end
|
503
|
+
when :def
|
504
|
+
check_type_declaration do
|
505
|
+
check_not_inside_def("can't define def") do
|
506
|
+
parse_def
|
507
|
+
end
|
508
|
+
end
|
509
|
+
when :macro
|
510
|
+
check_type_declaration do
|
511
|
+
check_not_inside_def("can't define macro") do
|
512
|
+
parse_macro
|
513
|
+
end
|
514
|
+
end
|
515
|
+
when :require
|
516
|
+
check_type_declaration do
|
517
|
+
check_not_inside_def("can't require") do
|
518
|
+
parse_require
|
519
|
+
end
|
520
|
+
end
|
521
|
+
when :case
|
522
|
+
check_type_declaration { parse_case }
|
523
|
+
when :select
|
524
|
+
check_type_declaration { parse_select }
|
525
|
+
when :if
|
526
|
+
check_type_declaration { parse_if }
|
527
|
+
when :unless
|
528
|
+
check_type_declaration { parse_unless }
|
529
|
+
when :include
|
530
|
+
check_type_declaration do
|
531
|
+
check_not_inside_def("can't include") do
|
532
|
+
parse_include
|
533
|
+
end
|
534
|
+
end
|
535
|
+
when :extend
|
536
|
+
check_type_declaration do
|
537
|
+
check_not_inside_def("can't extend") do
|
538
|
+
parse_extend
|
539
|
+
end
|
540
|
+
end
|
541
|
+
when :class
|
542
|
+
check_type_declaration do
|
543
|
+
check_not_inside_def("can't define class") do
|
544
|
+
parse_class_def
|
545
|
+
end
|
546
|
+
end
|
547
|
+
when :struct
|
548
|
+
check_type_declaration do
|
549
|
+
check_not_inside_def("can't define struct") do
|
550
|
+
parse_class_def is_struct: true
|
551
|
+
end
|
552
|
+
end
|
553
|
+
when :module
|
554
|
+
check_type_declaration do
|
555
|
+
check_not_inside_def("can't define module") do
|
556
|
+
parse_module_def
|
557
|
+
end
|
558
|
+
end
|
559
|
+
when :enum
|
560
|
+
check_type_declaration do
|
561
|
+
check_not_inside_def("can't define enum") do
|
562
|
+
parse_enum_def
|
563
|
+
end
|
564
|
+
end
|
565
|
+
when :while
|
566
|
+
check_type_declaration { parse_while }
|
567
|
+
when :until
|
568
|
+
check_type_declaration { parse_until }
|
569
|
+
when :return
|
570
|
+
check_type_declaration { parse_return }
|
571
|
+
when :next
|
572
|
+
check_type_declaration { parse_next }
|
573
|
+
when :break
|
574
|
+
check_type_declaration { parse_break }
|
575
|
+
when :lib
|
576
|
+
check_type_declaration do
|
577
|
+
check_not_inside_def("can't define lib") do
|
578
|
+
parse_lib
|
579
|
+
end
|
580
|
+
end
|
581
|
+
when :fun
|
582
|
+
check_type_declaration do
|
583
|
+
check_not_inside_def("can't define fun") do
|
584
|
+
parse_fun_def top_level: true, require_body: true
|
585
|
+
end
|
586
|
+
end
|
587
|
+
when :alias
|
588
|
+
check_type_declaration do
|
589
|
+
check_not_inside_def("can't define alias") do
|
590
|
+
parse_alias
|
591
|
+
end
|
592
|
+
end
|
593
|
+
when :pointerof
|
594
|
+
check_type_declaration { parse_pointerof }
|
595
|
+
when :sizeof
|
596
|
+
check_type_declaration { parse_sizeof }
|
597
|
+
when :instance_sizeof
|
598
|
+
check_type_declaration { parse_instance_sizeof }
|
599
|
+
when :offsetof
|
600
|
+
check_type_declaration { parse_offsetof }
|
601
|
+
when :typeof
|
602
|
+
check_type_declaration { parse_typeof }
|
603
|
+
when :private
|
604
|
+
check_type_declaration { parse_visibility_modifier Crystal::Visibility::Private }
|
605
|
+
when :protected
|
606
|
+
check_type_declaration { parse_visibility_modifier Crystal::Visibility::Protected }
|
607
|
+
when :asm
|
608
|
+
check_type_declaration { parse_asm }
|
609
|
+
when :annotation
|
610
|
+
check_type_declaration do
|
611
|
+
check_not_inside_def("can't define annotation") do
|
612
|
+
parse_annotation_def
|
613
|
+
end
|
614
|
+
end
|
615
|
+
else
|
616
|
+
set_visibility parse_var_or_call
|
617
|
+
end
|
618
|
+
when :CONST
|
619
|
+
parse_generic_or_custom_literal
|
620
|
+
when :INSTANCE_VAR
|
621
|
+
if @in_macro_expression && @token.value == "@type"
|
622
|
+
@is_macro_def = true
|
623
|
+
end
|
624
|
+
new_node_check_type_declaration Crystal::InstanceVar
|
625
|
+
when :CLASS_VAR
|
626
|
+
new_node_check_type_declaration Crystal::ClassVar
|
627
|
+
when :UNDERSCORE
|
628
|
+
node_and_next_token Crystal::Underscore.new
|
629
|
+
else
|
630
|
+
unexpected_token_in_atomic
|
631
|
+
end
|
632
|
+
end
|
339
633
|
end
|
340
634
|
end
|