@tilua/parser 1.1.0 → 2.1.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 +186 -47
- package/dist/index.cjs +1405 -455
- package/dist/index.d.cts +107 -64
- package/dist/index.d.ts +107 -64
- package/dist/index.js +1404 -456
- 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
|
|
|
@@ -337,9 +341,11 @@ name: T | nil -- must be written, but may be nil
|
|
|
337
341
|
Omitting an argument requires `?` (or a default), as in TypeScript — a
|
|
338
342
|
parameter typed `T | nil` still has to be passed something.
|
|
339
343
|
|
|
340
|
-
**Optional chaining** — `a?.b` and `a?:m(x)` are nil when
|
|
341
|
-
nothing further along the chain runs, arguments
|
|
342
|
-
is a `string | nil
|
|
344
|
+
**Optional chaining** — `a?.b`, `a?.[k]`, `a?.(x)` and `a?:m(x)` are nil when
|
|
345
|
+
`a` is, and then nothing further along the chain runs, arguments and the key
|
|
346
|
+
included: `folder?:FindFirstChild("A")?.Name` is a `string | nil`, and
|
|
347
|
+
`maps?.[key]?.label` reads the key only when `maps` is there. The `?` must
|
|
348
|
+
touch the `.` or `:`; `c ? a : b` stays a
|
|
343
349
|
ternary. Parentheses end a chain. A chain cannot be assigned to (`a?.b = 1` is
|
|
344
350
|
an error). A chain that got through narrows what it tested: inside
|
|
345
351
|
`if (part?.Parent)`, and `if (part?.Name == "Door")`, `part` is not nil.
|
|
@@ -407,7 +413,7 @@ class Dog extends Animal {
|
|
|
407
413
|
}
|
|
408
414
|
}
|
|
409
415
|
|
|
410
|
-
const rex = new
|
|
416
|
+
const rex = Dog.new("Rex", "shiba")
|
|
411
417
|
rex:speak() -- the receiver is `this`
|
|
412
418
|
rex.label = "Max" -- the setter
|
|
413
419
|
Dog.made() -- a static, inherited from Animal
|
|
@@ -415,22 +421,98 @@ Dog.made() -- a static, inherited from Animal
|
|
|
415
421
|
|
|
416
422
|
The receiver is written `this`, and it is an ordinary first parameter: a
|
|
417
423
|
method's type is `(this: Dog, ...) => R`, so `rex:speak()` supplies it the way
|
|
418
|
-
`function T:m()` supplies `self`.
|
|
419
|
-
|
|
424
|
+
`function T:m()` supplies `self`. An instance is built the way Luau builds
|
|
425
|
+
one, with the class's own function: `Dog.new(x)` — callable like any other,
|
|
426
|
+
and passable as a value. There is no `new Dog(x)`; writing it is a syntax
|
|
427
|
+
error that says so.
|
|
428
|
+
|
|
429
|
+
**`public`, `private` and `protected`** go before a member — `private
|
|
430
|
+
balance = 0`, `private static function check()`, `public get size()`. Leaving
|
|
431
|
+
it out means public. A private member can be reached only inside the body of
|
|
432
|
+
the class that declared it, including functions nested in its methods; a
|
|
433
|
+
subclass is outside, as in TypeScript. A protected one is reachable from the
|
|
434
|
+
classes extending it too. It is a type check and nothing more: the member is
|
|
435
|
+
an ordinary key at runtime.
|
|
436
|
+
|
|
437
|
+
**`readonly`** fields are assigned where they are declared or in the
|
|
438
|
+
constructor of their own class, and nowhere else: `readonly id: number`.
|
|
439
|
+
|
|
440
|
+
The modifiers can come in any order — `static private readonly count = 0` —
|
|
441
|
+
and each stays an ordinary name where no member follows it, so
|
|
442
|
+
`private: boolean` and `readonly = 1` are still fields.
|
|
443
|
+
|
|
444
|
+
**`abstract`** — an `abstract class` has no `new`: it is built only as part of
|
|
445
|
+
a class extending it. It may declare `abstract function area(): number`, a
|
|
446
|
+
head with no body, and a class extending it that is not abstract itself has to
|
|
447
|
+
write every such member. Calling an abstract method through `super` is an
|
|
448
|
+
error, as is `Shape.new`.
|
|
449
|
+
|
|
450
|
+
**`override`** says a member replaces one of the class it extends, and is an
|
|
451
|
+
error on a member that does not. Whether or not it is written, a member that
|
|
452
|
+
replaces one has to fit it: its type, `this` aside, is checked against the
|
|
453
|
+
base's.
|
|
454
|
+
|
|
455
|
+
**`implements`** — `class Person implements Named, Greeter` checks that the
|
|
456
|
+
instances have every member each shape names, of a type that fits. Nothing
|
|
457
|
+
happens at runtime.
|
|
420
458
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
459
|
+
```luau
|
|
460
|
+
abstract class Shape implements Named {
|
|
461
|
+
readonly name: string
|
|
462
|
+
protected sides = 0
|
|
463
|
+
constructor(name: string) {
|
|
464
|
+
this.name = name
|
|
465
|
+
}
|
|
466
|
+
abstract function area(): number
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
class Square extends Shape {
|
|
470
|
+
side = 1
|
|
471
|
+
constructor() {
|
|
472
|
+
super("square")
|
|
473
|
+
this.sides = 4 -- protected: reachable from here
|
|
474
|
+
}
|
|
475
|
+
override function area(): number {
|
|
476
|
+
return this.side * this.side
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**Metamethods** are methods with their Luau names. The class table *is* its
|
|
482
|
+
instances' metatable, so `function __add(other: Vec): Vec` in a class is the
|
|
483
|
+
`+` of its instances — and the type checker reads it the same way: `a + b`
|
|
484
|
+
between two `Vec`s is a `Vec`. `__sub`, `__mul`, `__div`, `__idiv`, `__mod`,
|
|
485
|
+
`__pow`, `__unm`, `__concat`, `__len` (`#v`), `__eq`, `__lt` and `__le` (`<`,
|
|
486
|
+
`>`, `<=`, `>=`), `__call` (calling an instance), `__iter` (`for a, b in v`)
|
|
487
|
+
and `__tostring` all work this way, and a class extending another inherits
|
|
488
|
+
them. Each is checked: it takes the operands Luau hands it, returns what Luau
|
|
489
|
+
expects of it (`__tostring` a string, `__eq`/`__lt`/`__le` a boolean), and is
|
|
490
|
+
not `static`. Comparing two instances whose class has no `__lt` is an error,
|
|
491
|
+
as it is at runtime.
|
|
492
|
+
|
|
493
|
+
```luau
|
|
494
|
+
class Vec {
|
|
495
|
+
x: number
|
|
496
|
+
constructor(x: number) {
|
|
497
|
+
this.x = x
|
|
498
|
+
}
|
|
499
|
+
function __add(other: Vec): Vec {
|
|
500
|
+
return Vec.new(this.x + other.x)
|
|
501
|
+
}
|
|
502
|
+
function __tostring(): string {
|
|
503
|
+
return `Vec(${this.x})`
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const v = Vec.new(1) + Vec.new(2) -- Vec
|
|
508
|
+
print(tostring(v)) -- Vec(3)
|
|
509
|
+
```
|
|
428
510
|
|
|
429
511
|
A declaration names two things. As a **type**, `Dog` is the type of its
|
|
430
512
|
instances, nominal the same way a `declare class` is: a table with the same
|
|
431
513
|
members is not one, and only `Dog` and what extends it are assignable to it.
|
|
432
514
|
As a **value**, `Dog` is the class table — its statics, and the `new` that
|
|
433
|
-
builds an instance. `export class` exports both.
|
|
515
|
+
builds an instance (`Dog.new(...)`). `export class` exports both.
|
|
434
516
|
|
|
435
517
|
Two links are always there, and they are what the memory model promises:
|
|
436
518
|
|
|
@@ -455,12 +537,12 @@ class Box<T> {
|
|
|
455
537
|
return this.value
|
|
456
538
|
}
|
|
457
539
|
function map<R>(f: (value: T) => R): Box<R> {
|
|
458
|
-
return new
|
|
540
|
+
return Box.new(f(this.value))
|
|
459
541
|
}
|
|
460
542
|
}
|
|
461
543
|
|
|
462
|
-
const n = new
|
|
463
|
-
const s = new
|
|
544
|
+
const n = Box.new(1) -- Box<number>, read off the argument
|
|
545
|
+
const s = Box.new<string>("a") -- or written out
|
|
464
546
|
const held: number = n:get()
|
|
465
547
|
|
|
466
548
|
class Ints extends Box<number> { -- extending one fixes its argument
|
|
@@ -482,24 +564,65 @@ it, as TypeScript's does, and importing it brings in the type too:
|
|
|
482
564
|
|
|
483
565
|
```luau
|
|
484
566
|
import Box from "./box" -- `Box` is the class *and* the type
|
|
485
|
-
const held: Box<number> = new
|
|
567
|
+
const held: Box<number> = Box.new(1)
|
|
486
568
|
```
|
|
487
569
|
|
|
488
570
|
Reported: a field with a type that nothing gives a value (`name: string` that
|
|
489
|
-
the constructor
|
|
571
|
+
the constructor does not assign on every way through it — both arms of an
|
|
572
|
+
`if`, not in a loop or a function written inside), a derived constructor that does not call
|
|
490
573
|
`super(...)`, `extends` naming something that is not a class, a chain that
|
|
491
574
|
closes on itself, a member written twice, and a member named one of the words
|
|
492
575
|
the compiler builds the class table out of (`new`, `ClassObject`,
|
|
493
576
|
`ParentClass`, `__init`, `__index`, `__newindex`, `__getters`, `__setters`,
|
|
494
577
|
`__dynamic`).
|
|
495
578
|
|
|
496
|
-
**
|
|
497
|
-
|
|
498
|
-
|
|
579
|
+
**One value, and arrays** — tilua has no packs. A function returns one value;
|
|
580
|
+
several are an array, and a tuple type says how many and of what:
|
|
581
|
+
|
|
582
|
+
```luau
|
|
583
|
+
function divide(a: number, b: number): [number, number] {
|
|
584
|
+
return [a // b, a % b]
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
const [quotient, remainder] = divide(7, 2) -- taken apart
|
|
588
|
+
const both = divide(7, 2) -- or kept: [number, number]
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
An array is a table, at runtime as much as in the types: `return [a, b]` is
|
|
592
|
+
`return { a, b }`. Where Luau answers several values — `pcall`, `string.find`,
|
|
593
|
+
a Roblox method such as `FindPartOnRay` — the type library puts a function of
|
|
594
|
+
its own in place of that global or method, which answers one value, as its
|
|
595
|
+
type says. A tuple may end in a rest,
|
|
596
|
+
`[string, ...number[]]`: that many, then any number more. `const a, b = 1, 2`
|
|
597
|
+
still pairs names with values one each; `const a, b = f()` is a name short,
|
|
598
|
+
and says to write `const [a, b] = f()`.
|
|
599
|
+
|
|
600
|
+
**A loop takes one value too** — `for (const item in source)`, and several are
|
|
601
|
+
an array the pattern takes apart:
|
|
602
|
+
|
|
603
|
+
```luau
|
|
604
|
+
for (const name in names) { print(name) }
|
|
605
|
+
for (const [i, name] in ipairs(names)) { print(i, name) }
|
|
606
|
+
for (const [key, score] in pairs(scores)) { print(key, score) }
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
The name is `const`, or `let` where the body assigns to it, as anywhere else.
|
|
610
|
+
A source is an array or a table, walked for its values; an iterator function,
|
|
611
|
+
called until it answers `nil`; or an iteration — `[step, state, first]`, what
|
|
612
|
+
`pairs(t)` answers — whose `step` is called with the state and the item before
|
|
613
|
+
it. An object says how it is walked with `__iter`, which answers one of those
|
|
614
|
+
two. `for (k, v in ...)` and `for (x in f, s, v)` are Luau's packs, and are
|
|
615
|
+
syntax errors.
|
|
616
|
+
|
|
617
|
+
A function that returns nothing returns `nil`: `() => nil`, not `() => ()`.
|
|
618
|
+
Bare `...` is gone — a
|
|
619
|
+
function takes a rest parameter, and what the script was started with is
|
|
620
|
+
`scriptArgs: unknown[]`. `()`, `(A, B)` as a type, `T...`, `...: T` and
|
|
621
|
+
`return a, b` are syntax errors that say what to write instead.
|
|
499
622
|
|
|
500
623
|
**Rest parameters** — `...name: T[]` is JavaScript's: every argument from that
|
|
501
|
-
position on, as an array. It is last, and the
|
|
502
|
-
|
|
624
|
+
position on, as an array. It is last, and it is the one way a function takes a
|
|
625
|
+
varying number of arguments.
|
|
503
626
|
|
|
504
627
|
```luau
|
|
505
628
|
function join(separator: string, ...parts: string[]): string {
|
|
@@ -517,24 +640,28 @@ firstOf(1, 2) -- number | nil: the arguments say what `T` is
|
|
|
517
640
|
```
|
|
518
641
|
|
|
519
642
|
A type is written the same way: `type Reporter = (level: string, ...lines:
|
|
520
|
-
string[]) =>
|
|
521
|
-
|
|
522
|
-
|
|
643
|
+
string[]) => nil`. Without an annotation a rest parameter is `unknown[]`. A rest
|
|
644
|
+
parameter may also be a tuple, or a type parameter standing for one — then the
|
|
645
|
+
arguments are exactly its elements, which is how a function says it forwards
|
|
646
|
+
another's:
|
|
523
647
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
648
|
+
```luau
|
|
649
|
+
declare function spawn<A extends unknown[]>(f: (...args: A) => nil, ...args: A): thread
|
|
650
|
+
|
|
651
|
+
spawn(function(n: number) { print(n) }, 1) -- ok
|
|
652
|
+
spawn(function(n: number) { print(n) }, "no") -- '"no"' is not a number
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
**Spreads** — `...xs` puts what an array holds into a call's arguments or an
|
|
656
|
+
array literal, as JavaScript does. A list of values — a declaration's, an
|
|
657
|
+
assignment's — takes one value per name; take an array apart with a
|
|
658
|
+
destructuring instead.
|
|
527
659
|
|
|
528
660
|
```luau
|
|
529
661
|
join("-", ...names) -- every name
|
|
530
662
|
join("-", ...names, "z") -- and one more after them
|
|
531
663
|
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
|
|
664
|
+
const both = [...names, "z"]
|
|
538
665
|
```
|
|
539
666
|
|
|
540
667
|
What the array holds is checked against what it fills. How many it holds is
|
|
@@ -570,9 +697,10 @@ its parameter types from it: in `signal:Connect(player => ... )`,
|
|
|
570
697
|
`player` is typed from `Connect`. The same applies to an annotated `const`
|
|
571
698
|
and to an assignment such as `remote.OnServerInvoke = function(player) { ... }`.
|
|
572
699
|
|
|
573
|
-
**
|
|
574
|
-
|
|
575
|
-
|
|
700
|
+
**Signals and other variadic generics** — a type parameter can stand for a
|
|
701
|
+
list of arguments: `type Signal<T extends unknown[] = any[]> = { Connect:
|
|
702
|
+
(self, cb: (...args: T) => nil) => Connection }`, given as a tuple —
|
|
703
|
+
`Signal<[Player, string]>`, `Signal<[]>` for none.
|
|
576
704
|
|
|
577
705
|
**Operators** — on a type that declares metamethods (`__add`, `__mul`,
|
|
578
706
|
`__unm`, ...), an operator has the metamethod's result, tried on the left
|
|
@@ -617,8 +745,19 @@ non-nil part.
|
|
|
617
745
|
|
|
618
746
|
Only `nil` and `false` are falsy — `0` and `""` are truthy, unlike JavaScript.
|
|
619
747
|
|
|
620
|
-
**
|
|
621
|
-
|
|
748
|
+
**What Luau raises on is said first.** An operator no metamethod answers takes
|
|
749
|
+
numbers — `..` a string or a number, `#` a string or a table — so `n * 2` with
|
|
750
|
+
`n` a `number | nil` is an error where it is written rather than where it runs.
|
|
751
|
+
A comparison two types can never settle (`s == "c"` with `s` a `"a" | "b"`) is
|
|
752
|
+
one too; a test against `nil` never is, since a map's value and an array's
|
|
753
|
+
element are read as what they hold. A name holds nothing until its line has
|
|
754
|
+
run, a list is indexed by position (`xs["a"]` is not a read), `readonly T[]`
|
|
755
|
+
rules out writing to the list as well as passing it where a `number[]` is
|
|
756
|
+
wanted, a key written twice in one table is reported, and a parameter with no
|
|
757
|
+
type says so — it is `any`, and `any` turns off every check made of it.
|
|
758
|
+
|
|
759
|
+
**Types** — unions, intersections, tuples `[A, B]` (with a rest, `[A,
|
|
760
|
+
...B[]]`), `keyof`, `T[K]`, conditional types with
|
|
622
761
|
`infer`, mapped types with `as` remapping, template literal types
|
|
623
762
|
(`` `on${Event}` ``), and set difference `A - B`. The utility types
|
|
624
763
|
(`Partial`, `Pick`, `Omit`, `ReturnType`, `Parameters`, `Exclude`, …) are
|