@tilua/parser 1.0.2 → 2.0.0

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.
package/README.md CHANGED
@@ -96,10 +96,14 @@ npm i -D @tilua-types/roblox # Luau + Roblox; or @tilua-types/lua on its
96
96
  - **Which config applies** — the nearest one in the file's folder or above.
97
97
  `tilua.config.json` and `tilua.config.jsonc` in the same folder is an error.
98
98
  Both forms accept comments and trailing commas.
99
- - **`types`** — any name, looked up as the package `@tilua-types/<name>` in
100
- `node_modules` from the config upward; one that is not installed is an
101
- error. A relative path (`"./types"`, `"./defs.d.tilua"`) loads the project's
102
- own definitions. A type library's own type-library dependencies load first.
99
+ - **`types`** — packages are looked for in `node_modules` from the config
100
+ upward. A bare name is `@tilua-types/<name>` first, then the package of that
101
+ name, so a library published under any name works: `"roblox"`,
102
+ `"my-types"`. A scoped name is taken as written (`"@me/types"`), and a `*`
103
+ matches every installed type library it fits (`"@tilua-types/*"`), in name
104
+ order. A relative path (`"./types"`, `"./defs.d.tilua"`) loads the project's
105
+ own definitions. A type library's own type-library dependencies load first;
106
+ one that is not installed is an error.
103
107
  - **`paths`** — tsconfig rules: an exact pattern wins, then the `*` pattern
