brighterscript 0.66.0-alpha.4 → 0.66.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/dist/DiagnosticMessages.d.ts +21 -3
- package/dist/DiagnosticMessages.js +35 -2
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.d.ts +1 -0
- package/dist/LanguageServer.js +8 -5
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Program.d.ts +20 -8
- package/dist/Program.js +107 -60
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.js +14 -2
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +15 -13
- package/dist/Scope.js +26 -65
- package/dist/Scope.js.map +1 -1
- package/dist/SymbolTable.d.ts +17 -10
- package/dist/SymbolTable.js +48 -26
- package/dist/SymbolTable.js.map +1 -1
- package/dist/XmlScope.d.ts +2 -0
- package/dist/XmlScope.js +38 -0
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/creators.d.ts +3 -1
- package/dist/astUtils/creators.js +14 -4
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +24 -5
- package/dist/astUtils/reflection.js +58 -13
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +85 -3
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +3 -3
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +4 -4
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +44 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.js +353 -20
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1452 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +9 -4
- package/dist/bscPlugin/hover/HoverProcessor.js +64 -67
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +162 -4
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.js +20 -16
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +22 -1
- package/dist/bscPlugin/validation/ScopeValidator.js +194 -42
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +621 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +7 -2
- package/dist/diagnosticUtils.js +43 -15
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/files/BrsFile.Class.spec.js +10 -8
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +3 -20
- package/dist/files/BrsFile.js +7 -355
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +2 -248
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.d.ts +1 -6
- package/dist/files/XmlFile.js +0 -13
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +0 -36
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/globalCallables.js +1 -5
- package/dist/globalCallables.js.map +1 -1
- package/dist/interfaces.d.ts +22 -2
- package/dist/interfaces.js +4 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +12 -0
- package/dist/lexer/Lexer.js +27 -2
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +40 -0
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +4 -0
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +4 -0
- package/dist/lexer/TokenKind.js +10 -1
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +8 -1
- package/dist/parser/AstNode.js +16 -0
- package/dist/parser/AstNode.js.map +1 -1
- package/dist/parser/Expression.d.ts +16 -1
- package/dist/parser/Expression.js +75 -11
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.d.ts +7 -0
- package/dist/parser/Parser.js +55 -7
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +330 -4
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +1 -1
- package/dist/parser/Statement.d.ts +18 -6
- package/dist/parser/Statement.js +54 -16
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/tests/Parser.spec.js +2 -1
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +16 -8
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +12 -6
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +8 -4
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +4 -4
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +13 -13
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/statement/ConstStatement.spec.js +1 -34
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.js +1 -257
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +8 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +6 -3
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +5 -3
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +26 -13
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/roku-types/data.json +156 -111
- package/dist/roku-types/index.d.ts +2 -27
- package/dist/types/ArrayType.d.ts +4 -1
- package/dist/types/ArrayType.js +43 -7
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +31 -2
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +11 -0
- package/dist/types/AssociativeArrayType.js +52 -0
- package/dist/types/AssociativeArrayType.js.map +1 -0
- package/dist/types/BaseFunctionType.d.ts +2 -1
- package/dist/types/BaseFunctionType.js +1 -1
- package/dist/types/BaseFunctionType.js.map +1 -1
- package/dist/types/BooleanType.d.ts +2 -4
- package/dist/types/BooleanType.js +6 -7
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BscType.d.ts +8 -4
- package/dist/types/BscType.js +42 -14
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BscTypeKind.d.ts +2 -0
- package/dist/types/BscTypeKind.js +2 -0
- package/dist/types/BscTypeKind.js.map +1 -1
- package/dist/types/BuiltInInterfaceAdder.d.ts +20 -0
- package/dist/types/BuiltInInterfaceAdder.js +139 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +109 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
- package/dist/types/ClassType.d.ts +6 -1
- package/dist/types/ClassType.js +26 -2
- package/dist/types/ClassType.js.map +1 -1
- package/dist/types/ComponentType.d.ts +26 -0
- package/dist/types/ComponentType.js +80 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +2 -4
- package/dist/types/DoubleType.js +6 -7
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DynamicType.d.ts +2 -2
- package/dist/types/DynamicType.js +3 -1
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/EnumType.d.ts +4 -5
- package/dist/types/EnumType.js +8 -7
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/FloatType.d.ts +2 -4
- package/dist/types/FloatType.js +6 -7
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FunctionType.d.ts +2 -1
- package/dist/types/FunctionType.js +6 -2
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/IntegerType.d.ts +2 -4
- package/dist/types/IntegerType.js +6 -7
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +2 -1
- package/dist/types/InterfaceType.js +8 -4
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +2 -2
- package/dist/types/InvalidType.d.ts +1 -1
- package/dist/types/InvalidType.js +5 -1
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +2 -4
- package/dist/types/LongIntegerType.js +6 -7
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/ObjectType.d.ts +3 -3
- package/dist/types/ObjectType.js +3 -1
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ReferenceType.d.ts +14 -0
- package/dist/types/ReferenceType.js +114 -13
- package/dist/types/ReferenceType.js.map +1 -1
- package/dist/types/ReferenceType.spec.js +15 -0
- package/dist/types/ReferenceType.spec.js.map +1 -1
- package/dist/types/StringType.d.ts +2 -4
- package/dist/types/StringType.js +5 -6
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +2 -1
- package/dist/types/TypedFunctionType.js +10 -3
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/UninitializedType.d.ts +2 -1
- package/dist/types/UninitializedType.js +1 -1
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +4 -2
- package/dist/types/UnionType.js +25 -4
- package/dist/types/UnionType.js.map +1 -1
- package/dist/types/UnionType.spec.js +46 -19
- package/dist/types/UnionType.spec.js.map +1 -1
- package/dist/types/VoidType.d.ts +2 -1
- package/dist/types/VoidType.js +6 -2
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/helpers.d.ts +2 -0
- package/dist/types/helpers.js +18 -3
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +25 -2
- package/dist/util.js +179 -13
- package/dist/util.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,8 @@ const DiagnosticMessages_1 = require("../../DiagnosticMessages");
|
|
|
5
5
|
const Program_1 = require("../../Program");
|
|
6
6
|
const testHelpers_spec_1 = require("../../testHelpers.spec");
|
|
7
7
|
const chai_1 = require("chai");
|
|
8
|
+
const IntegerType_1 = require("../../types/IntegerType");
|
|
9
|
+
const StringType_1 = require("../../types/StringType");
|
|
8
10
|
describe('ScopeValidator', () => {
|
|
9
11
|
let sinon = sinonImport.createSandbox();
|
|
10
12
|
let rootDir = process.cwd();
|
|
@@ -265,7 +267,7 @@ describe('ScopeValidator', () => {
|
|
|
265
267
|
`);
|
|
266
268
|
program.validate();
|
|
267
269
|
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
268
|
-
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('string', 'Direction')
|
|
270
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('string', 'Direction').message
|
|
269
271
|
]);
|
|
270
272
|
});
|
|
271
273
|
it('supports passing enum type as enum type', () => {
|
|
@@ -697,6 +699,255 @@ describe('ScopeValidator', () => {
|
|
|
697
699
|
//should have no errors
|
|
698
700
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
699
701
|
});
|
|
702
|
+
it('allows calling future function and save to same variable', () => {
|
|
703
|
+
program.setFile('source/util.brs', `
|
|
704
|
+
function getSomeInt() as integer
|
|
705
|
+
numVal = getUntypedNum()
|
|
706
|
+
numVal = cInt(numVal)
|
|
707
|
+
return numVal
|
|
708
|
+
end function
|
|
709
|
+
|
|
710
|
+
function getUntypedNum()
|
|
711
|
+
return 1
|
|
712
|
+
end function
|
|
713
|
+
`);
|
|
714
|
+
program.validate();
|
|
715
|
+
//should have no errors
|
|
716
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
717
|
+
});
|
|
718
|
+
it('allows union types of all compatible types as arg', () => {
|
|
719
|
+
program.setFile('source/util.bs', `
|
|
720
|
+
sub printIntNum(num as float or double or integer)
|
|
721
|
+
print cInt(num)
|
|
722
|
+
end sub
|
|
723
|
+
`);
|
|
724
|
+
program.validate();
|
|
725
|
+
//should have no errors
|
|
726
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
727
|
+
});
|
|
728
|
+
it('allows function calls of built-in members of primitives', () => {
|
|
729
|
+
program.setFile('source/util.brs', `
|
|
730
|
+
sub doSomething()
|
|
731
|
+
myStr = "Hello World"
|
|
732
|
+
myStr = myStr.replace("World", "You")
|
|
733
|
+
print myStr
|
|
734
|
+
end sub
|
|
735
|
+
`);
|
|
736
|
+
program.validate();
|
|
737
|
+
//should have no errors
|
|
738
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
739
|
+
});
|
|
740
|
+
it('validates union types of all compatible types as arg - when some do not work', () => {
|
|
741
|
+
program.setFile('source/util.bs', `
|
|
742
|
+
sub printIntNum(maybeNum as float or string)
|
|
743
|
+
print cInt(maybeNum)
|
|
744
|
+
end sub
|
|
745
|
+
`);
|
|
746
|
+
program.validate();
|
|
747
|
+
//should have no errors
|
|
748
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
749
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('float or string', 'float').message
|
|
750
|
+
]);
|
|
751
|
+
});
|
|
752
|
+
it('validates function calls of built-in members of primitives', () => {
|
|
753
|
+
program.setFile('source/util.brs', `
|
|
754
|
+
sub doSomething()
|
|
755
|
+
myStr = "Hello World"
|
|
756
|
+
notAString = 3.14
|
|
757
|
+
myStr = myStr.replace("World", notAString)
|
|
758
|
+
print myStr
|
|
759
|
+
end sub
|
|
760
|
+
`);
|
|
761
|
+
program.validate();
|
|
762
|
+
//should have error - 2nd param should be a string, not a float
|
|
763
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
764
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('float', 'string').message
|
|
765
|
+
]);
|
|
766
|
+
});
|
|
767
|
+
it('validates method calls of classes', () => {
|
|
768
|
+
program.setFile('source/util.bs', `
|
|
769
|
+
class Klass
|
|
770
|
+
sub test(input as string)
|
|
771
|
+
end sub
|
|
772
|
+
end class
|
|
773
|
+
|
|
774
|
+
sub doSomething()
|
|
775
|
+
k = new Klass()
|
|
776
|
+
k.test(3.14)
|
|
777
|
+
end sub
|
|
778
|
+
`);
|
|
779
|
+
program.validate();
|
|
780
|
+
//should have error - param should be a string, not a float
|
|
781
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
782
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('float', 'string').message
|
|
783
|
+
]);
|
|
784
|
+
});
|
|
785
|
+
it('validates inside method calls of classes', () => {
|
|
786
|
+
program.setFile('source/util.bs', `
|
|
787
|
+
class Klass
|
|
788
|
+
sub test(input as string)
|
|
789
|
+
end sub
|
|
790
|
+
|
|
791
|
+
sub otherTest()
|
|
792
|
+
m.test(3.14)
|
|
793
|
+
end sub
|
|
794
|
+
end class
|
|
795
|
+
`);
|
|
796
|
+
program.validate();
|
|
797
|
+
//should have error - param should be a string, not a float
|
|
798
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
799
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('float', 'string').message
|
|
800
|
+
]);
|
|
801
|
+
});
|
|
802
|
+
it('validates calls of a constructor', () => {
|
|
803
|
+
program.setFile('source/util.bs', `
|
|
804
|
+
class Klass
|
|
805
|
+
sub new(name as string)
|
|
806
|
+
end sub
|
|
807
|
+
end class
|
|
808
|
+
|
|
809
|
+
sub createKlass()
|
|
810
|
+
k = new Klass(3.14)
|
|
811
|
+
end sub
|
|
812
|
+
`);
|
|
813
|
+
program.validate();
|
|
814
|
+
//should have error - param should be a string, not a float
|
|
815
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
816
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('float', 'string').message
|
|
817
|
+
]);
|
|
818
|
+
});
|
|
819
|
+
it('validates super calls in a constructor', () => {
|
|
820
|
+
program.setFile('source/util.bs', `
|
|
821
|
+
class Klass
|
|
822
|
+
sub new(name as string)
|
|
823
|
+
end sub
|
|
824
|
+
end class
|
|
825
|
+
|
|
826
|
+
class SubKlass extends Klass
|
|
827
|
+
sub new()
|
|
828
|
+
super(3.14)
|
|
829
|
+
end sub
|
|
830
|
+
end class
|
|
831
|
+
`);
|
|
832
|
+
program.validate();
|
|
833
|
+
//should have error - param should be a string, not a float
|
|
834
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
835
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('float', 'string').message
|
|
836
|
+
]);
|
|
837
|
+
});
|
|
838
|
+
it('validates super calls in a class methods', () => {
|
|
839
|
+
program.setFile('source/util.bs', `
|
|
840
|
+
class Klass
|
|
841
|
+
sub test(name as string)
|
|
842
|
+
end sub
|
|
843
|
+
end class
|
|
844
|
+
|
|
845
|
+
class SubKlass extends Klass
|
|
846
|
+
sub test2()
|
|
847
|
+
super.test(3.14)
|
|
848
|
+
end sub
|
|
849
|
+
end class
|
|
850
|
+
`);
|
|
851
|
+
program.validate();
|
|
852
|
+
//should have error - param should be a string, not a float
|
|
853
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
854
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('float', 'string').message
|
|
855
|
+
]);
|
|
856
|
+
});
|
|
857
|
+
it('validates a function passed as an arg', () => {
|
|
858
|
+
program.setFile('source/util.bs', `
|
|
859
|
+
sub foo()
|
|
860
|
+
getPi = function()
|
|
861
|
+
return 3.14
|
|
862
|
+
end function
|
|
863
|
+
bar(getPi)
|
|
864
|
+
end sub
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
sub bar(num as integer)
|
|
868
|
+
print num
|
|
869
|
+
end sub
|
|
870
|
+
`);
|
|
871
|
+
program.validate();
|
|
872
|
+
//should have error - param should be a string, not a float
|
|
873
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
874
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('function () as dynamic', 'integer').message
|
|
875
|
+
]);
|
|
876
|
+
});
|
|
877
|
+
it('allows AAs that match an interface to be passed as args', () => {
|
|
878
|
+
program.setFile('source/util.bs', `
|
|
879
|
+
sub doStuff()
|
|
880
|
+
takesMyIface({beta: "hello", charlie: "world"})
|
|
881
|
+
end sub
|
|
882
|
+
|
|
883
|
+
sub takesMyIface(iFace as MyIFace)
|
|
884
|
+
end sub
|
|
885
|
+
|
|
886
|
+
interface MyIFace
|
|
887
|
+
beta as string
|
|
888
|
+
charlie as string
|
|
889
|
+
end interface
|
|
890
|
+
`);
|
|
891
|
+
program.validate();
|
|
892
|
+
//should have error
|
|
893
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
894
|
+
});
|
|
895
|
+
it('validates empty AAs that are passed as args to param expecting interface', () => {
|
|
896
|
+
program.setFile('source/util.bs', `
|
|
897
|
+
sub doStuff()
|
|
898
|
+
takesMyIface({})
|
|
899
|
+
end sub
|
|
900
|
+
|
|
901
|
+
sub takesMyIface(iFace as MyIFace)
|
|
902
|
+
end sub
|
|
903
|
+
|
|
904
|
+
interface MyIFace
|
|
905
|
+
beta as string
|
|
906
|
+
charlie as string
|
|
907
|
+
end interface
|
|
908
|
+
`);
|
|
909
|
+
program.validate();
|
|
910
|
+
//should have error
|
|
911
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
912
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('roAssociativeArray', 'MyIFace', {
|
|
913
|
+
missingFields: [{ name: 'beta', expectedType: StringType_1.StringType.instance }, { name: 'charlie', expectedType: StringType_1.StringType.instance }]
|
|
914
|
+
}).message
|
|
915
|
+
]);
|
|
916
|
+
});
|
|
917
|
+
it('includes data on missing fields', () => {
|
|
918
|
+
program.setFile('source/util.bs', `
|
|
919
|
+
sub doStuff()
|
|
920
|
+
takesMyIface({charlie: "hello"})
|
|
921
|
+
end sub
|
|
922
|
+
|
|
923
|
+
sub takesMyIface(iFace as MyIFace)
|
|
924
|
+
end sub
|
|
925
|
+
|
|
926
|
+
interface MyIFace
|
|
927
|
+
beta as string
|
|
928
|
+
charlie as integer
|
|
929
|
+
end interface
|
|
930
|
+
`);
|
|
931
|
+
program.validate();
|
|
932
|
+
//should have error
|
|
933
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
934
|
+
DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('roAssociativeArray', 'MyIFace', {
|
|
935
|
+
missingFields: [{ name: 'beta', expectedType: StringType_1.StringType.instance }],
|
|
936
|
+
fieldMismatches: [{ name: 'charlie', expectedType: IntegerType_1.IntegerType.instance, actualType: StringType_1.StringType.instance }]
|
|
937
|
+
}).message
|
|
938
|
+
]);
|
|
939
|
+
//The aa should have 'beta' and 'charlie' properties of type string and integer
|
|
940
|
+
const diagnostics = program.getDiagnostics();
|
|
941
|
+
(0, chai_1.expect)(diagnostics.length).to.eq(1);
|
|
942
|
+
const data = diagnostics[0].data;
|
|
943
|
+
(0, chai_1.expect)(data.missingFields.length).to.eq(1);
|
|
944
|
+
(0, chai_1.expect)(data.missingFields[0].name).to.eq('beta');
|
|
945
|
+
(0, testHelpers_spec_1.expectTypeToBe)(data.missingFields[0].expectedType, StringType_1.StringType);
|
|
946
|
+
(0, chai_1.expect)(data.fieldMismatches.length).to.eq(1);
|
|
947
|
+
(0, chai_1.expect)(data.fieldMismatches[0].name).to.eq('charlie');
|
|
948
|
+
(0, testHelpers_spec_1.expectTypeToBe)(data.fieldMismatches[0].expectedType, IntegerType_1.IntegerType);
|
|
949
|
+
(0, testHelpers_spec_1.expectTypeToBe)(data.fieldMismatches[0].actualType, StringType_1.StringType);
|
|
950
|
+
});
|
|
700
951
|
});
|
|
701
952
|
describe('cannotFindName', () => {
|
|
702
953
|
it('finds variables from assignments from member functions of primitive types', () => {
|
|
@@ -710,6 +961,375 @@ describe('ScopeValidator', () => {
|
|
|
710
961
|
//should have no errors
|
|
711
962
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
712
963
|
});
|
|
964
|
+
it('validates when lhs of compound assignment does not exist', () => {
|
|
965
|
+
program.setFile('source/util.brs', `
|
|
966
|
+
sub main()
|
|
967
|
+
expected += chr(10) + " version=""2.0"""
|
|
968
|
+
end sub
|
|
969
|
+
`);
|
|
970
|
+
program.validate();
|
|
971
|
+
//should have error - cannot find "expected"
|
|
972
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
973
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('expected').message
|
|
974
|
+
]);
|
|
975
|
+
});
|
|
976
|
+
});
|
|
977
|
+
describe('returnTypeMismatch', () => {
|
|
978
|
+
it('finds when a function returns a type that is not what was declared', () => {
|
|
979
|
+
program.setFile('source/util.bs', `
|
|
980
|
+
function getPi() as float
|
|
981
|
+
return "apple" ' get it?
|
|
982
|
+
end function
|
|
983
|
+
`);
|
|
984
|
+
program.validate();
|
|
985
|
+
//should have error - return value should be a float, not a string
|
|
986
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
987
|
+
DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch('string', 'float').message
|
|
988
|
+
]);
|
|
989
|
+
});
|
|
990
|
+
it('finds all return statements that do not match', () => {
|
|
991
|
+
program.setFile('source/util.bs', `
|
|
992
|
+
function getPi(kind as integer) as float
|
|
993
|
+
if kind = 1
|
|
994
|
+
return "apple"
|
|
995
|
+
else if kind = 2
|
|
996
|
+
return false
|
|
997
|
+
else if kind = 3
|
|
998
|
+
return new Pie("lemon")
|
|
999
|
+
end if
|
|
1000
|
+
return 3.14
|
|
1001
|
+
end function
|
|
1002
|
+
|
|
1003
|
+
class Pie
|
|
1004
|
+
kind as string
|
|
1005
|
+
sub new(kind as string)
|
|
1006
|
+
m.kind = kind
|
|
1007
|
+
end sub
|
|
1008
|
+
end class
|
|
1009
|
+
`);
|
|
1010
|
+
program.validate();
|
|
1011
|
+
//should have error - return value should be a float, not whatever else
|
|
1012
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1013
|
+
DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch('string', 'float').message,
|
|
1014
|
+
DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch('boolean', 'float').message,
|
|
1015
|
+
DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch('Pie', 'float').message
|
|
1016
|
+
]);
|
|
1017
|
+
});
|
|
1018
|
+
it('allows returning compatible types', () => {
|
|
1019
|
+
program.setFile('source/util.bs', `
|
|
1020
|
+
function getPi() as float
|
|
1021
|
+
return 3 ' integers are compatible with floats
|
|
1022
|
+
end function
|
|
1023
|
+
|
|
1024
|
+
function getPie() as Pie
|
|
1025
|
+
return new Tart("lemon") ' Tart extends Pie
|
|
1026
|
+
end function
|
|
1027
|
+
|
|
1028
|
+
class Pie
|
|
1029
|
+
kind as string
|
|
1030
|
+
sub new(kind as string)
|
|
1031
|
+
m.kind = kind
|
|
1032
|
+
end sub
|
|
1033
|
+
end class
|
|
1034
|
+
|
|
1035
|
+
class Tart extends Pie
|
|
1036
|
+
size = "small"
|
|
1037
|
+
end class
|
|
1038
|
+
`);
|
|
1039
|
+
program.validate();
|
|
1040
|
+
//should have no errors
|
|
1041
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
1042
|
+
});
|
|
1043
|
+
it('detects return types on void functions (subs)', () => {
|
|
1044
|
+
program.setFile('source/util.bs', `
|
|
1045
|
+
sub sayHello(name as string)
|
|
1046
|
+
return "hello " + name ' return should be void in subs
|
|
1047
|
+
end sub
|
|
1048
|
+
`);
|
|
1049
|
+
program.validate();
|
|
1050
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1051
|
+
DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch('string', 'void').message
|
|
1052
|
+
]);
|
|
1053
|
+
});
|
|
1054
|
+
it('detects return types on void functions', () => {
|
|
1055
|
+
program.setFile('source/util.bs', `
|
|
1056
|
+
function sayHello(name as string) as void
|
|
1057
|
+
return "hello " + name ' return should be void in subs
|
|
1058
|
+
end function
|
|
1059
|
+
`);
|
|
1060
|
+
program.validate();
|
|
1061
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1062
|
+
DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch('string', 'void').message
|
|
1063
|
+
]);
|
|
1064
|
+
});
|
|
1065
|
+
});
|
|
1066
|
+
describe('assignmentTypeMismatch', () => {
|
|
1067
|
+
it('finds when the type of the lhs is not compatible with the expected type', () => {
|
|
1068
|
+
program.setFile('source/util.bs', `
|
|
1069
|
+
sub doStuff(thing as iThing)
|
|
1070
|
+
thing.name = 123
|
|
1071
|
+
end sub
|
|
1072
|
+
|
|
1073
|
+
interface iThing
|
|
1074
|
+
name as string
|
|
1075
|
+
end interface
|
|
1076
|
+
`);
|
|
1077
|
+
program.validate();
|
|
1078
|
+
//should have error - assignment value should be a string, not a float
|
|
1079
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1080
|
+
DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('integer', 'string').message
|
|
1081
|
+
]);
|
|
1082
|
+
});
|
|
1083
|
+
it('allows setting a member with correct type that is a union type', () => {
|
|
1084
|
+
program.setFile('source/util.bs', `
|
|
1085
|
+
sub doStuff(thing as iThing)
|
|
1086
|
+
thing.name = 123
|
|
1087
|
+
end sub
|
|
1088
|
+
|
|
1089
|
+
interface iThing
|
|
1090
|
+
name as string or integer
|
|
1091
|
+
end interface
|
|
1092
|
+
`);
|
|
1093
|
+
program.validate();
|
|
1094
|
+
//should have no error - assignment value should be a string, not a float
|
|
1095
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
1096
|
+
});
|
|
1097
|
+
it('finds when the rhs type is not compatible with the lhs, which is a union type', () => {
|
|
1098
|
+
program.setFile('source/util.bs', `
|
|
1099
|
+
sub doStuff(thing as iThing)
|
|
1100
|
+
thing.name = false
|
|
1101
|
+
end sub
|
|
1102
|
+
|
|
1103
|
+
interface iThing
|
|
1104
|
+
name as string or integer
|
|
1105
|
+
end interface
|
|
1106
|
+
`);
|
|
1107
|
+
program.validate();
|
|
1108
|
+
//should have error - assignment value should be a string or integer, not a boolean
|
|
1109
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1110
|
+
DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('boolean', 'string or integer').message
|
|
1111
|
+
]);
|
|
1112
|
+
});
|
|
1113
|
+
it('validates when trying to assign to a class method', () => {
|
|
1114
|
+
program.setFile('source/util.bs', `
|
|
1115
|
+
sub doStuff(myThing as Thing)
|
|
1116
|
+
myThing.getPi = 3.14
|
|
1117
|
+
end sub
|
|
1118
|
+
|
|
1119
|
+
class Thing
|
|
1120
|
+
function getPi() as float
|
|
1121
|
+
return 3.14
|
|
1122
|
+
end function
|
|
1123
|
+
end class
|
|
1124
|
+
`);
|
|
1125
|
+
program.validate();
|
|
1126
|
+
//should have error
|
|
1127
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1128
|
+
DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('float', 'function getPi() as float').message
|
|
1129
|
+
]);
|
|
1130
|
+
});
|
|
1131
|
+
it('allows adding new properties to a class (but why would you want to?)', () => {
|
|
1132
|
+
program.setFile('source/util.bs', `
|
|
1133
|
+
sub doStuff(myThing as Thing)
|
|
1134
|
+
myThing.getPi = 3.14
|
|
1135
|
+
end sub
|
|
1136
|
+
|
|
1137
|
+
class Thing
|
|
1138
|
+
end class
|
|
1139
|
+
`);
|
|
1140
|
+
program.validate();
|
|
1141
|
+
//should have no errors
|
|
1142
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
1143
|
+
});
|
|
1144
|
+
it('validates class constructors', () => {
|
|
1145
|
+
program.setFile('source/util.bs', `
|
|
1146
|
+
class Video
|
|
1147
|
+
sub new(url as integer)
|
|
1148
|
+
m.url = url 'this should be a compile error
|
|
1149
|
+
end sub
|
|
1150
|
+
public url as string
|
|
1151
|
+
end class
|
|
1152
|
+
`);
|
|
1153
|
+
program.validate();
|
|
1154
|
+
//should have errors
|
|
1155
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1156
|
+
DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('integer', 'string').message
|
|
1157
|
+
]);
|
|
1158
|
+
});
|
|
1159
|
+
it('validates when assigning to a sgNode', () => {
|
|
1160
|
+
program.setFile('source/util.bs', `
|
|
1161
|
+
sub setLabelText(label as roSGNodeLabel)
|
|
1162
|
+
label.text = 1234
|
|
1163
|
+
end sub
|
|
1164
|
+
|
|
1165
|
+
`);
|
|
1166
|
+
program.validate();
|
|
1167
|
+
//should have errors
|
|
1168
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1169
|
+
DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('integer', 'string').message
|
|
1170
|
+
]);
|
|
1171
|
+
});
|
|
1172
|
+
});
|
|
1173
|
+
describe('operatorTypeMismatch', () => {
|
|
1174
|
+
it('finds when the type of the lhs is not compatible with the rhs type', () => {
|
|
1175
|
+
program.setFile('source/util.bs', `
|
|
1176
|
+
sub doStuff()
|
|
1177
|
+
a = 1 + true
|
|
1178
|
+
b = "hello" * 2
|
|
1179
|
+
end sub
|
|
1180
|
+
|
|
1181
|
+
`);
|
|
1182
|
+
program.validate();
|
|
1183
|
+
//should have errors
|
|
1184
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1185
|
+
DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('+', 'integer', 'boolean').message,
|
|
1186
|
+
DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('*', 'string', 'integer').message
|
|
1187
|
+
]);
|
|
1188
|
+
});
|
|
1189
|
+
it('allows when the type of the lhs is compatible with the rhs type', () => {
|
|
1190
|
+
program.setFile('source/util.bs', `
|
|
1191
|
+
sub doStuff()
|
|
1192
|
+
a = 10 << 1
|
|
1193
|
+
b = "hello" + "world"
|
|
1194
|
+
c = 78 / 34
|
|
1195
|
+
d = 100 \\ 5
|
|
1196
|
+
thing = new Klass()
|
|
1197
|
+
e = thing <> invalid
|
|
1198
|
+
end sub
|
|
1199
|
+
|
|
1200
|
+
class Klass
|
|
1201
|
+
end class
|
|
1202
|
+
`);
|
|
1203
|
+
program.validate();
|
|
1204
|
+
//should have no errors
|
|
1205
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
1206
|
+
});
|
|
1207
|
+
it('allows tests against invalid', () => {
|
|
1208
|
+
program.setFile('source/util.bs', `
|
|
1209
|
+
sub doStuff()
|
|
1210
|
+
thing = new Klass()
|
|
1211
|
+
x = thing <> invalid
|
|
1212
|
+
end sub
|
|
1213
|
+
|
|
1214
|
+
class Klass
|
|
1215
|
+
end class
|
|
1216
|
+
`);
|
|
1217
|
+
program.validate();
|
|
1218
|
+
//should have no errors
|
|
1219
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
1220
|
+
});
|
|
1221
|
+
it('disallows equality tests of classes', () => {
|
|
1222
|
+
program.setFile('source/util.bs', `
|
|
1223
|
+
sub doStuff()
|
|
1224
|
+
thing = new Klass()
|
|
1225
|
+
thing2 = new Klass()
|
|
1226
|
+
x = thing = thing2
|
|
1227
|
+
end sub
|
|
1228
|
+
|
|
1229
|
+
class Klass
|
|
1230
|
+
end class
|
|
1231
|
+
`);
|
|
1232
|
+
program.validate();
|
|
1233
|
+
//should have errors
|
|
1234
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1235
|
+
DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('=', 'Klass', 'Klass').message
|
|
1236
|
+
]);
|
|
1237
|
+
});
|
|
1238
|
+
it('disallows operations between dynamic and custom types', () => {
|
|
1239
|
+
program.setFile('source/util.bs', `
|
|
1240
|
+
sub doStuff(input)
|
|
1241
|
+
thing = new Klass()
|
|
1242
|
+
x = thing + input
|
|
1243
|
+
end sub
|
|
1244
|
+
|
|
1245
|
+
class Klass
|
|
1246
|
+
end class
|
|
1247
|
+
`);
|
|
1248
|
+
program.validate();
|
|
1249
|
+
//should have errors
|
|
1250
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1251
|
+
DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('+', 'Klass', 'dynamic').message
|
|
1252
|
+
]);
|
|
1253
|
+
});
|
|
1254
|
+
it('allows valid operations on enum members', () => {
|
|
1255
|
+
program.setFile('source/util.bs', `
|
|
1256
|
+
sub makeEasterly(d as Direction)
|
|
1257
|
+
print d + "e"
|
|
1258
|
+
print Direction.north + "east"
|
|
1259
|
+
end sub
|
|
1260
|
+
|
|
1261
|
+
function getTax(itemAmt as ItemCost) as Float
|
|
1262
|
+
return itemAmt * 1.15
|
|
1263
|
+
end function
|
|
1264
|
+
|
|
1265
|
+
enum Direction
|
|
1266
|
+
north = "n"
|
|
1267
|
+
south = "s"
|
|
1268
|
+
end enum
|
|
1269
|
+
|
|
1270
|
+
enum ItemCost
|
|
1271
|
+
x = 99.99
|
|
1272
|
+
y = 29.99
|
|
1273
|
+
end enum
|
|
1274
|
+
|
|
1275
|
+
`);
|
|
1276
|
+
program.validate();
|
|
1277
|
+
//should have no errors
|
|
1278
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
1279
|
+
});
|
|
1280
|
+
it('finds invalid operations on enum members', () => {
|
|
1281
|
+
program.setFile('source/util.bs', `
|
|
1282
|
+
enum Direction
|
|
1283
|
+
north = "n"
|
|
1284
|
+
south = "s"
|
|
1285
|
+
end enum
|
|
1286
|
+
|
|
1287
|
+
sub makeEasterly(d as Direction)
|
|
1288
|
+
print d + 2
|
|
1289
|
+
print 3.14 * Direction.north
|
|
1290
|
+
end sub
|
|
1291
|
+
`);
|
|
1292
|
+
program.validate();
|
|
1293
|
+
//should have errors
|
|
1294
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1295
|
+
DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('+', 'Direction', 'integer').message,
|
|
1296
|
+
DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('*', 'float', 'Direction').message
|
|
1297
|
+
]);
|
|
1298
|
+
});
|
|
1299
|
+
it('validates unary operators', () => {
|
|
1300
|
+
program.setFile('source/util.bs', `
|
|
1301
|
+
sub doStuff()
|
|
1302
|
+
x = - "hello world"
|
|
1303
|
+
end sub
|
|
1304
|
+
`);
|
|
1305
|
+
program.validate();
|
|
1306
|
+
//should have errors
|
|
1307
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1308
|
+
DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('-', 'string').message
|
|
1309
|
+
]);
|
|
1310
|
+
});
|
|
1311
|
+
it('allows unary on dynamic and union types', () => {
|
|
1312
|
+
program.setFile('source/util.bs', `
|
|
1313
|
+
sub doStuff(x)
|
|
1314
|
+
y = -x
|
|
1315
|
+
print y
|
|
1316
|
+
end sub
|
|
1317
|
+
|
|
1318
|
+
sub doOtherStuff(x as float or integer)
|
|
1319
|
+
y = -x
|
|
1320
|
+
print y
|
|
1321
|
+
end sub
|
|
1322
|
+
|
|
1323
|
+
sub doEventMoreStuff(x as boolean or dynamic)
|
|
1324
|
+
if not x
|
|
1325
|
+
print "ok"
|
|
1326
|
+
end if
|
|
1327
|
+
end sub
|
|
1328
|
+
`);
|
|
1329
|
+
program.validate();
|
|
1330
|
+
//should have no errors
|
|
1331
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
1332
|
+
});
|
|
713
1333
|
});
|
|
714
1334
|
});
|
|
715
1335
|
//# sourceMappingURL=ScopeValidator.spec.js.map
|