@tilua/parser 1.1.0 → 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
 
@@ -407,7 +411,7 @@ class Dog extends Animal {
407
411
  }
408
412
  }
409
413
 
410
- const rex = new Dog("Rex", "shiba")
414
+ const rex = Dog.new("Rex", "shiba")
411
415
  rex:speak() -- the receiver is `this`
412
416
  rex.label = "Max" -- the setter
413
417
  Dog.made() -- a static, inherited from Animal
@@ -415,22 +419,98 @@ Dog.made() -- a static, inherited from Animal
415
419
 
416
420
  The receiver is written `this`, and it is an ordinary first parameter: a
417
421
  method's type is `(this: Dog, ...) => R`, so `rex:speak()` supplies it the way
418
- `function T:m()` supplies `self`. `new Dog(x)` *is* `Dog.new(x)` — the same
419
- 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.
420
456
 
421
- **`public` and `private`** go before a member — `private balance = 0`,
422
- `private static function check()`, `public get size()`. Leaving it out means
423
- public. A private member can be reached only inside the body of the class that
424
- declared it, including functions nested in its methods; a subclass is outside,
425
- as in TypeScript. It is a type check and nothing more: the member is an
426
- ordinary key at runtime. `public` and `private` stay ordinary names elsewhere,
427
- so `private: boolean` is still a field.
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
+ ```
428
508
 
429
509
  A declaration names two things. As a **type**, `Dog` is the type of its
430
510
  instances, nominal the same way a `declare class` is: a table with the same
431
511
  members is not one, and only `Dog` and what extends it are assignable to it.
432
512
  As a **value**, `Dog` is the class table — its statics, and the `new` that
433
- builds an instance. `export class` exports both.
513
+ builds an instance (`Dog.new(...)`). `export class` exports both.
434
514
 
435
515
  Two links are always there, and they are what the memory model promises:
436
516
 
@@ -455,12 +535,12 @@ class Box<T> {
455
535
  return this.value
456
536
  }
457
537
  function map<R>(f: (value: T) => R): Box<R> {
458
- return new Box(f(this.value))
538
+ return Box.new(f(this.value))
459
539
  }
460
540
  }
461
541
 
462
- const n = new Box(1) -- Box<number>, read off the argument
463
- 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
464
544
  const held: number = n:get()
465
545
 
466
546
  class Ints extends Box<number> { -- extending one fixes its argument
@@ -482,24 +562,65 @@ it, as TypeScript's does, and importing it brings in the type too:
482
562
 
483
563
  ```luau
484
564
  import Box from "./box" -- `Box` is the class *and* the type
485
- const held: Box<number> = new Box(1)
565
+ const held: Box<number> = Box.new(1)
486
566
  ```
487
567
 
488
568
  Reported: a field with a type that nothing gives a value (`name: string` that
489
- 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
490
571
  `super(...)`, `extends` naming something that is not a class, a chain that
491
572
  closes on itself, a member written twice, and a member named one of the words
492
573
  the compiler builds the class table out of (`new`, `ClassObject`,
493
574
  `ParentClass`, `__init`, `__index`, `__newindex`, `__getters`, `__setters`,
494
575
  `__dynamic`).
495
576
 
496
- **Varargs** — `...` is Lua's pack, and every name on the left reads one of
497
- it: with `...: number`, `const a, b = ...` gives two numbers. `[...]` puts the
498
- 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.
499
620
 
500
621
  **Rest parameters** — `...name: T[]` is JavaScript's: every argument from that
501
- position on, as an array. It is last, and the call signature is the same one
502
- `...: 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.
503
624
 
504
625
  ```luau
505
626
  function join(separator: string, ...parts: string[]): string {
@@ -517,24 +638,28 @@ firstOf(1, 2) -- number | nil: the arguments say what `T` is
517
638
  ```
518
639
 
519
640
  A type is written the same way: `type Reporter = (level: string, ...lines:
520
- string[]) => ()` describes the same calls as `(level: string, ...string) =>
521
- ()`. Without an annotation a rest parameter is `unknown[]`; annotated with
522
- 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:
523
645
 
524
- **Spreads** — `...xs` puts what an array holds into any list of values, as
525
- JavaScript does: a call's arguments, a `return`, a declaration, an assignment.
526
- Bare `...` is unchanged, and is still the pack.
646
+ ```luau
647
+ declare function spawn<A extends unknown[]>(f: (...args: A) => nil, ...args: A): thread
648
+
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.
527
657
 
528
658
  ```luau
529
659
  join("-", ...names) -- every name
530
660
  join("-", ...names, "z") -- and one more after them
531
661
  add3(...nums) -- however many `nums` turns out to hold
532
-
533
- function three(): (number, number, number) {
534
- return ...nums
535
- }
536
-
537
- const first, second = ...names -- one each, as far as the names go
662
+ const both = [...names, "z"]
538
663
  ```
539
664
 
540
665
  What the array holds is checked against what it fills. How many it holds is
@@ -570,9 +695,10 @@ its parameter types from it: in `signal:Connect(player => ... )`,
570
695
  `player` is typed from `Connect`. The same applies to an annotated `const`
571
696
  and to an assignment such as `remote.OnServerInvoke = function(player) { ... }`.
572
697
 
573
- **Type packs** — `type Signal<T... = ...any> = { Connect: (self, cb: (T...) => ()) => () }`.
574
- A pack parameter takes every type argument from its position on:
575
- `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.
576
702
 
577
703
  **Operators** — on a type that declares metamethods (`__add`, `__mul`,
578
704
  `__unm`, ...), an operator has the metamethod's result, tried on the left
@@ -617,8 +743,8 @@ non-nil part.
617
743
 
618
744
  Only `nil` and `false` are falsy — `0` and `""` are truthy, unlike JavaScript.
619
745
 
620
- **Types** — unions, intersections, tuples `[A, B]`, type packs `(A, B)` (the
621
- 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
622
748
  `infer`, mapped types with `as` remapping, template literal types
623
749
  (`` `on${Event}` ``), and set difference `A - B`. The utility types
624
750
  (`Partial`, `Pick`, `Omit`, `ReturnType`, `Parameters`, `Exclude`, …) are