104
108
  with the longest prefix; targets resolve from `baseUrl` (default: the
105
109
  config's folder).
@@ -147,7 +151,7 @@ if (n < 0) {
147
151
 
148
152
  while (going) { step() }
149
153
  for (i = 1, 10) { total += i }
150
- for (name, value in pairs(t)) { print(name, value) }
154
+ for (const [name, value] in pairs(t)) { print(name, value) }
151
155
  repeat { step() } until (done)
152
156
  do { ... }
153
157
 
@@ -175,7 +179,7 @@ if (n < 0) return "negative"
175
179
  elseif (n == 0) return "zero"
176
180
  else return "positive"
177
181
 
178
- for (_, item in items) if (item) print(item)
182
+ for (const item in items) if (item) print(item)
179
183
  while (queued > 0) queued -= 1
180
184
  ```
181
185
 
@@ -298,6 +302,18 @@ call needed it — and the receiver is passed as the call's first argument. An
298
302
  answer of `undefined` leaves an ordinary Luau method call, which is what
299
303
  `text:upper()` wants, since a string already answers to it.
300
304
 
305
+ A call can also carry more than was written. Every hook is told `at`, where
306
+ the call was written (`{ file, line, column }`), and `arguments`: each one's
307
+ type, that type as text, the code it was written as, and, for a name, the
308
+ code of what it names. An answer's `prepend` lists Luau expressions to pass
309
+ ahead of the written arguments. `globalCall` answers for a call to a global,
310
+ such as `print(x)`, and `globalValue` for a global read as a value, such as
311
+ `local p = print`. A local with the same name belongs to the author, and no
312
+ hook is asked about it. A runtime can read `__LINES__`, the bundle's line map
313
+ (`nil` outside a bundle), to turn a line Luau reports back into a place in the
314
+ project. `console:log`, `print` and `error` in `@tilua-types/lua` are built on
315
+ these hooks.
316
+
301
317
  The compiler lowers the language and nothing else: `filter` appears nowhere in
302
318
  it.
303
319
 
@@ -395,7 +411,7 @@ class Dog extends Animal {
395
411
  }
396
412
  }
397
413
 
398
- const rex = new Dog("Rex", "shiba")
414
+ const rex = Dog.new("Rex", "shiba")
399
415
  rex:speak() -- the receiver is `this`
400
416
  rex.label = "Max" -- the setter
401
417
  Dog.made() -- a static, inherited from Animal
@@ -403,14 +419,98 @@ Dog.made() -- a static, inherited from Animal
403
419
 
404
420
  The receiver is written `this`, and it is an ordinary first parameter: a
405
421
  method's type is `(this: Dog, ...) => R`, so `rex:speak()` supplies it the way
406
- `function T:m()` supplies `self`. `new Dog(x)` *is* `Dog.new(x)` — the same
407
- function, callable by hand and passable as a value.
422
+ `function T:m()` supplies `self`. An instance is built the way Luau builds
423
+ one, with the class's own function: `Dog.new(x)` — callable like any other,
424
+ and passable as a value. There is no `new Dog(x)`; writing it is a syntax
425
+ error that says so.
426
+
427
+ **`public`, `private` and `protected`** go before a member — `private
428
+ balance = 0`, `private static function check()`, `public get size()`. Leaving
429
+ it out means public. A private member can be reached only inside the body of
430
+ the class that declared it, including functions nested in its methods; a
431
+ subclass is outside, as in TypeScript. A protected one is reachable from the
432
+ classes extending it too. It is a type check and nothing more: the member is
433
+ an ordinary key at runtime.
434
+
435
+ **`readonly`** fields are assigned where they are declared or in the
436
+ constructor of their own class, and nowhere else: `readonly id: number`.
437
+
438
+ The modifiers can come in any order — `static private readonly count = 0` —
439
+ and each stays an ordinary name where no member follows it, so
440
+ `private: boolean` and `readonly = 1` are still fields.
441
+
442
+ **`abstract`** — an `abstract class` has no `new`: it is built only as part of
443
+ a class extending it. It may declare `abstract function area(): number`, a
444
+ head with no body, and a class extending it that is not abstract itself has to
445
+ write every such member. Calling an abstract method through `super` is an
446
+ error, as is `Shape.new`.
447
+
448
+ **`override`** says a member replaces one of the class it extends, and is an
449
+ error on a member that does not. Whether or not it is written, a member that
450
+ replaces one has to fit it: its type, `this` aside, is checked against the
451
+ base's.
452
+
453
+ **`implements`** — `class Person implements Named, Greeter` checks that the
454
+ instances have every member each shape names, of a type that fits. Nothing
455
+ happens at runtime.
456
+
457
+ ```luau
458
+ abstract class Shape implements Named {
459
+ readonly name: string
460
+ protected sides = 0
461
+ constructor(name: string) {
462
+ this.name = name
463
+ }
464
+ abstract function area(): number
465
+ }
466
+
467
+ class Square extends Shape {
468
+ side = 1
469
+ constructor() {
470
+ super("square")
471
+ this.sides = 4 -- protected: reachable from here
472
+ }
473
+ override function area(): number {
474
+ return this.side * this.side
475
+ }
476
+ }
477
+ ```
478
+
479
+ **Metamethods** are methods with their Luau names. The class table *is* its
480
+ instances' metatable, so `function __add(other: Vec): Vec` in a class is the
481
+ `+` of its instances — and the type checker reads it the same way: `a + b`
482
+ between two `Vec`s is a `Vec`. `__sub`, `__mul`, `__div`, `__idiv`, `__mod`,
483
+ `__pow`, `__unm`, `__concat`, `__len` (`#v`), `__eq`, `__lt` and `__le` (`<`,
484
+ `>`, `<=`, `>=`), `__call` (calling an instance), `__iter` (`for a, b in v`)
485
+ and `__tostring` all work this way, and a class extending another inherits
486
+ them. Each is checked: it takes the operands Luau hands it, returns what Luau
487
+ expects of it (`__tostring` a string, `__eq`/`__lt`/`__le` a boolean), and is
488
+ not `static`. Comparing two instances whose class has no `__lt` is an error,
489
+ as it is at runtime.
490
+
491
+ ```luau
492
+ class Vec {
493
+ x: number
494
+ constructor(x: number) {
495
+ this.x = x
496
+ }
497
+ function __add(other: Vec): Vec {
498
+ return Vec.new(this.x + other.x)
499
+ }
500
+ function __tostring(): string {
501
+ return `Vec(${this.x})`
502
+ }
503
+ }
504
+
505
+ const v = Vec.new(1) + Vec.new(2) -- Vec
506
+ print(tostring(v)) -- Vec(3)
507
+ ```
408
508
 
409
509
  A declaration names two things. As a **type**, `Dog` is the type of its
410
510
  instances, nominal the same way a `declare class` is: a table with the same
411
511
  members is not one, and only `Dog` and what extends it are assignable to it.
412
512
  As a **value**, `Dog` is the class table — its statics, and the `new` that
413
- builds an instance. `export class` exports both.
513
+ builds an instance (`Dog.new(...)`). `export class` exports both.
414
514
 
415
515
  Two links are always there, and they are what the memory model promises:
416
516
 
@@ -435,12 +535,12 @@ class Box<T> {
435
535
  return this.value
436
536
  }
437
537
  function map<R>(f: (value: T) => R): Box<R> {
438
- return new Box(f(this.value))
538
+ return Box.new(f(this.value))
439
539
  }
440
540
  }
