@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 +170 -44
- package/dist/index.cjs +1137 -426
- package/dist/index.d.cts +98 -64
- package/dist/index.d.ts +98 -64
- package/dist/index.js +1136 -427
- package/package.json +1 -1
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`** —
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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 (
|
|
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
|
|
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`.
|
|
419
|
-
|
|
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
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
|
538
|
+
return Box.new(f(this.value))
|
|
459
539
|
}
|
|
460
540
|
}
|
|
461
541
|
|
|
462
|
-
const n = new
|
|
463
|
-
const s = new
|
|
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
|
|
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
|
|
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
|
-
**
|
|
497
|
-
|
|
498
|
-
|
|
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
|
|
502
|
-
|
|
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[]) =>
|
|
521
|
-
|
|
522
|
-
|
|
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
|
-
|
|
525
|
-
|
|
526
|
-
|
|
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
|
-
**
|
|
574
|
-
|
|
575
|
-
|
|
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]
|
|
621
|
-
|
|
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
|