gloss 0.0.3 → 0.1.1

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +3 -0
  3. data/.github/workflows/{crystal.yml → crystal_specs.yml} +1 -1
  4. data/.github/workflows/{ruby.yml → ruby_specs.yml} +2 -2
  5. data/.gloss.yml +1 -0
  6. data/.rspec +1 -0
  7. data/Gemfile.lock +10 -12
  8. data/README.md +36 -5
  9. data/Rakefile +1 -1
  10. data/exe/gloss +13 -2
  11. data/ext/gloss/Makefile +8 -19
  12. data/ext/gloss/{src/lib → lib}/cr_ruby.cr +0 -0
  13. data/ext/gloss/lib/rbs_types.cr +3 -0
  14. data/ext/gloss/spec/parser_spec.cr +83 -83
  15. data/ext/gloss/src/cr_ast.cr +96 -77
  16. data/ext/gloss/src/gloss.cr +2 -2
  17. data/ext/gloss/src/lexer.cr +59 -1
  18. data/ext/gloss/src/rb_ast.cr +114 -63
  19. data/lib/gloss.rb +15 -7
  20. data/lib/gloss/cli.rb +85 -28
  21. data/lib/gloss/config.rb +13 -7
  22. data/lib/gloss/errors.rb +3 -4
  23. data/lib/gloss/initializer.rb +9 -9
  24. data/lib/gloss/logger.rb +29 -0
  25. data/lib/gloss/parser.rb +19 -5
  26. data/lib/gloss/prog_loader.rb +141 -0
  27. data/lib/gloss/scope.rb +7 -2
  28. data/lib/gloss/source.rb +17 -14
  29. data/lib/gloss/type_checker.rb +86 -33
  30. data/lib/gloss/utils.rb +44 -0
  31. data/lib/gloss/version.rb +1 -2
  32. data/lib/gloss/visitor.rb +667 -0
  33. data/lib/gloss/watcher.rb +51 -16
  34. data/lib/gloss/writer.rb +24 -15
  35. data/sig/core.rbs +2 -0
  36. data/sig/fast_blank.rbs +4 -0
  37. data/sig/{gloss.rbs → gls.rbs} +0 -0
  38. data/sig/listen.rbs +1 -0
  39. data/sig/optparse.rbs +6 -0
  40. data/sig/rubygems.rbs +9 -0
  41. data/sig/yaml.rbs +3 -0
  42. data/src/exe/gloss +19 -0
  43. data/src/lib/gloss.gl +26 -0
  44. data/src/lib/gloss/cli.gl +70 -0
  45. data/src/lib/gloss/config.gl +9 -3
  46. data/src/lib/gloss/initializer.gl +4 -6
  47. data/src/lib/gloss/logger.gl +21 -0
  48. data/src/lib/gloss/parser.gl +17 -5
  49. data/src/lib/gloss/prog_loader.gl +133 -0
  50. data/src/lib/gloss/scope.gl +7 -0
  51. data/src/lib/gloss/source.gl +32 -0
  52. data/src/lib/gloss/type_checker.gl +85 -36
  53. data/src/lib/gloss/utils.gl +38 -0
  54. data/src/lib/gloss/version.gl +1 -1
  55. data/src/lib/gloss/visitor.gl +575 -0
  56. data/src/lib/gloss/watcher.gl +44 -10
  57. data/src/lib/gloss/writer.gl +16 -14
  58. metadata +28 -8
  59. data/lib/gloss/builder.rb +0 -447
@@ -1,4 +1,5 @@
1
- require "./lib/cr_ruby"
1
+ require "../lib/cr_ruby"
2
+ require "../lib/rbs_types"
2
3
  require "./cr_ast"
3
4
  require "./rb_ast"
4
5
  require "./parser"
@@ -10,7 +11,6 @@ def parse_string(self : CrRuby::VALUE, str : CrRuby::VALUE)
10
11
  output = begin
11
12
  Gloss.parse_string(string)
12
13
  rescue e : Crystal::SyntaxException
13
- pp e.backtrace
14
14
  e.to_s
15
15
  end
16
16
 
@@ -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
@@ -19,7 +19,7 @@ module Rb
19
19
  abstract class NodeWithChildren < Node
20
20
  @info : NamedTuple(type: String, children: Array(Node))
21
21
 
