From b97a63b34d254d8b2dbab18f4b57ee601c7cc87d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 8 Aug 2021 16:36:07 +0200 Subject: [PATCH] Move tupleReturn annotation to deprecated section --- docs/advanced/compiler-annotations.md | 388 ++------------------------ 1 file changed, 19 insertions(+), 369 deletions(-) diff --git a/docs/advanced/compiler-annotations.md b/docs/advanced/compiler-annotations.md index 4eb9b9b0..7ca8d4fb 100644 --- a/docs/advanced/compiler-annotations.md +++ b/docs/advanced/compiler-annotations.md @@ -248,42 +248,44 @@ This is annotation works the same as [@noSelf](#noself) being applied to a names `@noSelfInFile` must be placed at the top of the file, before the first statement. -## @tupleReturn +## Deprecated + +:::warning +Some annotations are deprecated and will be/have been removed. +Below are the deprecated annotations and instructions to recreate their behavior with vanilla TypeScript. +::: + +### @tupleReturn + + **Target elements:** `(declare) function` This decorator indicates a function returns a lua tuple instead of a table. It influences both destructing assignments of calls of that function, as well as changing the format of returns inside the function body. -**Example** +**Upgrade Instructions** - +Use the [`LuaMultiReturn` language extensions](language-extensions.md#luamultireturn-type) instead of a custom annotated types. This makes multi return usage type-safe and more obvious. ```typescript +/** @tupleReturn */ function myFunction(): [number, string] { return [3, "4"]; } const [a, b] = myFunction(); ``` -```lua -function myFunction() - return {3, "4"} -end -local a,b = unpack(myFunction()) -``` - - - - +Becomes: ```typescript -/** @tupleReturn */ -function myFunction(): [number, string] { - return [3, "4"]; +function myFunction(): LuaMultiReturn<[number, string]> { + return $multi(3, "4"); } const [a, b] = myFunction(); ``` +Lua output: + ```lua function myFunction() return 3, "4" @@ -291,28 +293,6 @@ end local a, b = myFunction() ``` - - -If you wish to use this annotation on function with overloads, it must be applied to each signature that requires it. - -**Example** - -```typescript -/** @tupleReturn */ -declare function myFunction(s: string): [string, string]; -/** @tupleReturn */ -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. - -## Deprecated - -:::warning -Some annotations are deprecated and will be/have been removed. -Below are the deprecated annotations and instructions to recreate their behavior with vanilla TypeScript. -::: - ### @extension @@ -322,58 +302,6 @@ Below are the deprecated annotations and instructions to recreate their behavior The Extension decorator marks a class as an extension of an already existing class. This causes the class header to not be translated, preventing instantiation and the override of the existing class. -**Default Behavior** - - - -```typescript -class MyClass { - myFunction(): void {} -} -``` - -```lua -MyClass = __TS__Class() -... -function MyClass.prototype.myFunction(self) end -``` - - - -**Example 1** - - - -```typescript -/** @extension */ -class MyClass { - myFunction(): void {} -} -``` - -```lua -function MyClass.myFunction(self) end -``` - - - -**Example 2** - - - -```typescript -/** @extension ExistingClassTable */ -class MyClass extends ExistingClass { - myFunction(): void {} -} -``` - -```lua -function ExistingClassTable.myFunction(self) end -``` - - - **Upgrade Instructions** Use an interface to extend your existing class and declare the table of the existing class as variable. @@ -407,41 +335,6 @@ function ExistingClassTable.myFunction(self) end The Extension decorator marks a class as an extension of an already existing meta class/table. This causes the class header to not be translated, preventing instantiation and the override of the existing class. -**Example** - - - -```typescript -class MyBaseClass { - myFunction(): void {} -} -``` - -```lua -MyBaseClass = __TS__Class() -... -function MyBaseClass.prototype.myFunction(self) end -``` - - - - - -```typescript -/** @metaExtension */ -class MyMetaExtension extends MyMetaClass { - myFunction(): void {} -} -``` - -```lua -local __meta__MyMetaClass = debug.getregistry().MyMetaClass -__meta__MyMetaClass.myFunction = function(self) -end; -``` - - - **Upgrade Instructions** Use an interface to extend your existing class and assign the functions to the meta table of the existing class. @@ -475,38 +368,6 @@ end This decorator marks a namespace as a phantom namespace. This means all members of the namespace will be translated as if they were not in that namespace. Primarily used to prevent scoping issues. -**Example** - - - -```typescript -namespace myNameSpace { - function myFunction(): void {} -} -``` - -```lua -myNameSpace = {} -function myNameSpace.myFunction() end -``` - - - - - -```typescript -/** @phantom */ -namespace myNameSpace { - function myFunction(): void {} -} -``` - -```lua -function myFunction() end -``` - - - **Upgrade instructions** Use ECMAScript modules and import/export. Alternatively, use a real (non-phantom) namespace. @@ -520,39 +381,6 @@ Use ECMAScript modules and import/export. Alternatively, use a real (non-phantom This decorator marks a class declaration as purely abstract. The result is that any class extending the purely abstract class will not extend this class in the resulting Lua. -**Example** - - - -```typescript -declare class MyAbstractClass {} -class MyClass extends MyAbstractClass {} -``` - -```lua -MyClass = __TS__Class() -MyClass.__base = MyAbstractClass -MyClass.____super = MyAbstractClass -setmetatable(MyClass, MyClass.____super) -setmetatable(MyClass.prototype, MyClass.____super.prototype) -``` - - - - - -```typescript -/** @pureAbstract */ -declare class MyAbstractClass {} -class MyClass extends MyAbstractClass {} -``` - -```lua -MyClass = __TS__Class() -``` - - - **Upgrade Instructions** Try declaring the "classes" of your lua enviroment as interface. @@ -583,26 +411,6 @@ Denotes a function declaration is a Lua numerical iterator. When used in a TypeS The function should not be a real function and an error will be thrown if it is used in any other way. -**Example** - - - - -```typescript -/** @forRange */ -declare function forRange(start: number, limit: number, step?: number): number[]; - -for (const i of forRange(1, 10)) {} -for (const i of forRange(10, 1, -1)) {} -``` - -```lua -for i = 1, 10 do end -for i = 10, 1, -1 do end -``` - - - **Upgrade Instructions** Use the [`$range` language extension](language-extensions.md#$range-iterator-function) instead of a custom annotated type. @@ -630,49 +438,6 @@ for i = 10, 1, -1 do end Denotes a type is a Lua iterator. When an object of a type with this annotation is used in a for...of statement, it will transpile directly as a lua iterator in a for...in statement, instead of being treated as a TypeScript iterable. Typically, this is used on an interface that extends `Iterable` or `Array` so that TypeScript will allow it to be used in a for...of statement. -**Example** - - - - -```typescript -/** @luaIterator */ -type LuaIterator = Iterable; - -declare function myIterator(): LuaIterator; -for (const s of myIterator()) {} -``` - -```lua -for s in myIterator() do end -``` - - - -This can also be combined with [@tupleReturn](#tuplereturn), if the iterator returns multiple values. - -**Example** - - - - -```typescript -/** @luaIterator @tupleReturn */ -type LuaTupleIterator = Iterable; - -declare namespace string { - function gmatch(s: string, pattern: string): LuaTupleIterator; -} - -for (const [a, b] of string.gmatch("foo", "(.)(.)")) {} -``` - -```lua -for a, b in string.gmatch("foo", "(.)(.)") do end -``` - - - **Upgrade Instructions** Use the [`LuaIterable` and `LuaMultiReturn` language extensions](language-extensions.md#luaiterable-type) instead of a custom annotated types. @@ -716,27 +481,9 @@ for a, b in string.gmatch("foo", "(.)(.)") do end This annotation signals the transpiler to translate a class as a simple lua table for optimization purposes. -```ts -/** @luaTable */ -declare class Table { - readonly length: number; - set(key: K, value: V | undefined): void; - get(key: K): V | undefined; -} - -const tbl = new Table(); // local tbl = {} - -const foo = {}; -tbl.set(foo, "bar"); // tbl[foo] = "bar" -print(tbl.get(foo)); // print(tbl[foo]) - -tbl.set(1, "baz"); // tbl[1] = "baz" -print(tbl.length); // print(#tbl) -``` - **Upgrade Instructions** -Use the built-in [`LuaTable` language extension](language-extensions.md#lua-table-types) instead of a custom annotated type. +Use the [`LuaTable` language extension](language-extensions.md#lua-table-types) instead of a custom annotated type. ```ts const tbl = new LuaTable(); // local tbl = {} @@ -757,103 +504,6 @@ print(tbl.length()); // print(#tbl) 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.