@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 +183 -37
- package/dist/index.cjs +1173 -417
- package/dist/index.d.cts +189 -68
- package/dist/index.d.ts +189 -68
- package/dist/index.js +1172 -418
- 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
|
|
|
@@ -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
|
|
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`.
|
|
407
|
-
|
|
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
|
|
538
|
+
return Box.new(f(this.value))
|
|
439
539
|
}
|
|
440
540
|
}
|
|
441
541
|
|
|
442
|
-
const n = new
|
|
443
|
-
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
|
|
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
|
|
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
|
|
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
|
-
**
|
|
477
|
-
|
|
478
|
-
|
|
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
|
|
482
|
-
|
|
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[]) =>
|
|
501
|
-
|
|
502
|
-
|
|
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
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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
|
-
**
|
|
554
|
-
|
|
555
|
-
|
|
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]
|
|
601
|
-
|
|
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
|