22
- def initialize(@children : Array(Node))
22
+ def initialize(@children : Array(Node), location : Crystal::Location?)
23
23
  @info = {
24
24
  type: self.class.name.split("::").last,
25
25
  children: @children,
@@ -32,7 +32,7 @@ module Rb
32
32
  abstract class NodeWithValue < Node
33
33
  @info : NamedTuple(type: String, value: String)
34
34
 
35
- def initialize(@value : String)
35
+ def initialize(@value : String, location : Crystal::Location?)
36
36
  @info = {
37
37
  type: self.class.name.split("::").last,
38
38
  value: @value,
@@ -43,13 +43,14 @@ module Rb
43
43
  end
44
44
 
45
45
  class Block < Node
46
- @info : NamedTuple(type: String, args: Array(Var), body: Node)
46
+ @info : NamedTuple(type: String, positional_args: Array(Var), body: Node, rest_p_args: Node?)
47
47
 
48
- def initialize(args, body)
48
+ def initialize(args, splat, body, location : Crystal::Location?)
49
49
  @info = {
50
50
  type: self.class.name.split("::").last,
51
51
  body: body,
52
- args: args,
52
+ positional_args: args,
53
+ rest_p_args: splat
53
54
  }
54
55
  end
55
56
 
@@ -62,7 +63,7 @@ module Rb
62
63
  class ClassNode < Node
63
64
  @info : NamedTuple(type: String, name: Path, body: Node, superclass: Node?, type_vars: Array(String)?, abstract: Bool)
64
65
 
65
- def initialize(name : Path, body : Node, superclass : Node?, type_vars : Array(String)?, abstr : Bool)
66
+ def initialize(name : Path, body : Node, superclass : Node?, type_vars : Array(String)?, abstr : Bool, location : Crystal::Location?)
66
67
  @info = {
67
68
  type: self.class.name.split("::").last,
68
69
  name: name,
@@ -80,7 +81,7 @@ module Rb
80
81
  class ModuleNode < Node
81
82
  @info : NamedTuple(type: String, name: Path, body: Node, type_vars: Array(String)?)
82
83
 
83
- def initialize(name : Path, body : Node, type_vars : Array(String)?)
84
+ def initialize(name : Path, body : Node, type_vars : Array(String)?, location : Crystal::Location?)
84
85
  @info = {
85
86
  type: self.class.name.split("::").last,
86
87
  name: name,
@@ -94,18 +95,32 @@ module Rb
94
95
  end
95
96
 
96
97
  class DefNode < Node
97
- @info : NamedTuple(type: String, name: String, body: Node, rp_args: Array(Arg), receiver: Node?,
98
- return_type: Node?, rest_kw_args: Arg?)
98
+ @info : NamedTuple(type: String, name: String, body: Node, positional_args: Array(Arg), receiver: Node?,
99
+ return_type: Node?, rest_kw_args: Arg?, rest_p_args: Arg?, block_arg: Node?, yield_arg_count: Int32?)
99
100
 
100
- def initialize(name : String, rp_args : Array(Arg), body : Node, receiver : Node?, return_type : Node?, rest_kw_args)
101
+ def initialize(
102
+ receiver : Node?,
103
+ name : String,
104
+ positional_args : Array(Arg),
105
+ splat,
106
+ rest_kw_args,
107
+ body : Node,
108
+ return_type : Node?,
109
+ yields : Int32?,
110
+ block_arg : Node?,
111
+ location : Crystal::Location?
112
+ )
101
113
  @info = {
102
- type: self.class.name.split("::").last,
103
- name: name,
104
- body: body,
105
- rp_args: rp_args,
106
- rest_kw_args: rest_kw_args,
107
- receiver: receiver,
108
- return_type: return_type,
114
+ type: self.class.name.split("::").last,
115
+ name: name,
116
+ body: body,
117
+ positional_args: positional_args,
118
+ rest_kw_args: rest_kw_args,
119
+ receiver: receiver,
120
+ return_type: return_type,
121
+ rest_p_args: splat,
122
+ yield_arg_count: yields,
123
+ block_arg: block_arg
109
124
  }
110
125
  end
111
126
 
@@ -116,15 +131,15 @@ module Rb
116
131
  @info : NamedTuple(type: String, name: String, external_name: String, value: Node?,
117
132
  restriction: Node?, keyword_arg: Bool)
118
133
 
119
- def initialize(name : String, external_name : String, restriction : Node?, value :
120
- Node?, keyword_arg)
134
+ def initialize(name : String, external_name : String, restriction : Node?, value : Node?,
135
+ keyword_arg, location : Crystal::Location?)
121
136
  @info = {
122
137
  type: self.class.name.split("::").last,
123
138
  name: name,
124
139
  restriction: restriction,
125
- value: value,
140
+ value: value,
126
141
  external_name: external_name,
127
- keyword_arg: keyword_arg
142
+ keyword_arg: keyword_arg,
128
143
  }
129
144
  end
130
145
 
@@ -134,7 +149,7 @@ module Rb
134
149
  class LiteralNode < Node
135
150
  @info : NamedTuple(type: String, value: String | Int32 | Bool | Nil, rb_type: String)
136
151
 
137
- def initialize(value, rb_type : RbLiteral)
152
+ def initialize(value, rb_type : RbLiteral, location : Crystal::Location?)
138
153
  val = case rb_type
139
154
  when Rb::AST::RbLiteral::TrueClass
140
155
  true
@@ -160,7 +175,7 @@ module Rb
160
175
  class ArrayLiteral < Node
161
176
  @info : NamedTuple(type: String, elements: Array(Node), frozen: Bool)
162
177
 
163
- def initialize(elems, frozen = false)
178
+ def initialize(elems, location : Crystal::Location?, frozen = false)
164
179
  @info = {
165
180
  type: self.class.name.split("::").last,
166
181
  elements: elems,
@@ -174,7 +189,7 @@ module Rb
174
189
  class HashLiteral < Node
175
190
  @info : NamedTuple(type: String, elements: Array(Tuple(Node, Node)) | Array(Tuple(String, Node)), frozen: Bool)
176
191
 
177
- def initialize(elems, frozen = false)
192
+ def initialize(elems, location : Crystal::Location?, frozen = false)
178
193
  @info = {
179
194
  type: self.class.name.split("::").last,
180
195
  elements: elems,
@@ -188,7 +203,7 @@ module Rb
188
203
  class RangeLiteral < Node
189
204
  @info : NamedTuple(type: String, from: Node, to: Node, exclusive: Bool)
190
205
 
191
- def initialize(from, to, exclusive)
206
+ def initialize(from, to, exclusive, location : Crystal::Location?)
192
207
  @info = {
193
208
  type: self.class.name.split("::").last,
194
209
  from: from,
@@ -203,7 +218,7 @@ module Rb
203
218
  class RegexLiteral < Node
204
219
  @info : NamedTuple(type: String, value: Node)
205
220
 
206
- def initialize(value)
221
+ def initialize(value, location : Crystal::Location?)
207
222
  @info = {
208
223
  type: self.class.name.split("::").last,
209
224
  value: value,
@@ -224,7 +239,7 @@ module Rb
224
239
  end
225
240
 
226
241
  class EmptyNode < Nop
227
- def initialize(class_name : String)
242
+ def initialize(class_name : String, location : Crystal::Location?)
228
243
  STDERR.puts "Encountered a ruby EmptyNode class name: #{class_name}"
229
244
  @info = {
230
245
  type: self.class.name.split("::").last,
@@ -235,7 +250,7 @@ module Rb
235
250
  class Var < Node
236
251
  @info : NamedTuple(type: String, name: String)
237
252
 
238
- def initialize(@name : String)
253
+ def initialize(@name : String, location : Crystal::Location?)
239
254
  @info = {
240
255
  type: self.class.name.split("::").last,
241
256
  name: @name,
@@ -254,7 +269,7 @@ module Rb
254
269
  abstract class Conditional < Node
255
270
  @info : NamedTuple(type: String, condition: Node, then: Node, else: Node)
256
271
 
257
- def initialize(@condition : Node, @thn : Node, @els : Node)
272
+ def initialize(@condition : Node, @thn : Node, @els : Node, location : Crystal::Location?)
258
273
  @info = {
259
274
  type: self.class.name.split("::").last,
260
275
  condition: @condition,
@@ -275,7 +290,7 @@ module Rb
275
290
  class Case < Node
276
291
  @info : NamedTuple(type: String, condition: Node?, whens: Array(When), else: Node?, exhaustive: Bool)
277
292
 
278
- def initialize(cond : Node?, whens : Array(When), els : Node?, exhaustive : Bool)
293
+ def initialize(cond : Node?, whens : Array(When), els : Node?, exhaustive : Bool, location : Crystal::Location?)
279
294
  @info = {
280
295
  type: self.class.name.split("::").last,
281
296
  condition: cond,
@@ -291,7 +306,7 @@ module Rb
291
306
  class When < Node
292
307
  @info : NamedTuple(type: String, conditions: Array(Node), body: Node, exhaustive: Bool)
293
308
 
294
- def initialize(conds : Array(Node), body : Node, exhaustive : Bool)
309
+ def initialize(conds : Array(Node), body : Node, exhaustive : Bool, location : Crystal::Location?)
295
310
  @info = {
296
311
  type: self.class.name.split("::").last,
297
312
  conditions: conds,
@@ -306,7 +321,7 @@ module Rb
306
321
  class Enum < Node
307
322
  @info : NamedTuple(type: String, name: Crystal::Path, members: Array(Node))
308
323
 
309
- def initialize(@name : Crystal::Path, @members : Array(Node))
324
+ def initialize(@name : Crystal::Path, @members : Array(Node), location : Crystal::Location?)
310
325
  @info = {
311
326
  type: self.class.name.split("::").last,
312
327
  name: @name,
@@ -318,18 +333,18 @@ module Rb
318
333
  end
319
334
 
320
335
  class Call < Node
321
- @info : NamedTuple(type: String, name: String, args: Array(Node), object: Node?, block:
322
- Block?, block_arg: Node?, named_args: Array(Arg)?)
336
+ @info : NamedTuple(type: String, name: String, args: Array(Node), object: Node?, block: Block?, block_arg: Node?, named_args: Array(Arg)?, has_parentheses: Bool)
323
337
 
324
- def initialize(object : Node?, name : String, args : Array(Node), named_args, block, block_arg)
338
+ def initialize(object : Node?, name : String, args : Array(Node), named_args, block, block_arg, has_parentheses, location : Crystal::Location?)
325
339
  @info = {
326
- type: self.class.name.split("::").last,
327
- name: name,
328
- args: args,
329
- object: object,
330
- block: block,
331
- block_arg: block_arg,
332
- named_args: named_args,
340
+ type: self.class.name.split("::").last,
341
+ name: name,
342
+ args: args,
343
+ object: object,
344
+ block: block,
345
+ block_arg: block_arg,
346
+ named_args: named_args,
347
+ has_parentheses: has_parentheses || false,
333
348
  }
334
349
  end
335
350
 
@@ -345,7 +360,7 @@ module Rb
345
360
  class StringInterpolation < Node
346
361
  @info : NamedTuple(type: String, contents: Array(Node))
347
362
 
348
- def initialize(contents)
363
+ def initialize(contents, location : Crystal::Location?)
349
364
  @info = {
350
365
  type: self.class.name.split("::").last,
351
366
  contents: contents,
@@ -358,7 +373,7 @@ module Rb
358
373
  class UnaryExpr < Node
359
374
  @info : NamedTuple(type: String, op: String, value: Node, with_parens: Bool)
360
375
 
361
- def initialize(val, op, parens)
376
+ def initialize(val, op, parens, location : Crystal::Location?)
362
377
  @info = {
363
378
  type: self.class.name.split("::").last,
364
379
  value: val,
@@ -373,7 +388,7 @@ module Rb
373
388
  class BinaryOp < Node
374
389
  @info : NamedTuple(type: String, op: String, left: Node, right: Node)
375
390
 
376
- def initialize(op, left, right)
391
+ def initialize(op, left, right, location : Crystal::Location?)
377
392
  @info = {
378
393
  type: self.class.name.split("::").last,
379
394
  left: left,
@@ -388,7 +403,7 @@ module Rb
388
403
  class Assign < Node
389
404
  @info : NamedTuple(type: String, op: String?, target: Node, value: Node)
390
405
 
391
- def initialize(target, value, op = nil)
406
+ def initialize(target, value, op, location : Crystal::Location?)
392
407
  @info = {
393
408
  type: self.class.name.split("::").last,
394
409
  target: target,
@@ -400,10 +415,24 @@ module Rb
400
415
  delegate :to_json, to: @info
401
416
  end
402
417
 
418
+ class MultiAssign < Node
419
+ @info : NamedTuple(type: String, targets: Array(Node), values: Array(Node))
420
+
421
+ def initialize(targets, values, location : Crystal::Location?)
422
+ @info = {
423
+ type: self.class.name.split("::").last,
424
+ targets: targets,
425
+ values: values,
426
+ }
427
+ end
428
+
429
+ delegate :to_json, to: @info
430
+ end
431
+
403
432
  class TypeDeclaration < Node
404
433
  @info : NamedTuple(type: String, var: Node, declared_type: Node, value: Node?, var_type: String)
405
434
 
406
- def initialize(@var : Node, @declared_type : Node, @value : Node?)
435
+ def initialize(@var : Node, @declared_type : Node, @value : Node?, location : Crystal::Location?)
407
436
  @info = {
408
437
  type: self.class.name.split("::").last,
409
438
  var: @var,
@@ -419,7 +448,7 @@ module Rb
419
448
  class MacroFor < Node
420
449
  @info : NamedTuple(type: String, vars: Array(Var), expr: Node, body: Node)
421
450
 
422
- def initialize(vars, expr, body)
451
+ def initialize(vars, expr, body, location : Crystal::Location?)
423
452
  @info = {
424
453
  type: self.class.name.split("::").last,
425
454
  vars: vars,
@@ -440,7 +469,7 @@ module Rb
440
469
  class MacroExpression < Node
441
470
  @info : NamedTuple(type: String, expr: Node, output: Bool)
442
471
 
443
- def initialize(expr, output)
472
+ def initialize(expr, output, location : Crystal::Location?)
444
473
  @info = {
445
474
  type: self.class.name.split("::").last,
446
475
  expr: expr,
@@ -454,7 +483,7 @@ module Rb
454
483
  class ControlExpression < Node
455
484
  @info : NamedTuple(type: String, value: Node?)
456
485
 
457
- def initialize(value)
486
+ def initialize(value, location : Crystal::Location?)
458
487
  @info = {
459
488
  type: self.class.name.split("::").last,
460
489
  value: value,
@@ -477,7 +506,7 @@ module Rb
477
506
  @info : NamedTuple(type: String, body: Node, rescues: Array(Rescue)?, else: Node?,
478
507
  ensure: Node?)
479
508
 
480
- def initialize(body, rescues, else_node, ensure_node)
509
+ def initialize(body, rescues, else_node, ensure_node, location : Crystal::Location?)
481
510
  @info = {
482
511
  type: self.class.name.split("::").last,
483
512
  body: body,
@@ -493,7 +522,7 @@ module Rb
493
522
  class Rescue < Node
494
523
  @info : NamedTuple(type: String, body: Node, types: Array(Node)?, name: String?)
495
524
 
496
- def initialize(body, types, name)
525
+ def initialize(body, types, name, location : Crystal::Location?)
497
526
  @info = {
498
527
  type: self.class.name.split("::").last,
499
528
  body: body,
@@ -508,10 +537,10 @@ module Rb
508
537
  class Union < Node
509
538
  @info : NamedTuple(type: String, types: Array(Node))
510
539
 
511
- def initialize(types)
540
+ def initialize(types, location : Crystal::Location?)
512
541
  @info = {
513
542
  type: self.class.name.split("::").last,
514
- types: types
543
+ types: types,
515
544
  }
516
545
  end
517
546
 
@@ -521,11 +550,11 @@ module Rb
521
550
  class Generic < Node
522
551
  @info : NamedTuple(type: String, name: Node, args: Array(Node))
523
552
 
524
- def initialize(name, args)
553
+ def initialize(name, args, location : Crystal::Location?)
525
554
  @info = {
526
- type: self.class.name.split("::").last,
555
+ type: self.class.name.split("::").last,
527
556
  name: name,
528
- args: args
557
+ args: args,
529
558
  }
530
559
  end
531
560
 
@@ -535,10 +564,10 @@ module Rb
535
564
  class Proc < Node
536
565
  @info : NamedTuple(type: String, function: DefNode)
537
566
 
538
- def initialize(function)
567
+ def initialize(function, location : Crystal::Location?)
539
568
  @info = {
540
- type: self.class.name.split("::").last,
541
- function: function
569
+ type: self.class.name.split("::").last,
570
+ function: function,
542
571
  }
543
572
  end
544
573
 
@@ -548,10 +577,10 @@ module Rb
548
577
  class NodeWithNameNode < Node
549
578
  @info : NamedTuple(type: String, name: Node)
550
579
 
551
- def initialize(name)
580
+ def initialize(name, location : Crystal::Location?)
552
581
  @info = {
553
- type: self.class.name.split("::").last,
554
- name: name
582
+ type: self.class.name.split("::").last,
583
+ name: name,
555
584
  }
556
585
  end
557
586
 
@@ -563,5 +592,27 @@ module Rb
563
592
 
564
593
  class Include < NodeWithNameNode
565
594
  end
595
+
596
+ class VisibilityModifier < Node
597
+ @info : NamedTuple(type: String, visibility: String, exp: Node)
598
+
599
+ def initialize(visibility : Crystal::Visibility, exp : Node, location : Crystal::Location?)
600
+ vis = case visibility
601
+ when Crystal::Visibility::Public
602
+ "public"
603
+ when Crystal::Visibility::Protected
604
+ "protected"
605
+ when Crystal::Visibility::Private
606
+ "private"
607
+ end
608
+ @info = {
609
+ type: self.class.name.split("::").last,
610
+ visibility: vis.as(String),
611
+ exp: exp,
612
+ }
613
+ end
614
+
615
+ delegate :to_json, to: @info
616
+ end
566
617
  end
567
618
  end