-
Notifications
You must be signed in to change notification settings - Fork 56
Intersection Type #1603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Intersection Type #1603
Changes from 20 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
0d9745e
wip
markwpearce 4849aad
Merge branch 'v1' into intersection_type
markwpearce a742506
Merge branch 'v1' into intersection_type
markwpearce 8fde59b
Added IntersectionType tests
markwpearce 48ac3f0
Added support for grouped type expressions
markwpearce a602261
Merge branch 'v1' into intersection_type
markwpearce 723b945
Adding tests for member types of intersection types in scope contexts
markwpearce e202859
Adds code to handle order of operations when building types
markwpearce 02ba2bb
Adds code to handle order of operations when building types
markwpearce 29022b7
removed log statments, started adding validation tests
markwpearce 6a73946
remove .only
markwpearce e49662b
Better handling of errors - missing right paren on function declratio…
markwpearce 8f72d55
fix lint error
markwpearce e7a8074
Adds more validation and compatibility tests for intersections:
markwpearce 9305d48
Adds new reference type for intersections with types with default dyn…
markwpearce a7c0f7b
Added comment
markwpearce b288f8a
Added docs
markwpearce 7836adf
Added completion tests
markwpearce bbd1bec
Renamed 'ComplexType' -> 'CompoundType'
markwpearce 492e7ad
More tests for Intersections with order of operations and callfuncs
markwpearce 5e648aa
Merge branch 'v1' into intersection_type
markwpearce d277935
Merge branch 'v1' into intersection_type
TwitchBronBron 92a7755
Update docs/intersection-types.md
markwpearce e129f4b
Changed Name IntersectionWithDefaultDynamicReferenceType -> Reference…
markwpearce db1138c
added more comments to ReferenceTypeWithDefault
markwpearce File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # Intersection Types | ||
|
|
||
| BrighterScript Intersection Types are a way to define a type that combines the members of multiple types. They are similar to Intersection Types found in other languages, such as [TypeScript](https://www.typescriptlang.org/docs/handbook/2/objects.html#intersection-types). | ||
|
|
||
| ## Syntax | ||
|
|
||
| Intersection types can be declared with the following syntax: `<type> and <type>`. For example, the parameter to the function below could be meets both the interfaces HasId and HasUrl: | ||
|
|
||
| ```BrighterScript | ||
| interface HasId | ||
| id as string | ||
| end interface | ||
|
|
||
| interface HasUrl | ||
| url as string | ||
| end interface | ||
|
|
||
| function getUrlWithQueryId(value as HasId and HasUrl) as string | ||
| return value.url + "?id=" + value.id | ||
| end function | ||
| ``` | ||
|
|
||
| Any number of inner types, including classes or interfaces, could be part of an intersection: | ||
|
|
||
| ```BrighterScript | ||
| interface HasId | ||
| id as string | ||
| end interface | ||
|
|
||
| interface HasUrl | ||
| url as string | ||
| end interface | ||
|
|
||
| interface HasSize | ||
| width as integer | ||
| height as integer | ||
| end interface | ||
|
|
||
|
|
||
| function getUrlWithQuerySize(response as HasId and HasUrl and HasSize) as string | ||
| return value.url + "?id=" + value.id + "&w=" + value.width.toStr().trim() + "&h=" + value.height.toStr().trim() | ||
| end function | ||
| ``` | ||
|
|
||
| ## Members and Validation | ||
|
|
||
| A diagnostic error will be raised when a member is accessed that is not a member of any of the types of a union. Note also that if a member is not the same type in each of the types in the union, it will itself be considered an intersection. | ||
|
|
||
| ```BrighterScript | ||
| sub testIntersection(value as {id as string} and {id as integer}) | ||
| ' This is an error - "value.id" is of type "string AND integer" | ||
| printInteger(value.id) | ||
| end sub | ||
|
|
||
| sub printInteger(x as integer) | ||
| print x | ||
| end sub | ||
| ``` | ||
|
|
||
| ## Transpilation | ||
|
|
||
| Since Brightscript does not have intersection types natively, intersection types will be transpiled as `dynamic`. | ||
|
|
||
| ```BrighterScript | ||
|
|
||
| interface HasRadius | ||
| radius as float | ||
| end interface | ||
|
|
||
| interface Point | ||
| x as float | ||
| y as float | ||
| end interface | ||
|
|
||
| function getCircleDetails(circle as HasRadius and Point) as string | ||
| return "Circle: radius=" + circle.radius.toStr() + ", center=" + circle.x.toStr() + "," + circle.y.toStr() | ||
| end function | ||
| ``` | ||
|
|
||
| transpiles to | ||
|
|
||
| ```BrightScript | ||
| function getCircleDetails(circle as dynamic) as string | ||
| return "Circle: radius=" + circle.radius.ToStr() + ", center=" + circle.x.toStr() + "," + circle.y.toStr() | ||
| end function | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,11 @@ | ||
| # BrighterScript | ||
|
|
||
| BrighterScript is a superset of Roku's BrightScript language. Its goal is to provide new functionality and enhanced syntax support to enhance the Roku channel developer experience. | ||
|
|
||
| See the following pages for more information: | ||
|
|
||
| ## [Annotations](annotations.md) | ||
|
|
||
| ```brighterscript | ||
| 'mostly useful for plugins that change code based on annotations | ||
| @logOnException() | ||
|
|
@@ -13,12 +15,14 @@ end | |
| ``` | ||
|
|
||
| ## [Callfunc Operator](callfunc-operator.md) | ||
|
|
||
| ```brighterscript | ||
| 'instead of `node.callfunc("someMethod", 1, 2, 3)`, you can do this: | ||
| [email protected](1, 2, 3) | ||
| ``` | ||
|
|
||
| ## [Classes](classes.md) | ||
|
|
||
| ```brighterscript | ||
| class Movie | ||
| public title as string | ||
|
|
@@ -33,6 +37,7 @@ end class | |
| ``` | ||
|
|
||
| ## [Constants](constants.md) | ||
|
|
||
| ```brighterscript | ||
| const API_URL = "https://api.acme.com/v1/" | ||
| sub main() | ||
|
|
@@ -41,6 +46,7 @@ end sub | |
| ``` | ||
|
|
||
| ## [Enums](enums.md) | ||
|
|
||
| ```brighterscript | ||
| enum RemoteButton | ||
| up = "up" | ||
|
|
@@ -51,6 +57,7 @@ end enum | |
| ``` | ||
|
|
||
| ## [Exceptions](exceptions.md) | ||
|
|
||
| ```brighterscript | ||
| try | ||
| somethingDangerous() | ||
|
|
@@ -59,7 +66,40 @@ catch 'look, no exception variable! | |
| end try | ||
| ``` | ||
|
|
||
| ## [Imports](imports.md) | ||
|
|
||
| ```brighterscript | ||
| import "pkg:/source/util.bs" | ||
| sub main() | ||
| print util_toUpper("hello world") | ||
| end sub | ||
| ``` | ||
|
|
||
| ## [Interfaces](interfaces.md) | ||
|
|
||
| ```brighterscript | ||
| interface IMyComponent | ||
| top as roSGNodeMyComponent | ||
|
|
||
| isSelected as boolean | ||
| selectedIndex as integer | ||
|
|
||
| data as {id as string, isEpisode as boolean} | ||
| end interface | ||
| ``` | ||
|
|
||
| ## [Intersection Types](intersection-types.md) | ||
|
|
||
| ```brighterscript | ||
| type MyClassAA = MyClass and roAssociativeArray | ||
|
|
||
| sub addData(klass as MyClass and roAssociativeArray, data as roAssociativeArray) | ||
| return klass.append(data) | ||
| end sub | ||
| ``` | ||
|
|
||
| ## [Namespaces](namespaces.md) | ||
|
|
||
| ```brighterscript | ||
| namespace util | ||
| function toUpper(value as string) | ||
|
|
@@ -72,28 +112,24 @@ sub main() | |
| end sub | ||
| ``` | ||
|
|
||
| ## [Imports](imports.md) | ||
| ```brighterscript | ||
| import "pkg:/source/util.bs" | ||
| sub main() | ||
| print util_toUpper("hello world") | ||
| end sub | ||
| ``` | ||
|
|
||
| ## [Null-coalescing operator](null-coalescing-operator.md) | ||
|
|
||
| ```brighterscript | ||
| userSettings = getSettingsFromRegistry() ?? {} | ||
| ``` | ||
|
|
||
| ## [Plugins](plugins.md) | ||
|
|
||
| Plugins can be used to manipulate code at any point during the program lifecycle. | ||
|
|
||
| ## [Regular Expression Literals](regex-literals.md) | ||
|
|
||
| ```brighterscript | ||
| print /hello world/ig | ||
| ``` | ||
|
|
||
| ## [Source Literals](source-literals.md) | ||
|
|
||
| ```brighterscript | ||
| print SOURCE_FILE_PATH | ||
| print SOURCE_LINE_NUM | ||
|
|
@@ -103,7 +139,9 @@ print SOURCE_LOCATION | |
| print PKG_PATH | ||
| print PKG_LOCATION | ||
| ``` | ||
|
|
||
| ## [Template Strings (Template Literals)](template-strings.md) | ||
|
|
||
| ```brighterscript | ||
| name = `John Smith` | ||
|
|
||
|
|
@@ -114,16 +152,19 @@ second line text` | |
| ``` | ||
|
|
||
| ## [Ternary (Conditional) Operator](ternary-operator.md) | ||
|
|
||
| ```brighterscript | ||
| authStatus = user <> invalid ? "logged in" : "not logged in" | ||
| ``` | ||
|
|
||
| ## [Typecasts](typecasts.md) | ||
|
|
||
| ```BrighterScript | ||
| nodeId = (node as roSgNode).id | ||
| ``` | ||
|
|
||
| ## [Typed Arrays](typed-arrays.md) | ||
|
|
||
| ```brighterscript | ||
| function getY(translation as float[]) as float | ||
| yValue = -1 | ||
|
|
@@ -135,6 +176,7 @@ end function | |
| ``` | ||
|
|
||
| ## [Type Statements](type-statements.md) | ||
|
|
||
| ```brighterscript | ||
| type number = integer or float or double | ||
|
|
||
|
|
@@ -144,11 +186,13 @@ end function | |
| ``` | ||
|
|
||
| ## [Union Types](union-types.md) | ||
|
|
||
| ```brighterscript | ||
| sub logData(data as string or number) | ||
| print data.toStr() | ||
| end sub | ||
| ``` | ||
|
|
||
| ## [Variable Shadowing](variable-shadowing.md) | ||
|
|
||
| Name resolution rules for various types of shadowing. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.