brighterscript 0.66.0-alpha.5 → 0.66.0-alpha.7

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.
Files changed (298) hide show
  1. package/CHANGELOG.md +64 -10
  2. package/README.md +16 -0
  3. package/bsconfig.schema.json +15 -0
  4. package/dist/ActionPipeline.d.ts +10 -0
  5. package/dist/ActionPipeline.js +40 -0
  6. package/dist/ActionPipeline.js.map +1 -0
  7. package/dist/BsConfig.d.ts +15 -1
  8. package/dist/CommentFlagProcessor.d.ts +4 -3
  9. package/dist/CommentFlagProcessor.js.map +1 -1
  10. package/dist/DiagnosticMessages.d.ts +19 -4
  11. package/dist/DiagnosticMessages.js +45 -5
  12. package/dist/DiagnosticMessages.js.map +1 -1
  13. package/dist/LanguageServer.js.map +1 -1
  14. package/dist/PluginInterface.d.ts +11 -2
  15. package/dist/PluginInterface.js +69 -10
  16. package/dist/PluginInterface.js.map +1 -1
  17. package/dist/Program.d.ts +101 -37
  18. package/dist/Program.js +492 -274
  19. package/dist/Program.js.map +1 -1
  20. package/dist/ProgramBuilder.d.ts +10 -4
  21. package/dist/ProgramBuilder.js +44 -54
  22. package/dist/ProgramBuilder.js.map +1 -1
  23. package/dist/Scope.d.ts +27 -13
  24. package/dist/Scope.js +44 -26
  25. package/dist/Scope.js.map +1 -1
  26. package/dist/SymbolTable.d.ts +5 -0
  27. package/dist/SymbolTable.js +15 -2
  28. package/dist/SymbolTable.js.map +1 -1
  29. package/dist/XmlScope.d.ts +7 -4
  30. package/dist/XmlScope.js +47 -8
  31. package/dist/XmlScope.js.map +1 -1
  32. package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +6 -1
  33. package/dist/astUtils/{AstEditor.js → Editor.js} +9 -3
  34. package/dist/astUtils/Editor.js.map +1 -0
  35. package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +10 -6
  36. package/dist/astUtils/Editor.spec.js.map +1 -0
  37. package/dist/astUtils/creators.d.ts +3 -1
  38. package/dist/astUtils/creators.js +9 -1
  39. package/dist/astUtils/creators.js.map +1 -1
  40. package/dist/astUtils/reflection.d.ts +30 -8
  41. package/dist/astUtils/reflection.js +64 -14
  42. package/dist/astUtils/reflection.js.map +1 -1
  43. package/dist/astUtils/reflection.spec.js +85 -4
  44. package/dist/astUtils/reflection.spec.js.map +1 -1
  45. package/dist/astUtils/visitors.d.ts +3 -3
  46. package/dist/astUtils/visitors.spec.js +7 -7
  47. package/dist/astUtils/visitors.spec.js.map +1 -1
  48. package/dist/bscPlugin/BscPlugin.d.ts +10 -2
  49. package/dist/bscPlugin/BscPlugin.js +24 -4
  50. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  51. package/dist/bscPlugin/FileWriter.d.ts +6 -0
  52. package/dist/bscPlugin/FileWriter.js +24 -0
  53. package/dist/bscPlugin/FileWriter.js.map +1 -0
  54. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +8 -8
  55. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  56. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +4 -4
  57. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  58. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +11 -1
  59. package/dist/bscPlugin/completions/CompletionsProcessor.js +112 -58
  60. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  61. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +151 -6
  62. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -1
  63. package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
  64. package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
  65. package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
  66. package/dist/bscPlugin/hover/HoverProcessor.d.ts +1 -7
  67. package/dist/bscPlugin/hover/HoverProcessor.js +2 -8
  68. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  69. package/dist/bscPlugin/hover/HoverProcessor.spec.js +55 -0
  70. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  71. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +1 -0
  72. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +43 -0
  73. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  74. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +22 -0
  75. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
  76. package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
  77. package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
  78. package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
  79. package/dist/bscPlugin/serialize/BslibManager.js +40 -0
  80. package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
  81. package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
  82. package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
  83. package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
  84. package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.d.ts → BrsFileTranspileProcessor.d.ts} +4 -2
  85. package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.js → BrsFileTranspileProcessor.js} +25 -4
  86. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
  87. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
  88. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
  89. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
  90. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +2 -2
  91. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -1
  92. package/dist/bscPlugin/validation/BrsFileValidator.js +2 -1
  93. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  94. package/dist/bscPlugin/validation/ScopeValidator.d.ts +12 -0
  95. package/dist/bscPlugin/validation/ScopeValidator.js +137 -19
  96. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  97. package/dist/bscPlugin/validation/ScopeValidator.spec.js +671 -1
  98. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
  99. package/dist/bscPlugin/validation/XmlFileValidator.js +2 -2
  100. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
  101. package/dist/cli.js +1 -0
  102. package/dist/cli.js.map +1 -1
  103. package/dist/deferred.d.ts +2 -2
  104. package/dist/deferred.js.map +1 -1
  105. package/dist/diagnosticUtils.d.ts +1 -0
  106. package/dist/diagnosticUtils.js +4 -3
  107. package/dist/diagnosticUtils.js.map +1 -1
  108. package/dist/examples/plugins/removePrint.js +1 -1
  109. package/dist/examples/plugins/removePrint.js.map +1 -1
  110. package/dist/files/AssetFile.d.ts +26 -0
  111. package/dist/files/AssetFile.js +26 -0
  112. package/dist/files/AssetFile.js.map +1 -0
  113. package/dist/files/BrsFile.Class.spec.js +40 -40
  114. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  115. package/dist/files/BrsFile.d.ts +42 -15
  116. package/dist/files/BrsFile.js +120 -78
  117. package/dist/files/BrsFile.js.map +1 -1
  118. package/dist/files/BrsFile.spec.js +266 -167
  119. package/dist/files/BrsFile.spec.js.map +1 -1
  120. package/dist/files/Factory.d.ts +25 -0
  121. package/dist/files/Factory.js +22 -0
  122. package/dist/files/Factory.js.map +1 -0
  123. package/dist/files/File.d.ts +106 -0
  124. package/dist/files/File.js +16 -0
  125. package/dist/files/File.js.map +1 -0
  126. package/dist/files/LazyFileData.d.ts +20 -0
  127. package/dist/files/LazyFileData.js +54 -0
  128. package/dist/files/LazyFileData.js.map +1 -0
  129. package/dist/files/LazyFileData.spec.d.ts +1 -0
  130. package/dist/files/LazyFileData.spec.js +27 -0
  131. package/dist/files/LazyFileData.spec.js.map +1 -0
  132. package/dist/files/XmlFile.d.ts +55 -17
  133. package/dist/files/XmlFile.js +88 -47
  134. package/dist/files/XmlFile.js.map +1 -1
  135. package/dist/files/XmlFile.spec.js +64 -57
  136. package/dist/files/XmlFile.spec.js.map +1 -1
  137. package/dist/files/tests/imports.spec.js +21 -8
  138. package/dist/files/tests/imports.spec.js.map +1 -1
  139. package/dist/files/tests/optionalChaning.spec.js +14 -14
  140. package/dist/files/tests/optionalChaning.spec.js.map +1 -1
  141. package/dist/globalCallables.js +2 -6
  142. package/dist/globalCallables.js.map +1 -1
  143. package/dist/index.d.ts +4 -1
  144. package/dist/index.js +4 -1
  145. package/dist/index.js.map +1 -1
  146. package/dist/interfaces.d.ts +326 -85
  147. package/dist/interfaces.js +4 -1
  148. package/dist/interfaces.js.map +1 -1
  149. package/dist/lexer/Lexer.js +1 -1
  150. package/dist/lexer/TokenKind.js +0 -1
  151. package/dist/lexer/TokenKind.js.map +1 -1
  152. package/dist/parser/AstNode.d.ts +2 -2
  153. package/dist/parser/AstNode.js +1 -1
  154. package/dist/parser/AstNode.js.map +1 -1
  155. package/dist/parser/BrsTranspileState.d.ts +3 -2
  156. package/dist/parser/BrsTranspileState.js +3 -2
  157. package/dist/parser/BrsTranspileState.js.map +1 -1
  158. package/dist/parser/Expression.d.ts +1 -1
  159. package/dist/parser/Expression.js +35 -19
  160. package/dist/parser/Expression.js.map +1 -1
  161. package/dist/parser/Parser.js +12 -1
  162. package/dist/parser/Parser.js.map +1 -1
  163. package/dist/parser/Parser.spec.js +18 -2
  164. package/dist/parser/Parser.spec.js.map +1 -1
  165. package/dist/parser/SGParser.d.ts +2 -2
  166. package/dist/parser/SGParser.js +3 -3
  167. package/dist/parser/SGParser.js.map +1 -1
  168. package/dist/parser/SGParser.spec.js +2 -2
  169. package/dist/parser/SGParser.spec.js.map +1 -1
  170. package/dist/parser/SGTypes.d.ts +1 -1
  171. package/dist/parser/Statement.js +1 -1
  172. package/dist/parser/Statement.js.map +1 -1
  173. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +10 -10
  174. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  175. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
  176. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
  177. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
  178. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  179. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +64 -36
  180. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  181. package/dist/parser/tests/expression/TernaryExpression.spec.js +34 -34
  182. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  183. package/dist/parser/tests/statement/ConstStatement.spec.js +17 -17
  184. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
  185. package/dist/parser/tests/statement/Continue.spec.js +2 -2
  186. package/dist/parser/tests/statement/Continue.spec.js.map +1 -1
  187. package/dist/parser/tests/statement/Enum.spec.js +26 -26
  188. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  189. package/dist/parser/tests/statement/For.spec.js +6 -6
  190. package/dist/parser/tests/statement/For.spec.js.map +1 -1
  191. package/dist/parser/tests/statement/ForEach.spec.js +4 -4
  192. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
  193. package/dist/parser/tests/statement/InterfaceStatement.spec.js +18 -10
  194. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  195. package/dist/parser/tests/statement/PrintStatement.spec.js +10 -10
  196. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  197. package/dist/preprocessor/Manifest.d.ts +1 -1
  198. package/dist/preprocessor/Manifest.js +2 -2
  199. package/dist/preprocessor/Manifest.js.map +1 -1
  200. package/dist/roku-types/data.json +111 -149
  201. package/dist/roku-types/index.d.ts +27 -13
  202. package/dist/types/ArrayType.d.ts +2 -1
  203. package/dist/types/ArrayType.js +6 -2
  204. package/dist/types/ArrayType.js.map +1 -1
  205. package/dist/types/ArrayType.spec.js +11 -1
  206. package/dist/types/ArrayType.spec.js.map +1 -1
  207. package/dist/types/AssociativeArrayType.d.ts +11 -0
  208. package/dist/types/AssociativeArrayType.js +52 -0
  209. package/dist/types/AssociativeArrayType.js.map +1 -0
  210. package/dist/types/BaseFunctionType.d.ts +2 -1
  211. package/dist/types/BaseFunctionType.js +1 -1
  212. package/dist/types/BaseFunctionType.js.map +1 -1
  213. package/dist/types/BooleanType.d.ts +2 -1
  214. package/dist/types/BooleanType.js +3 -2
  215. package/dist/types/BooleanType.js.map +1 -1
  216. package/dist/types/BscType.d.ts +3 -3
  217. package/dist/types/BscType.js +26 -12
  218. package/dist/types/BscType.js.map +1 -1
  219. package/dist/types/BscTypeKind.d.ts +2 -0
  220. package/dist/types/BscTypeKind.js +2 -0
  221. package/dist/types/BscTypeKind.js.map +1 -1
  222. package/dist/types/BuiltInInterfaceAdder.d.ts +8 -0
  223. package/dist/types/BuiltInInterfaceAdder.js +88 -23
  224. package/dist/types/BuiltInInterfaceAdder.js.map +1 -1
  225. package/dist/types/ClassType.d.ts +2 -1
  226. package/dist/types/ClassType.js +2 -2
  227. package/dist/types/ClassType.js.map +1 -1
  228. package/dist/types/ComponentType.d.ts +26 -0
  229. package/dist/types/ComponentType.js +83 -0
  230. package/dist/types/ComponentType.js.map +1 -0
  231. package/dist/types/DoubleType.d.ts +2 -1
  232. package/dist/types/DoubleType.js +4 -2
  233. package/dist/types/DoubleType.js.map +1 -1
  234. package/dist/types/DynamicType.d.ts +2 -2
  235. package/dist/types/DynamicType.js +1 -1
  236. package/dist/types/DynamicType.js.map +1 -1
  237. package/dist/types/EnumType.d.ts +3 -2
  238. package/dist/types/EnumType.js +3 -3
  239. package/dist/types/EnumType.js.map +1 -1
  240. package/dist/types/FloatType.d.ts +2 -1
  241. package/dist/types/FloatType.js +4 -2
  242. package/dist/types/FloatType.js.map +1 -1
  243. package/dist/types/FunctionType.d.ts +2 -1
  244. package/dist/types/FunctionType.js +2 -2
  245. package/dist/types/FunctionType.js.map +1 -1
  246. package/dist/types/IntegerType.d.ts +2 -1
  247. package/dist/types/IntegerType.js +4 -2
  248. package/dist/types/IntegerType.js.map +1 -1
  249. package/dist/types/InterfaceType.d.ts +2 -1
  250. package/dist/types/InterfaceType.js +3 -7
  251. package/dist/types/InterfaceType.js.map +1 -1
  252. package/dist/types/InterfaceType.spec.js +25 -2
  253. package/dist/types/InterfaceType.spec.js.map +1 -1
  254. package/dist/types/LongIntegerType.d.ts +2 -1
  255. package/dist/types/LongIntegerType.js +4 -2
  256. package/dist/types/LongIntegerType.js.map +1 -1
  257. package/dist/types/ObjectType.d.ts +2 -2
  258. package/dist/types/ObjectType.js +1 -1
  259. package/dist/types/ObjectType.js.map +1 -1
  260. package/dist/types/ReferenceType.d.ts +2 -0
  261. package/dist/types/ReferenceType.js +45 -1
  262. package/dist/types/ReferenceType.js.map +1 -1
  263. package/dist/types/StringType.d.ts +2 -1
  264. package/dist/types/StringType.js +4 -4
  265. package/dist/types/StringType.js.map +1 -1
  266. package/dist/types/TypedFunctionType.d.ts +7 -1
  267. package/dist/types/TypedFunctionType.js +47 -17
  268. package/dist/types/TypedFunctionType.js.map +1 -1
  269. package/dist/types/TypedFunctionType.spec.js +99 -0
  270. package/dist/types/TypedFunctionType.spec.js.map +1 -1
  271. package/dist/types/UninitializedType.d.ts +2 -1
  272. package/dist/types/UninitializedType.js +1 -1
  273. package/dist/types/UninitializedType.js.map +1 -1
  274. package/dist/types/UnionType.d.ts +2 -2
  275. package/dist/types/UnionType.js +10 -3
  276. package/dist/types/UnionType.js.map +1 -1
  277. package/dist/types/UnionType.spec.js +3 -2
  278. package/dist/types/UnionType.spec.js.map +1 -1
  279. package/dist/types/VoidType.d.ts +2 -1
  280. package/dist/types/VoidType.js +2 -2
  281. package/dist/types/VoidType.js.map +1 -1
  282. package/dist/types/helper.spec.js +15 -0
  283. package/dist/types/helper.spec.js.map +1 -1
  284. package/dist/types/helpers.d.ts +5 -1
  285. package/dist/types/helpers.js +31 -3
  286. package/dist/types/helpers.js.map +1 -1
  287. package/dist/util.d.ts +26 -6
  288. package/dist/util.js +181 -52
  289. package/dist/util.js.map +1 -1
  290. package/dist/validators/ClassValidator.js.map +1 -1
  291. package/package.json +1 -1
  292. package/dist/astUtils/AstEditor.js.map +0 -1
  293. package/dist/astUtils/AstEditor.spec.js.map +0 -1
  294. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
  295. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -31
  296. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
  297. /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
  298. /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → serialize/BslibInjector.spec.d.ts} +0 -0
