gloss 0.0.3 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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