From e7c01c1762b5567119c63d2be33e347ec18e8d7d Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 6 Mar 2021 08:00:02 -0700 Subject: [PATCH 1/2] deprectaed @vararg annotation and added $vararg constant extension --- docs/advanced/compiler-annotations.md | 251 +++++++++++++++----------- docs/advanced/language-extensions.md | 34 ++++ 2 files changed, 182 insertions(+), 103 deletions(-) diff --git a/docs/advanced/compiler-annotations.md b/docs/advanced/compiler-annotations.md index f3b923bb..f9346d90 100644 --- a/docs/advanced/compiler-annotations.md +++ b/docs/advanced/compiler-annotations.md @@ -306,109 +306,6 @@ declare function myFunction(n: number): [number, number]; Note that if any overloaded signature of a function implementation has the annotation, all array/tuple return values will unpacked in the transpiled output. -## @vararg - -**Target elements:** `(declare) interface or type` - -Indicates that an array-like type represents a Lua vararg expression (`...`) and should be transpiled to that when used in a spread expression. This is useful for forwarding varargs instead of wrapping them in a table and unpacking them. - -**Example** - - - -```typescript -function varargWrapUnpack(...args: string[]) { - console.log(...args); -} -``` - -```lua -function varargWrapUnpack(self, ...) - local args = ({...}) - print(unpack(args)) -end -``` - - - - - -```typescript -/** @vararg */ -interface Vararg extends Array {} - -function varargForward(...args: Vararg) { - console.log(...args); -} -``` - -```lua -function varargForward(self, ...) - print(...)) -end -``` - - - -This can be used to access the file-scope varargs as well. - -**Example** - - - -```typescript -declare const arg: Vararg; -console.log(...arg); -const [x, y] = [...arg]; -``` - -```lua -print(...) -local x, y = ... -``` - - - -To also support tuple-typed rest parameters, you can define the type like this: - -**Example** - -```typescript -/** @vararg */ -type Vararg = T & { __luaVararg?: never }; - -function varargForward(...args: Vararg<[string, number]>) {} -``` - -**_Warning_** - -TypeScriptToLua does not check that the vararg expression is valid in the context it is used. If the array is used in a spread operation in an invalid context (such as a nested function), a deoptimization will occur. - -**Example** - - - -```typescript -function outerFunction(...args: Vararg) { - function innerFunction() { - console.log(...args); - } - innerFunction(); -} -``` - -```lua -function outerFunction(self, ...) - local args = {...} - local function innerFunction(self) - print(unpack(args)) - end - innerFunction(_G) -end -``` - - - ## Deprecated :::warning @@ -851,3 +748,151 @@ print(tbl.get(foo)); // print(tbl[foo]) tbl.set(1, "baz"); // tbl[1] = "baz" print(tbl.length()); // print(#tbl) ``` + +### @vararg + +**Target elements:** `(declare) interface or type` + +Indicates that an array-like type represents a Lua vararg expression (`...`) and should be transpiled to that when used in a spread expression. This is useful for forwarding varargs instead of wrapping them in a table and unpacking them. + +**Example** + + + +```typescript +function varargWrapUnpack(...args: string[]) { + console.log(...args); +} +``` + +```lua +function varargWrapUnpack(self, ...) + local args = ({...}) + print(unpack(args)) +end +``` + + + + + +```typescript +/** @vararg */ +interface Vararg extends Array {} + +function varargForward(...args: Vararg) { + console.log(...args); +} +``` + +```lua +function varargForward(self, ...) + print(...)) +end +``` + + + +This can be used to access the file-scope varargs as well. + +**Example** + + + +```typescript +declare const arg: Vararg; +console.log(...arg); +const [x, y] = [...arg]; +``` + +```lua +print(...) +local x, y = ... +``` + + + +To also support tuple-typed rest parameters, you can define the type like this: + +**Example** + +```typescript +/** @vararg */ +type Vararg = T & { __luaVararg?: never }; + +function varargForward(...args: Vararg<[string, number]>) {} +``` + +**_Warning_** + +TypeScriptToLua does not check that the vararg expression is valid in the context it is used. If the array is used in a spread operation in an invalid context (such as a nested function), a deoptimization will occur. + +**Example** + + + +```typescript +function outerFunction(...args: Vararg) { + function innerFunction() { + console.log(...args); + } + innerFunction(); +} +``` + +```lua +function outerFunction(self, ...) + local args = {...} + local function innerFunction(self) + print(unpack(args)) + end + innerFunction(_G) +end +``` + + + +**Upgrade Instructions** + +`@vararg` is no longer required to prevent vararg parameters from being wrapped in a table. The ellipsis operator will now automatically be used if the parameter is used in a spread expression. + +Example: + + + +```ts +function varargForward(...args: string[]) { + console.log(...args); +} +``` + +```lua +function varargForward(...) + print(...) +end +``` + + + +However, if the parameter is accessed as an array or tuple, it will be wrapped in a table. + +Example: + + + +```ts +function varargAccess(...args: string[]) { + console.log(args[0]); +} +``` + +```lua +function varargAccess(...) + local args = {...} + print(args[1]) +end +``` + + + +Note that are a few cases where the parameter will still be wrapped in a table, even if a spread expression is used, in order to generate correctly functioning Lua. diff --git a/docs/advanced/language-extensions.md b/docs/advanced/language-extensions.md index 68c084a2..3f4e9aea 100644 --- a/docs/advanced/language-extensions.md +++ b/docs/advanced/language-extensions.md @@ -321,3 +321,37 @@ declare namespace IdDictionary { IdDictionary.set(dict, id, "bar"); console.log(IdDictionary.get(dict, id)); ``` + +## $vararg Constant + +Lua allows use of the ellipsis operator (`...`) to access command line arguments passed when executing a script file. To access this from Typescript, you can use the `$vararg` constant in a spread expression. + +Example: + + + +```ts +console.log(...$vararg); +``` + +```lua +print(...) +``` + + + +When run: + + + +``` +> lua myscript.lua foo bar +``` + +``` +foo bar +``` + + + +Use of `$vararg` is only allowed at file scope, and only in a spread expression (`...$vararg`). From ceb2a8a2632075e6c7d3bf5c37e51b5ce876a6ff Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 6 Mar 2021 10:51:50 -0700 Subject: [PATCH 2/2] added DeprecatedInVersion tag to @vararg annotation --- docs/advanced/compiler-annotations.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/advanced/compiler-annotations.md b/docs/advanced/compiler-annotations.md index f9346d90..80dbfcb8 100644 --- a/docs/advanced/compiler-annotations.md +++ b/docs/advanced/compiler-annotations.md @@ -751,6 +751,8 @@ print(tbl.length()); // print(#tbl) ### @vararg + + **Target elements:** `(declare) interface or type` Indicates that an array-like type represents a Lua vararg expression (`...`) and should be transpiled to that when used in a spread expression. This is useful for forwarding varargs instead of wrapping them in a table and unpacking them.