@@ -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();
@@ -128,6 +130,57 @@ describe('ScopeValidator', () => {
128
130
  //should have no errors
129
131
  (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
130
132
  });
133
+ it('checks for at least the number of non-optional args on variadic (callFunc) functions', () => {
134
+ program.setFile('components/Widget.xml', (0, testHelpers_spec_1.trim) `
135
+ <?xml version="1.0" encoding="utf-8" ?>
136
+ <component name="Widget" extends="Group">
137
+ <script uri="Widget.brs"/>
138
+ <interface>
139
+ <function name="someFunc" />
140
+ </interface>
141
+ </component>
142
+ `);
143
+ program.setFile('components/Widget.brs', `
144
+ sub someFunc(input as object)
145
+ print input
146
+ end sub
147
+ `);
148
+ program.setFile('source/util.brs', `
149
+ sub useCallFunc(input as roSGNodeWidget)
150
+ input.callFunc()
151
+ end sub
152
+ `);
153
+ program.validate();
154
+ //should have an error
155
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
156
+ DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount('1-32', 0)
157
+ ]);
158
+ });
159
+ it('any number number of args on variadic (callFunc) functions', () => {
160
+ program.setFile('components/Widget.xml', (0, testHelpers_spec_1.trim) `
161
+ <?xml version="1.0" encoding="utf-8" ?>
162
+ <component name="Widget" extends="Group">
163
+ <script uri="Widget.brs"/>
164
+ <interface>
165
+ <function name="someFunc" />
166
+ </interface>
167
+ </component>
168
+ `);
169
+ program.setFile('components/Widget.brs', `
170
+ sub someFunc(input as object)
171
+ print input
172
+ end sub
173
+ `);
174
+ program.setFile('source/util.brs', `
175
+ sub useCallFunc(input as roSGNodeWidget)
176
+ input.callFunc("someFunc", 1, 2, 3, {})
177
+ end sub
178
+ `);
179
+ program.validate();
180
+ //TODO: do a better job of handling callFunc() invocations!
181
+ //should have an error
182
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
183
+ });
131
184
  });