441
541
 
442
- const n = new Box(1) -- Box<number>, read off the argument
443
- const s = new Box<string>("a") -- or written out
542
+ const n = Box.new(1) -- Box<number>, read off the argument
543
+ const s = Box.new<string>("a") -- or written out
444
544
  const held: number = n:get()
445
545
 
446
546
  class Ints extends Box<number> { -- extending one fixes its argument
@@ -462,24 +562,65 @@ it, as TypeScript's does, and importing it brings in the type too:
462
562
 
463
563
  ```luau
464
564
  import Box from "./box" -- `Box` is the class *and* the type
465
- const held: Box<number> = new Box(1)
565
+ const held: Box<number> = Box.new(1)
466
566
  ```
467
567
 
468
568
  Reported: a field with a type that nothing gives a value (`name: string` that
469
- the constructor never assigns), a derived constructor that does not call
569
+ the constructor does not assign on every way through it — both arms of an
570
+ `if`, not in a loop or a function written inside), a derived constructor that does not call
470
571
  `super(...)`, `extends` naming something that is not a class, a chain that
471
572
  closes on itself, a member written twice, and a member named one of the words
472
573
  the compiler builds the class table out of (`new`, `ClassObject`,
473
574
  `ParentClass`, `__init`, `__index`, `__newindex`, `__getters`, `__setters`,
474
575
  `__dynamic`).
475
576
 
476
- **Varargs** — `...` is Lua's pack, and every name on the left reads one of
477
- it: with `...: number`, `const a, b = ...` gives two numbers. `[...]` puts the
478
- whole pack in an array.
577
+ **One value, and arrays** — tilua has no packs. A function returns one value;
578
+ several are an array, and a tuple type says how many and of what:
579
+
580
+ ```luau
581
+ function divide(a: number, b: number): [number, number] {
582
+ return [a // b, a % b]
583
+ }
584
+
585
+ const [quotient, remainder] = divide(7, 2) -- taken apart
586
+ const both = divide(7, 2) -- or kept: [number, number]
587
+ ```
588
+
589
+ An array is a table, at runtime as much as in the types: `return [a, b]` is
590
+ `return { a, b }`. Where Luau answers several values — `pcall`, `string.find`,
591
+ a Roblox method such as `FindPartOnRay` — the type library puts a function of
592
+ its own in place of that global or method, which answers one value, as its
593
+ type says. A tuple may end in a rest,
594
+ `[string, ...number[]]`: that many, then any number more. `const a, b = 1, 2`
595
+ still pairs names with values one each; `const a, b = f()` is a name short,
596
+ and says to write `const [a, b] = f()`.
597
+
598
+ **A loop takes one value too** — `for (const item in source)`, and several are
599
+ an array the pattern takes apart:
600
+
601
+ ```luau
602
+ for (const name in names) { print(name) }
603
+ for (const [i, name] in ipairs(names)) { print(i, name) }
604
+ for (const [key, score] in pairs(scores)) { print(key, score) }
605
+ ```
606
+
607
+ The name is `const`, or `let` where the body assigns to it, as anywhere else.
608
+ A source is an array or a table, walked for its values; an iterator function,
609
+ called until it answers `nil`; or an iteration — `[step, state, first]`, what
610
+ `pairs(t)` answers — whose `step` is called with the state and the item before
611
+ it. An object says how it is walked with `__iter`, which answers one of those
612
+ two. `for (k, v in ...)` and `for (x in f, s, v)` are Luau's packs, and are
613
+ syntax errors.
614
+
615
+ A function that returns nothing returns `nil`: `() => nil`, not `() => ()`.
616
+ Bare `...` is gone — a
617
+ function takes a rest parameter, and what the script was started with is
618
+ `scriptArgs: unknown[]`. `()`, `(A, B)` as a type, `T...`, `...: T` and
619
+ `return a, b` are syntax errors that say what to write instead.
479
620
 
