From a60a402c8d53e5010875aaf8fc44abd3ea22066a Mon Sep 17 00:00:00 2001 From: imlodinu Date: Mon, 21 Apr 2025 13:48:19 +0800 Subject: [PATCH 1/5] RFC: Formalize declaration syntax --- docs/syntax-declaration.md | 82 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 docs/syntax-declaration.md diff --git a/docs/syntax-declaration.md b/docs/syntax-declaration.md new file mode 100644 index 0000000..0e06955 --- /dev/null +++ b/docs/syntax-declaration.md @@ -0,0 +1,82 @@ +# Declaration syntax + +## Summary + +Formalizing the luau declaration syntax used in the luau parser. + +## Motivation + +RIght now the declaration syntax used by the luau parser is undocumented and an unstable implementation detail. By defining the syntax, it allows for embedders of luau to have typechecking for their apis without having to resort to empty modules. This should allow tools like luau-lsp to be able to provide easier ways to use these declarations. + +## Design + +Declaration syntax should only be usable in definition files. Definition files + +The declaration syntax mirrors the current syntax used by the luau parser. All declarations are prefixed with `declare`, and global variables, global functions, and classes are able to be declared. + +## Global variables +After `declare`, an identifier representing the name of the global variable is expected, followed by a colon and a type. +For example: + +```luau +declare myglobal: number +declare anotherglobal: { + add: (number, number) -> number, + sub: (number, number) -> number, +} +``` + +## Global functions +Global functions can have the attributes which comes before declare. After `declare`, the `function` keyword is expected, followed by an identifier representing the name of the global function, optional generic type list, binding list, and finally. The body of the function is omitted. + +Every parameter must be annotated with a type and if there is a vararg, it also must be annotated with a type. The return type is optional, but if it is not specified, the function will be treated as returning `nil`. + +For example: + +```luau +declare function warn(...: T...) +declare function wait(seconds: number?): (number, number) +declare function delay(delayTime: number?, callback: (T...) -> ()) +``` + +## Classes +After `declare`, `class` is expected, followed by an identifier representing the name of the class. If the class inherits from another class, `extends` is expected, followed by the name of the class to inherit from. + +Class properties and methods are now expected. + +To declare a property, it can be specified with `["identifier"]`, `[ [[identifier]] ]`, or `identifier` followed by a colon and a type. + +To declare an indexer, a type is used within `[` and `]` followed by a colon and a type. More than one class indexer is invalid. + +To declare a method, the `function` keyword is expected followed by an identifier for the function name, binding list with varargs allowed, and an optional return type preceded by a colon. + +There must always be at least one parameter in the binding list, and the first parameter in the binding list must be called `self` and have no type annotation. The rest of the parameters must be annotated with a type, and if there is a vararg, it also must be annotated with a type. + +The class is closed with the `end` keyword. + +Example: +```luau +declare class MyClass extends BaseClass + -- properties + ["Property1"]: number, + [ [[Propery2]] ]: string, + -- note this is not a method + Property3: (number, number) -> number, + -- indexer + [number | string]: string, + -- methods + function Method1(self, a: number, b: string): (number, string) + function Clone(self): MyClass + function Empty(self) +end +``` + +More examples can found in [luau-lsp's globalTypes.d.luau](https://github.com/JohnnyMorganz/luau-lsp/blob/main/scripts/globalTypes.d.luau) and [luau's parser tests](https://github.com/luau-lang/luau/blob/master/tests/Parser.test.cpp#L1908) + +## Drawbacks + +A drawback would be that this is an unstable implementation detail, which allows for the parser to freely change the syntax without worry for backwards compatibility. By formalizing the syntax, it would mean more consideration would be needed when changing how declarations are parsed in the future. + +## Alternatives + +THe alternative to this is to leave this as an implementation detail. However this makes it inconvenient for embedders of luau to use the declaration syntax. \ No newline at end of file From 7e4337b006bd0e01546cbb6ea4e31c0da5981a2c Mon Sep 17 00:00:00 2001 From: imlodinu Date: Mon, 21 Apr 2025 13:51:53 +0800 Subject: [PATCH 2/5] fix small typo --- docs/syntax-declaration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/syntax-declaration.md b/docs/syntax-declaration.md index 0e06955..fa0896b 100644 --- a/docs/syntax-declaration.md +++ b/docs/syntax-declaration.md @@ -79,4 +79,4 @@ A drawback would be that this is an unstable implementation detail, which allows ## Alternatives -THe alternative to this is to leave this as an implementation detail. However this makes it inconvenient for embedders of luau to use the declaration syntax. \ No newline at end of file +The alternative to this is to leave this as an implementation detail. However this makes it inconvenient for embedders of luau to use the declaration syntax. \ No newline at end of file From b29cdd910bd0cd3e71cd0f0f166ba30b469774d7 Mon Sep 17 00:00:00 2001 From: imlodinu Date: Mon, 21 Apr 2025 13:54:00 +0800 Subject: [PATCH 3/5] fix missing line --- docs/syntax-declaration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/syntax-declaration.md b/docs/syntax-declaration.md index fa0896b..21b0fbc 100644 --- a/docs/syntax-declaration.md +++ b/docs/syntax-declaration.md @@ -10,7 +10,7 @@ RIght now the declaration syntax used by the luau parser is undocumented and an ## Design -Declaration syntax should only be usable in definition files. Definition files +Declaration syntax should only be usable in definition files. Definition files have the extension of `.d.luau` and are used to provide type information for modules. They should not be allowed to do anything beyond declaring type aliases and declarations. The declaration syntax mirrors the current syntax used by the luau parser. All declarations are prefixed with `declare`, and global variables, global functions, and classes are able to be declared. From f1898bffcd896059da78e9f96158c604a6337ee4 Mon Sep 17 00:00:00 2001 From: imlodinu Date: Mon, 21 Apr 2025 15:12:34 +0800 Subject: [PATCH 4/5] fix small syntax error in class example and clarify that classes are nominal types --- docs/syntax-declaration.md | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/docs/syntax-declaration.md b/docs/syntax-declaration.md index 21b0fbc..1d264e4 100644 --- a/docs/syntax-declaration.md +++ b/docs/syntax-declaration.md @@ -40,6 +40,29 @@ declare function delay(delayTime: number?, callback: (T...) -> ()) ``` ## Classes +Classes are nominally typed, meaning that the class name is used to identify the class. Even with the same shape, two classes with different names are not interchangeable. This is different from the structural typing used in luau, where two objects with the same shape are interchangeable. +For example: + +```luau +-- assuming A is a class +declare class B extends A + x: number + y: number +end + +declare class C extends A + x: number + y: number +end +``` + +So in another file, this is invalid: +```luau +local a: B = -- some value +local b: C = -- some value +a = b -- this is a type error +``` + After `declare`, `class` is expected, followed by an identifier representing the name of the class. If the class inherits from another class, `extends` is expected, followed by the name of the class to inherit from. Class properties and methods are now expected. @@ -58,12 +81,12 @@ Example: ```luau declare class MyClass extends BaseClass -- properties - ["Property1"]: number, - [ [[Propery2]] ]: string, + ["Property1"]: number + [ [[Propery2]] ]: string -- note this is not a method - Property3: (number, number) -> number, + Property3: (number, number) -> number -- indexer - [number | string]: string, + [number | string]: string -- methods function Method1(self, a: number, b: string): (number, string) function Clone(self): MyClass From eb6cd4874d5206857d4a6c0be04b716a53049178 Mon Sep 17 00:00:00 2001 From: imlodinu Date: Mon, 21 Apr 2025 16:25:59 +0800 Subject: [PATCH 5/5] capitalise Luau --- docs/syntax-declaration.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/syntax-declaration.md b/docs/syntax-declaration.md index 1d264e4..53912e2 100644 --- a/docs/syntax-declaration.md +++ b/docs/syntax-declaration.md @@ -2,17 +2,17 @@ ## Summary -Formalizing the luau declaration syntax used in the luau parser. +Formalizing the Luau declaration syntax used in the Luau parser. ## Motivation -RIght now the declaration syntax used by the luau parser is undocumented and an unstable implementation detail. By defining the syntax, it allows for embedders of luau to have typechecking for their apis without having to resort to empty modules. This should allow tools like luau-lsp to be able to provide easier ways to use these declarations. +RIght now the declaration syntax used by the Luau parser is undocumented and an unstable implementation detail. By defining the syntax, it allows for embedders of Luau to have typechecking for their apis without having to resort to empty modules. This should allow tools like luau-lsp to be able to provide easier ways to use these declarations. ## Design Declaration syntax should only be usable in definition files. Definition files have the extension of `.d.luau` and are used to provide type information for modules. They should not be allowed to do anything beyond declaring type aliases and declarations. -The declaration syntax mirrors the current syntax used by the luau parser. All declarations are prefixed with `declare`, and global variables, global functions, and classes are able to be declared. +The declaration syntax mirrors the current syntax used by the Luau parser. All declarations are prefixed with `declare`, and global variables, global functions, and classes are able to be declared. ## Global variables After `declare`, an identifier representing the name of the global variable is expected, followed by a colon and a type. @@ -40,7 +40,7 @@ declare function delay(delayTime: number?, callback: (T...) -> ()) ``` ## Classes -Classes are nominally typed, meaning that the class name is used to identify the class. Even with the same shape, two classes with different names are not interchangeable. This is different from the structural typing used in luau, where two objects with the same shape are interchangeable. +Classes are nominally typed, meaning that the class name is used to identify the class. Even with the same shape, two classes with different names are not interchangeable. This is different from the structural typing used in Luau, where two objects with the same shape are interchangeable. For example: ```luau @@ -94,7 +94,7 @@ declare class MyClass extends BaseClass end ``` -More examples can found in [luau-lsp's globalTypes.d.luau](https://github.com/JohnnyMorganz/luau-lsp/blob/main/scripts/globalTypes.d.luau) and [luau's parser tests](https://github.com/luau-lang/luau/blob/master/tests/Parser.test.cpp#L1908) +More examples can found in [luau-lsp's globalTypes.d.luau](https://github.com/JohnnyMorganz/luau-lsp/blob/main/scripts/globalTypes.d.luau) and [Luau's parser tests](https://github.com/luau-lang/luau/blob/master/tests/Parser.test.cpp#L1908) ## Drawbacks @@ -102,4 +102,4 @@ A drawback would be that this is an unstable implementation detail, which allows ## Alternatives -The alternative to this is to leave this as an implementation detail. However this makes it inconvenient for embedders of luau to use the declaration syntax. \ No newline at end of file +The alternative to this is to leave this as an implementation detail. However this makes it inconvenient for embedders of Luau to use the declaration syntax. \ No newline at end of file