132
185
  describe('argumentTypeMismatch', () => {
133
186
  it('param `as object` supports all known types', () => {
@@ -265,7 +318,7 @@ describe('ScopeValidator', () => {
265
318
  `);
266
319
  program.validate();
267
320
  (0, testHelpers_spec_1.expectDiagnostics)(program, [
268
- DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('string', 'Direction')
321
+ DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('string', 'Direction').message
269
322
  ]);
270
323
  });
271
324
  it('supports passing enum type as enum type', () => {
@@ -872,6 +925,251 @@ describe('ScopeValidator', () => {
872
925
  DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('function () as dynamic', 'integer').message
873
926
  ]);
874
927
  });
928
+ it('allows AAs that match an interface to be passed as args', () => {
929
+ program.setFile('source/util.bs', `
930
+ sub doStuff()
931
+ takesMyIface({beta: "hello", charlie: "world"})
932
+ end sub
933
+
934
+ sub takesMyIface(iFace as MyIFace)
935
+ end sub
936
+
937
+ interface MyIFace
938
+ beta as string
939
+ charlie as string
940
+ end interface
941
+ `);
942
+ program.validate();
943
+ //should have error
944
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
945
+ });
946
+ it('validates empty AAs that are passed as args to param expecting interface', () => {
947
+ program.setFile('source/util.bs', `
948
+ sub doStuff()
949
+ takesMyIface({})
950
+ end sub
951
+
952
+ sub takesMyIface(iFace as MyIFace)
953
+ end sub
954
+
955
+ interface MyIFace
956
+ beta as string
957
+ charlie as string
958
+ end interface
959
+ `);
960
+ program.validate();
961
+ //should have error
962
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
963
+ DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('roAssociativeArray', 'MyIFace', {
964
+ missingFields: [{ name: 'beta', expectedType: StringType_1.StringType.instance }, { name: 'charlie', expectedType: StringType_1.StringType.instance }]
965
+ }).message
966
+ ]);
967
+ });
968
+ it('includes data on missing fields', () => {
969
+ program.setFile('source/util.bs', `
970
+ sub doStuff()
971
+ takesMyIface({charlie: "hello"})
972
+ end sub
973
+
974
+ sub takesMyIface(iFace as MyIFace)
975
+ end sub
976
+
977
+ interface MyIFace
978
+ beta as string
979
+ charlie as integer
980
+ end interface
981
+ `);
982
+ program.validate();
983
+ //should have error
984
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
985
+ DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('roAssociativeArray', 'MyIFace', {
986
+ missingFields: [{ name: 'beta', expectedType: StringType_1.StringType.instance }],
987
+ fieldMismatches: [{ name: 'charlie', expectedType: IntegerType_1.IntegerType.instance, actualType: StringType_1.StringType.instance }]
988
+ }).message
989
+ ]);
990
+ //The aa should have 'beta' and 'charlie' properties of type string and integer
991
+ const diagnostics = program.getDiagnostics();
992
+ (0, chai_1.expect)(diagnostics.length).to.eq(1);
993
+ const data = diagnostics[0].data;
994
+ (0, chai_1.expect)(data.missingFields.length).to.eq(1);
995
+ (0, chai_1.expect)(data.missingFields[0].name).to.eq('beta');
996
+ (0, testHelpers_spec_1.expectTypeToBe)(data.missingFields[0].expectedType, StringType_1.StringType);
997
+ (0, chai_1.expect)(data.fieldMismatches.length).to.eq(1);
998
+ (0, chai_1.expect)(data.fieldMismatches[0].name).to.eq('charlie');
999
+ (0, testHelpers_spec_1.expectTypeToBe)(data.fieldMismatches[0].expectedType, IntegerType_1.IntegerType);
1000
+ (0, testHelpers_spec_1.expectTypeToBe)(data.fieldMismatches[0].actualType, StringType_1.StringType);
1001
+ });
1002
+ it('allows interfaces that have a superset of properties', () => {
1003
+ program.setFile('source/util.bs', `
1004
+ sub doStuff()
1005
+ takesMyIface({alpha: true, beta: "hello", charlie: 1})
1006
+ end sub
1007
+
1008
+ sub takesMyIface(iFace as MyIFace)
1009
+ end sub
1010
+
1011
+ interface MyIFace
1012
+ beta as string
1013
+ charlie as integer
1014
+ end interface
1015
+ `);
1016
+ program.validate();
1017
+ //should have no errors
1018
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1019
+ });
1020
+ it('allows interfaces that have a superset of properties', () => {
1021
+ program.setFile('source/util.bs', `
1022
+ sub doStuff(otherFace as MyOtherFace)
1023
+ takesMyIface(otherFace)
1024
+ end sub
1025
+
1026
+ sub takesMyIface(iFace as MyIFace)
1027
+ end sub
1028
+
1029
+ interface MyIFace
1030
+ beta as string
1031
+ charlie as integer
1032
+ end interface
1033
+
1034
+ interface MyOtherFace
1035
+ alpha as boolean
1036
+ beta as string
1037
+ charlie as integer
1038
+ end interface
1039
+ `);
1040
+ program.validate();
1041
+ //should have no errors
1042
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1043
+ });
1044
+ it('includes data on missing fields', () => {
1045
+ program.setFile('source/util.bs', `
1046
+ sub doStuff()
1047
+ takesMyIface({charlie: "hello"})
1048
+ end sub
1049
+
1050
+ sub takesMyIface(iFace as MyIFace)
1051
+ end sub
1052
+
1053
+ interface MyIFace
1054
+ beta as string
1055
+ charlie as integer
1056
+ end interface
1057
+ `);
1058
+ program.validate();
1059
+ //should have error
1060
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1061
+ DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('roAssociativeArray', 'MyIFace', {
1062
+ missingFields: [{ name: 'beta', expectedType: StringType_1.StringType.instance }],
1063
+ fieldMismatches: [{ name: 'charlie', expectedType: IntegerType_1.IntegerType.instance, actualType: StringType_1.StringType.instance }]
1064
+ }).message
1065
+ ]);
1066
+ //The aa should have 'beta' and 'charlie' properties of type string and integer
1067
+ const diagnostics = program.getDiagnostics();
1068
+ (0, chai_1.expect)(diagnostics.length).to.eq(1);
1069
+ const data = diagnostics[0].data;
1070
+ (0, chai_1.expect)(data.missingFields.length).to.eq(1);
1071
+ (0, chai_1.expect)(data.missingFields[0].name).to.eq('beta');
1072
+ (0, testHelpers_spec_1.expectTypeToBe)(data.missingFields[0].expectedType, StringType_1.StringType);
1073
+ (0, chai_1.expect)(data.fieldMismatches.length).to.eq(1);
1074
+ (0, chai_1.expect)(data.fieldMismatches[0].name).to.eq('charlie');
1075
+ (0, testHelpers_spec_1.expectTypeToBe)(data.fieldMismatches[0].expectedType, IntegerType_1.IntegerType);
1076
+ (0, testHelpers_spec_1.expectTypeToBe)(data.fieldMismatches[0].actualType, StringType_1.StringType);
1077
+ });
1078
+ describe('array compatibility', () => {
1079
+ it('accepts dynamic when assigning to a roArray', () => {
1080
+ program.setFile('source/util.bs', `
1081
+ sub takesArray(arr as roArray)
1082
+ end sub
1083
+
1084
+ sub doStuff(someArray)
1085
+ takesArray(someArray)
1086
+ end sub
1087
+ `);
1088
+ program.validate();
1089
+ //should have no errors
1090
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1091
+ });
1092
+ it('accepts roArray when assigning to a roArray', () => {
1093
+ program.setFile('source/util.bs', `
1094
+ sub takesArray(arr as roArray)
1095
+ end sub
1096
+
1097
+ sub doStuff(someArray as roArray)
1098
+ takesArray(someArray)
1099
+ end sub
1100
+ `);
1101
+ program.validate();
1102
+ //should have no errors
1103
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1104
+ });
1105
+ it('accepts typed arrays when assigning to a roArray', () => {
1106
+ program.setFile('source/util.bs', `
1107
+ sub takesArray(arr as roArray)
1108
+ end sub
1109
+
1110
+ sub doStuff(someArray as dynamic[])
1111
+ takesArray(someArray)
1112
+ end sub
1113
+ `);
1114
+ program.validate();
1115
+ //should have no errors
1116
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1117
+ });
1118
+ it('accepts roArray when assigning to dynamic[]', () => {
1119
+ program.setFile('source/util.bs', `
1120
+ sub takesArray(arr as dynamic[])
1121
+ end sub
1122
+
1123
+ sub doStuff(someArray as roArray)
1124
+ takesArray(someArray)
1125
+ end sub
1126
+ `);
1127
+ program.validate();
1128
+ //should have no errors
1129
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1130
+ });
1131
+ it('accepts roArray when assigning to typed array', () => {
1132
+ program.setFile('source/util.bs', `
1133
+ sub takesArray(arr as string[])
1134
+ end sub
1135
+
1136
+ sub doStuff(someArray as roArray)
1137
+ takesArray(someArray)
1138
+ end sub
1139
+ `);
1140
+ program.validate();
1141
+ //should have no errors
1142
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1143
+ });
1144
+ it('validates when typed array types are incompatible', () => {
1145
+ program.setFile('source/util.bs', `
1146
+ sub takesArray(arr as string[])
1147
+ end sub
1148
+
1149
+ sub doStuff(someArray as integer[])
1150
+ takesArray(someArray)
1151
+ end sub
1152
+ `);
1153
+ program.validate();
1154
+ //should have errors
1155
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1156
+ DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch('Array<integer>', 'Array<string>').message
1157
+ ]);
1158
+ });
1159
+ it('accepts when typed array types are compatible', () => {
1160
+ program.setFile('source/util.bs', `
1161
+ sub takesArray(arr as float[])
1162
+ end sub
1163
+
1164
+ sub doStuff(someArray as integer[])
1165
+ takesArray(someArray)
1166
+ end sub
1167
+ `);
1168
+ program.validate();
1169
+ //should have no errors
1170
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1171
+ });
1172
+ });
875
1173
  });
876
1174
  describe('cannotFindName', () => {
877
1175
  it('finds variables from assignments from member functions of primitive types', () => {
@@ -986,6 +1284,378 @@ describe('ScopeValidator', () => {
986
1284
  DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch('string', 'void').message
987
1285
  ]);
988
1286
  });
1287
+ it('allows returning enums with the default type that matches the declared return type', () => {
1288
+ program.setFile('source/util.bs', `
1289
+ enum MyEnum
1290
+ val1
1291
+ val2
1292
+ end enum
1293
+
1294
+ function getInt() as integer
1295
+ return MyEnum.val1
1296
+ end function
1297
+ `);
1298
+ program.validate();
1299
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1300
+ });
1301
+ it('allows returning enums passed as a param with the default type that matches the declared return type', () => {
1302
+ program.setFile('source/util.bs', `
1303
+ enum MyEnum
1304
+ val1
1305
+ val2
1306
+ end enum
1307
+
1308
+ function getInt(enumVal as MyEnum) as integer
1309
+ return enumVal
1310
+ end function
1311
+ `);
1312
+ program.validate();
1313
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1314
+ });
1315
+ it('allows returning enums with the default type that matches the declared return type for string enums', () => {
1316
+ program.setFile('source/util.bs', `
1317
+ enum MyEnum
1318
+ val1 = "hello"
1319
+ val2 = "world"
1320
+ end enum
1321
+
1322
+ function getInt() as string
1323
+ return MyEnum.val1
1324
+ end function
1325
+ `);
1326
+ program.validate();
1327
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1328
+ });
1329
+ it('flags returning enums with the default type that does not matches the declared return type', () => {
1330
+ program.setFile('source/util.bs', `
1331
+ enum MyEnum
1332
+ val1 = "hello"
1333
+ val2 = "world"
1334
+ end enum
1335
+
1336
+ function getInt() as integer
1337
+ return MyEnum.val1
1338
+ end function
1339
+ `);
1340
+ program.validate();
1341
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1342
+ DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch('MyEnum', 'integer').message
1343
+ ]);
1344
+ });
1345
+ it('flags returning enums passed as params with the default type that does not matches the declared return type', () => {
1346
+ program.setFile('source/util.bs', `
1347
+ enum MyEnum
1348
+ val1 = "hello"
1349
+ val2 = "world"
1350
+ end enum
1351
+
1352
+ function getInt(enumVal as MyEnum) as integer
1353
+ return enumVal
1354
+ end function
1355
+ `);
1356
+ program.validate();
1357
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1358
+ DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch('MyEnum', 'integer').message
1359
+ ]);
1360
+ });
1361
+ it('flags returning enums type', () => {
1362
+ program.setFile('source/util.bs', `
1363
+ enum MyEnum
1364
+ val1 = "hello"
1365
+ val2 = "world"
1366
+ end enum
1367
+
1368
+
1369
+ function getInt() as integer
1370
+ return MyEnum
1371
+ end function
1372
+ `);
1373
+ program.validate();
1374
+ (0, chai_1.expect)(program.getDiagnostics().length).to.be.greaterThan(0);
1375
+ });
1376
+ it('allows returning an Enum', () => {
1377
+ program.setFile('source/util.bs', `
1378
+ enum MyEnum
1379
+ val1 = "hello"
1380
+ val2 = "world"
1381
+ end enum
1382
+
1383
+
1384
+ function getInt() as MyEnum
1385
+ return MyEnum.val1
1386
+ end function
1387
+ `);
1388
+ program.validate();
1389
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1390
+ });
1391
+ });
1392
+ describe('assignmentTypeMismatch', () => {
1393
+ it('finds when the type of the lhs is not compatible with the expected type', () => {
1394
+ program.setFile('source/util.bs', `
1395
+ sub doStuff(thing as iThing)
1396
+ thing.name = 123
1397
+ end sub
1398
+
1399
+ interface iThing
1400
+ name as string
1401
+ end interface
1402
+ `);
1403
+ program.validate();
1404
+ //should have error - assignment value should be a string, not a float
1405
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1406
+ DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('integer', 'string').message
1407
+ ]);
1408
+ });
1409
+ it('allows setting a member with correct type that is a union type', () => {
1410
+ program.setFile('source/util.bs', `
1411
+ sub doStuff(thing as iThing)
1412
+ thing.name = 123
1413
+ end sub
1414
+
1415
+ interface iThing
1416
+ name as string or integer
1417
+ end interface
1418
+ `);
1419
+ program.validate();
1420
+ //should have no error - assignment value should be a string, not a float
1421
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1422
+ });
1423
+ it('finds when the rhs type is not compatible with the lhs, which is a union type', () => {
1424
+ program.setFile('source/util.bs', `
1425
+ sub doStuff(thing as iThing)
1426
+ thing.name = false
1427
+ end sub
1428
+
1429
+ interface iThing
1430
+ name as string or integer
1431
+ end interface
1432
+ `);
1433
+ program.validate();
1434
+ //should have error - assignment value should be a string or integer, not a boolean
1435
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1436
+ DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('boolean', 'string or integer').message
1437
+ ]);
1438
+ });
1439
+ it('validates when trying to assign to a class method', () => {
1440
+ program.setFile('source/util.bs', `
1441
+ sub doStuff(myThing as Thing)
1442
+ myThing.getPi = 3.14
1443
+ end sub
1444
+
1445
+ class Thing
1446
+ function getPi() as float
1447
+ return 3.14
1448
+ end function
1449
+ end class
1450
+ `);
1451
+ program.validate();
1452
+ //should have error
1453
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1454
+ DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('float', 'function getPi() as float').message
1455
+ ]);
1456
+ });
1457
+ it('allows adding new properties to a class (but why would you want to?)', () => {
1458
+ program.setFile('source/util.bs', `
1459
+ sub doStuff(myThing as Thing)
1460
+ myThing.getPi = 3.14
1461
+ end sub
1462
+
1463
+ class Thing
1464
+ end class
1465
+ `);
1466
+ program.validate();
1467
+ //should have no errors
1468
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1469
+ });
1470
+ it('validates class constructors', () => {
1471
+ program.setFile('source/util.bs', `
1472
+ class Video
1473
+ sub new(url as integer)
1474
+ m.url = url 'this should be a compile error
1475
+ end sub
1476
+ public url as string
1477
+ end class
1478
+ `);
1479
+ program.validate();
1480
+ //should have errors
1481
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1482
+ DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('integer', 'string').message
1483
+ ]);
1484
+ });
1485
+ it('validates when assigning to a sgNode', () => {
1486
+ program.setFile('source/util.bs', `
1487
+ sub setLabelText(label as roSGNodeLabel)
1488
+ label.text = 1234
1489
+ end sub
1490
+
1491
+ `);
1492
+ program.validate();
1493
+ //should have errors
1494
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1495
+ DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch('integer', 'string').message
1496
+ ]);
1497
+ });
1498
+ });
1499
+ describe('operatorTypeMismatch', () => {
1500
+ it('finds when the type of the lhs is not compatible with the rhs type', () => {
1501
+ program.setFile('source/util.bs', `
1502
+ sub doStuff()
1503
+ a = 1 + true
1504
+ b = "hello" * 2
1505
+ end sub
1506
+
1507
+ `);
1508
+ program.validate();
1509
+ //should have errors
1510
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1511
+ DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('+', 'integer', 'boolean').message,
1512
+ DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('*', 'string', 'integer').message
1513
+ ]);
1514
+ });
1515
+ it('allows when the type of the lhs is compatible with the rhs type', () => {
1516
+ program.setFile('source/util.bs', `
1517
+ sub doStuff()
1518
+ a = 10 << 1
1519
+ b = "hello" + "world"
1520
+ c = 78 / 34
1521
+ d = 100 \\ 5
1522
+ thing = new Klass()
1523
+ e = thing <> invalid
1524
+ end sub
1525
+
1526
+ class Klass
1527
+ end class
1528
+ `);
1529
+ program.validate();
1530
+ //should have no errors
1531
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1532
+ });
1533
+ it('allows tests against invalid', () => {
1534
+ program.setFile('source/util.bs', `
1535
+ sub doStuff()
1536
+ thing = new Klass()
1537
+ x = thing <> invalid
1538
+ end sub
1539
+
1540
+ class Klass
1541
+ end class
1542
+ `);
1543
+ program.validate();
1544
+ //should have no errors
1545
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1546
+ });
1547
+ it('disallows equality tests of classes', () => {
1548
+ program.setFile('source/util.bs', `
1549
+ sub doStuff()
1550
+ thing = new Klass()
1551
+ thing2 = new Klass()
1552
+ x = thing = thing2
1553
+ end sub
1554
+
1555
+ class Klass
1556
+ end class
1557
+ `);
1558
+ program.validate();
1559
+ //should have errors
1560
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1561
+ DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('=', 'Klass', 'Klass').message
1562
+ ]);
1563
+ });
1564
+ it('disallows operations between dynamic and custom types', () => {
1565
+ program.setFile('source/util.bs', `
1566
+ sub doStuff(input)
1567
+ thing = new Klass()
1568
+ x = thing + input
1569
+ end sub
1570
+
1571
+ class Klass
1572
+ end class
1573
+ `);
1574
+ program.validate();
1575
+ //should have errors
1576
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1577
+ DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('+', 'Klass', 'dynamic').message
1578
+ ]);
1579
+ });
1580
+ it('allows valid operations on enum members', () => {
1581
+ program.setFile('source/util.bs', `
1582
+ sub makeEasterly(d as Direction)
1583
+ print d + "e"
1584
+ print Direction.north + "east"
1585
+ end sub
1586
+
1587
+ function getTax(itemAmt as ItemCost) as Float
1588
+ return itemAmt * 1.15
1589
+ end function
1590
+
1591
+ enum Direction
1592
+ north = "n"
1593
+ south = "s"
1594
+ end enum
1595
+
1596
+ enum ItemCost
1597
+ x = 99.99
1598
+ y = 29.99
1599
+ end enum
1600
+
1601
+ `);
1602
+ program.validate();
1603
+ //should have no errors
1604
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1605
+ });
1606
+ it('finds invalid operations on enum members', () => {
1607
+ program.setFile('source/util.bs', `
1608
+ enum Direction
1609
+ north = "n"
1610
+ south = "s"
1611
+ end enum
1612
+
1613
+ sub makeEasterly(d as Direction)
1614
+ print d + 2
1615
+ print 3.14 * Direction.north
1616
+ end sub
1617
+ `);
1618
+ program.validate();
1619
+ //should have errors
1620
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1621
+ DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('+', 'Direction', 'integer').message,
1622
+ DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('*', 'float', 'Direction').message
1623
+ ]);
1624
+ });
1625
+ it('validates unary operators', () => {
1626
+ program.setFile('source/util.bs', `
1627
+ sub doStuff()
1628
+ x = - "hello world"
1629
+ end sub
1630
+ `);
1631
+ program.validate();
1632
+ //should have errors
1633
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1634
+ DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch('-', 'string').message
1635
+ ]);
1636
+ });
1637
+ it('allows unary on dynamic and union types', () => {
1638
+ program.setFile('source/util.bs', `
1639
+ sub doStuff(x)
1640
+ y = -x
1641
+ print y
1642
+ end sub
1643
+
1644
+ sub doOtherStuff(x as float or integer)
1645
+ y = -x
1646
+ print y
1647
+ end sub
1648
+
1649
+ sub doEventMoreStuff(x as boolean or dynamic)
1650
+ if not x
1651
+ print "ok"
1652
+ end if
1653
+ end sub
1654
+ `);
1655
+ program.validate();
1656
+ //should have no errors
1657
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1658
+ });
989
1659
  });
990
1660
  });
991
1661
  //# sourceMappingURL=ScopeValidator.spec.js.map