480
621
  **Rest parameters** — `...name: T[]` is JavaScript's: every argument from that
481
- position on, as an array. It is last, and the call signature is the same one
482
- `...: T` describes — the difference is only what the body sees.
622
+ position on, as an array. It is last, and it is the one way a function takes a
623
+ varying number of arguments.
483
624
 
484
625
  ```luau
485
626
  function join(separator: string, ...parts: string[]): string {
@@ -497,24 +638,28 @@ firstOf(1, 2) -- number | nil: the arguments say what `T` is
497
638
  ```
498
639
 
499
640
  A type is written the same way: `type Reporter = (level: string, ...lines:
500
- string[]) => ()` describes the same calls as `(level: string, ...string) =>
501
- ()`. Without an annotation a rest parameter is `unknown[]`; annotated with
502
- something that is not an array, it is reported.
641
+ string[]) => nil`. Without an annotation a rest parameter is `unknown[]`. A rest
642
+ parameter may also be a tuple, or a type parameter standing for one — then the
643
+ arguments are exactly its elements, which is how a function says it forwards
644
+ another's:
645
+
646
+ ```luau
647
+ declare function spawn<A extends unknown[]>(f: (...args: A) => nil, ...args: A): thread
503
648
 
504
- **Spreads** — `...xs` puts what an array holds into any list of values, as
505
- JavaScript does: a call's arguments, a `return`, a declaration, an assignment.
506
- Bare `...` is unchanged, and is still the pack.
649
+ spawn(function(n: number) { print(n) }, 1) -- ok
650
+ spawn(function(n: number) { print(n) }, "no") -- '"no"' is not a number
651
+ ```
652
+
653
+ **Spreads** — `...xs` puts what an array holds into a call's arguments or an
654
+ array literal, as JavaScript does. A list of values — a declaration's, an
655
+ assignment's — takes one value per name; take an array apart with a
656
+ destructuring instead.
507
657
 
508
658
  ```luau
509
659
  join("-", ...names) -- every name
510
660
  join("-", ...names, "z") -- and one more after them
511
661
  add3(...nums) -- however many `nums` turns out to hold
512
-
513
- function three(): (number, number, number) {
514
- return ...nums
515
- }
516
-
517
- const first, second = ...names -- one each, as far as the names go
662
+ const both = [...names, "z"]
518
663
  ```
519
664
 
520
665
  What the array holds is checked against what it fills. How many it holds is
@@ -550,9 +695,10 @@ its parameter types from it: in `signal:Connect(player => ... )`,
550
695
  `player` is typed from `Connect`. The same applies to an annotated `const`
551
696
  and to an assignment such as `remote.OnServerInvoke = function(player) { ... }`.
552
697
 
553
- **Type packs** — `type Signal<T... = ...any> = { Connect: (self, cb: (T...) => ()) => () }`.
554
- A pack parameter takes every type argument from its position on:
555
- `Signal<Player, string>`, `Signal<()>` for none.
698
+ **Signals and other variadic generics** — a type parameter can stand for a
699
+ list of arguments: `type Signal<T extends unknown[] = any[]> = { Connect:
700
+ (self, cb: (...args: T) => nil) => Connection }`, given as a tuple —
701
+ `Signal<[Player, string]>`, `Signal<[]>` for none.
556
702
 
557
703
  **Operators** — on a type that declares metamethods (`__add`, `__mul`,
558
704
  `__unm`, ...), an operator has the metamethod's result, tried on the left
@@ -597,8 +743,8 @@ non-nil part.
597
743
 
598
744
  Only `nil` and `false` are falsy — `0` and `""` are truthy, unlike JavaScript.
599
745
 
600
- **Types** — unions, intersections, tuples `[A, B]`, type packs `(A, B)` (the
601
- several values a function returns), `keyof`, `T[K]`, conditional types with
746
+ **Types** — unions, intersections, tuples `[A, B]` (with a rest, `[A,
747
+ ...B[]]`), `keyof`, `T[K]`, conditional types with
602
748
  `infer`, mapped types with `as` remapping, template literal types
603
749
  (`` `on${Event}` ``), and set difference `A - B`. The utility types
604
750
  (`Partial`, `Pick`, `Omit`, `ReturnType`, `Parameters`, `Exclude`, …) are