Skip to content
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

Adds support for types declared in comments #1293

Merged
merged 12 commits into from
Sep 23, 2024
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
Loading