-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds Callfunc Completion and Validation (#1352)
* Fixed completion and hovers on callFUn invocations * Callfunc return types are used for assignments * Callfunc and @invocations return types are honored, as long as they are built in types * Adds Callfunc invocation validation * removed .onlys * Adds component.createChild() typing * fixed some comments * Removed validation errors on generic roSgNode * Perform validation on dependent types when ComponentType changes * added one final test for for revalidation when callfunc type changes * Re-validates references to a component when the callfunc signature changes * Change some comments: * removed commented out code * removed commented out code * Makes componentType checking with builtin components better * Added changed symbols logging -- noticed there's way too many there * Added cannotFindCallFuncFunction and many tests * Found a crash and fixed it * Ensures validation when the unresolved member of a resolved type changes * Added coomments * Better handling of completion and validation of nodes from component libraries * Fixes callfunc on result of function call * Revert change - there's a difference between built in symbols and built in types * Fix build * Fixed issue for callfuncs returning voidtype * Adds count of changed symbols to the validation metrics * Adds protection on not being able to decipher defining nodes for some symbols --------- Co-authored-by: Bronley Plumb <[email protected]>
- Loading branch information
1 parent
7fb92ff
commit 1a27f76
Showing
47 changed files
with
2,117 additions
and
237 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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 |
---|---|---|
|
@@ -19,7 +19,7 @@ import type { SinonSpy } from 'sinon'; | |
import { createSandbox } from 'sinon'; | ||
import { SymbolTypeFlag } from './SymbolTypeFlag'; | ||
import { AssetFile } from './files/AssetFile'; | ||
import type { ProvideFileEvent, CompilerPlugin, BeforeProvideFileEvent, AfterProvideFileEvent, BeforeFileAddEvent, AfterFileAddEvent, BeforeFileRemoveEvent, AfterFileRemoveEvent } from './interfaces'; | ||
import type { ProvideFileEvent, CompilerPlugin, BeforeProvideFileEvent, AfterProvideFileEvent, BeforeFileAddEvent, AfterFileAddEvent, BeforeFileRemoveEvent, AfterFileRemoveEvent, ScopeValidationOptions } from './interfaces'; | ||
import { StringType, TypedFunctionType, DynamicType, FloatType, IntegerType, InterfaceType, ArrayType, BooleanType, DoubleType, UnionType } from './types'; | ||
import { AssociativeArrayType } from './types/AssociativeArrayType'; | ||
import { ComponentType } from './types/ComponentType'; | ||
|
@@ -584,6 +584,161 @@ describe('Program', () => { | |
program.validate(); | ||
expectZeroDiagnostics(program); | ||
}); | ||
|
||
describe('changed symbols', () => { | ||
it('includes components when component interface changes', () => { | ||
program.setFile('components/widget.xml', trim` | ||
<component name="Widget" extends="Group"> | ||
<interface> | ||
<field id="foo" type="string" /> | ||
</interface> | ||
</component> | ||
`); | ||
program.setFile('components/other.xml', trim` | ||
<component name="Other" extends="Group"> | ||
<interface> | ||
<field id="foo" type="string" /> | ||
</interface> | ||
</component> | ||
`); | ||
program.setFile('source/main.bs', ` | ||
sub sourceScopeFunc() | ||
end sub | ||
`); | ||
program.validate(); | ||
let options: ScopeValidationOptions = program['currentScopeValidationOptions']; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodewidget')).to.be.true; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodeother')).to.be.true; | ||
|
||
expectZeroDiagnostics(program); | ||
//change widget | ||
program.setFile('components/widget.xml', trim` | ||
<component name="Widget" extends="Group"> | ||
<interface> | ||
<field id="foo" type="integer" /> | ||
</interface> | ||
</component> | ||
`); | ||
program.validate(); | ||
expectZeroDiagnostics(program); | ||
options = program['currentScopeValidationOptions']; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodewidget')).to.be.true; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodeother')).to.be.false; | ||
}); | ||
|
||
it('includes components when component callfunc changes', () => { | ||
program.setFile('components/widget.xml', trim` | ||
<component name="Widget" extends="Group"> | ||
<script type="text/brightscript" uri="widget.bs" /> | ||
<interface> | ||
<function name="foo" /> | ||
</interface> | ||
</component> | ||
`); | ||
program.setFile('components/widget.bs', ` | ||
sub foo() | ||
end sub | ||
`); | ||
program.setFile('components/other.xml', trim` | ||
<component name="Other" extends="Group"> | ||
<interface> | ||
<field id="foo" type="string" /> | ||
</interface> | ||
</component> | ||
`); | ||
program.setFile('source/main.bs', ` | ||
sub sourceScopeFunc() | ||
end sub | ||
`); | ||
program.validate(); | ||
let options: ScopeValidationOptions = program['currentScopeValidationOptions']; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodewidget')).to.be.true; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodeother')).to.be.true; | ||
|
||
expectZeroDiagnostics(program); | ||
//change [email protected] | ||
program.setFile('components/widget.bs', ` | ||
sub foo(input) | ||
print input | ||
end sub | ||
`); | ||
program.validate(); | ||
expectZeroDiagnostics(program); | ||
options = program['currentScopeValidationOptions']; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodewidget')).to.be.true; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodeother')).to.be.false; | ||
}); | ||
|
||
it('includes types that depend on a changed component', () => { | ||
program.setFile('components/widget.xml', trim` | ||
<component name="Widget" extends="Group"> | ||
<script type="text/brightscript" uri="widget.bs" /> | ||
<interface> | ||
<function name="foo" /> | ||
</interface> | ||
</component> | ||
`); | ||
program.setFile('components/widget.bs', ` | ||
sub foo() | ||
end sub | ||
`); | ||
program.setFile('components/other.xml', trim` | ||
<component name="Other" extends="Group"> | ||
<interface> | ||
<field id="foo" type="string" /> | ||
</interface> | ||
</component> | ||
`); | ||
program.setFile('source/main.bs', ` | ||
interface IncludesWidget | ||
widget as roSGNodeWidget | ||
end interface | ||
sub sourceScopeFunc() | ||
end sub | ||
`); | ||
program.validate(); | ||
expectZeroDiagnostics(program); | ||
let options: ScopeValidationOptions = program['currentScopeValidationOptions']; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodewidget')).to.be.true; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodeother')).to.be.true; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('includeswidget')).to.be.true; | ||
|
||
// change roSgNodeOther | ||
program.setFile('components/other.xml', trim` | ||
<component name="Other" extends="Group"> | ||
<interface> | ||
<field id="foo" type="integer" /> | ||
</interface> | ||
</component> | ||
`); | ||
program.validate(); | ||
expectZeroDiagnostics(program); | ||
options = program['currentScopeValidationOptions']; | ||
|
||
// only rosgnodewidget changes | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodewidget')).to.be.false; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodeother')).to.be.true; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('includeswidget')).to.be.false; | ||
|
||
//change [email protected] | ||
program.setFile('components/widget.bs', ` | ||
sub foo(input) | ||
print input | ||
end sub | ||
`); | ||
program.validate(); | ||
expectZeroDiagnostics(program); | ||
options = program['currentScopeValidationOptions']; | ||
|
||
// has rosgnodewidget AND IncludesWidget, because it depends on roSgnodeWidget | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodewidget')).to.be.true; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('rosgnodeother')).to.be.false; | ||
expect(options.changedSymbols.get(SymbolTypeFlag.typetime).has('includeswidget')).to.be.true; | ||
}); | ||
|
||
}); | ||
|
||
}); | ||
|
||
describe('hasFile', () => { | ||
|
Oops, something went wrong.