Skip to content

Commit

Permalink
Adds support for types declared in comments (#1293)
Browse files Browse the repository at this point in the history
* Add basic docs

* Added a BrsDoc Parser

* Remove leading apostrophes in brsdocs

* Added a comment on apostrophes

* BrsDoc parser can get parsed docs for a node

* Support for @retrun and @type tags

* Just comments and names

* Defined case sensitivity of doc parsing

* Adds diagnostics for bad types in doc comment tags

* Unifies doc types so it uses a parsed expression

* a few tweaks

* Diagnostics on bad types in doc comments unerline the type

---------

Co-authored-by: Mark Pearce <mark.pearce@redspace.com>
  • Loading branch information
TwitchBronBron and markwpearce authored Sep 23, 2024
1 parent 43cbf8b commit 8d5f810
Show file tree
Hide file tree
Showing 18 changed files with 1,420 additions and 46 deletions.
50 changes: 50 additions & 0 deletions docs/type-checking-without-transpile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Typechecking without transpiling
If you want the benefits of BrighterScript's type system but don't want to use the transpiler, you can use comments to declare variable types to get much richer editor experience and type validation.

## Params
Declare the type of a specific parameter:

```brighterscript
'@param {roSGNodeRectangle} node
function resize(node, width as integer, height as string)
'yay, we know that `node` is a `roSGNodeRectangle` type
node.width = width
node.height = height
end function
```

## Return type

Declare the return type of a function

```brighterscript
'@return {roSGNodeRectangle}
function createRectangle()
return createObject("roSGNode", "Rectangle")
end function
function test()
'yay, we know that `rectangle` is a `roSGNodeRectangle` type
rectangle = createRectangle()
end function
```

## Inline variable type
You can override the type of a variable in brs files by starting a comment with `@type` . This will cast the variable below with the given type.

```brighterscript
' @type {integer}
runtime = getRuntimeFromServer()
```

## TODO: Function-level variable type
Sometimes you need to declare a variable at more than one location in your code. In this situation, you can declare the variable type in the body of the function before the variable usage, and that variable will then be treated as that type.

```brighterscript
' @type {integer} runtime
if m.top.hasRuntime
runtime = m.top.runtime
else
runtime = 12345
end if
```
8 changes: 8 additions & 0 deletions src/DiagnosticMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,14 @@ export let DiagnosticMessages = {
message: `Unsafe unmatched terminator '${terminator}' in conditional compilation block`,
code: 1153,
severity: DiagnosticSeverity.Error
}),
cannotFindTypeInCommentDoc: (name: string) => ({
message: `Cannot find type '${name}' in doc comment`,
code: 1154,
data: {
name: name
},
severity: DiagnosticSeverity.Error
})
};
export const defaultMaximumTruncationLength = 160;
Expand Down
21 changes: 21 additions & 0 deletions src/Scope.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2813,6 +2813,27 @@ describe('Scope', () => {
expectZeroDiagnostics(program);
});

it('should allow access to underscored version of namespaced class constructor in different file', () => {
program.setFile('source/main.bs', `
sub printPi()
print alpha_util_SomeKlass().value
end sub
`);
program.setFile('source/util.bs', `
namespace alpha.util
class SomeKlass
value as float
sub new()
value = 3.14
end sub
end class
end namespace
`);
program.validate();
expectZeroDiagnostics(program);
});

it('resolves deep namespaces defined in different locations', () => {
program.setFile(`source/main.bs`, `
sub main()
Expand Down
1 change: 1 addition & 0 deletions src/SymbolTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export class SymbolTable implements SymbolTypeGetter {
options.data.doNotMerge = data?.doNotMerge;
options.data.isAlias = data?.isAlias;
options.data.isInstance = data?.isInstance;
options.data.isFromDocComment = data?.isFromDocComment;
}
return resolvedType;
}
Expand Down
Loading

0 comments on commit 8d5f810

Please sign in to comment.