brighterscript 0.65.1 → 0.66.0-alpha.0

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 (249) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +8 -0
  3. package/dist/BsConfig.d.ts +5 -11
  4. package/dist/CacheVerifier.d.ts +8 -0
  5. package/dist/CacheVerifier.js +20 -0
  6. package/dist/CacheVerifier.js.map +1 -0
  7. package/dist/DiagnosticMessages.d.ts +9 -4
  8. package/dist/DiagnosticMessages.js +8 -3
  9. package/dist/DiagnosticMessages.js.map +1 -1
  10. package/dist/FunctionScope.d.ts +1 -0
  11. package/dist/FunctionScope.js +3 -0
  12. package/dist/FunctionScope.js.map +1 -1
  13. package/dist/PluginInterface.d.ts +0 -4
  14. package/dist/PluginInterface.js.map +1 -1
  15. package/dist/Program.d.ts +6 -39
  16. package/dist/Program.js +42 -44
  17. package/dist/Program.js.map +1 -1
  18. package/dist/ProgramBuilder.d.ts +4 -0
  19. package/dist/ProgramBuilder.js +12 -7
  20. package/dist/ProgramBuilder.js.map +1 -1
  21. package/dist/Scope.d.ts +1 -5
  22. package/dist/Scope.js +3 -28
  23. package/dist/Scope.js.map +1 -1
  24. package/dist/SymbolTable.d.ts +44 -6
  25. package/dist/SymbolTable.js +151 -25
  26. package/dist/SymbolTable.js.map +1 -1
  27. package/dist/XmlScope.js +11 -12
  28. package/dist/XmlScope.js.map +1 -1
  29. package/dist/astUtils/creators.d.ts +16 -6
  30. package/dist/astUtils/creators.js +39 -16
  31. package/dist/astUtils/creators.js.map +1 -1
  32. package/dist/astUtils/reflection.d.ts +46 -37
  33. package/dist/astUtils/reflection.js +145 -147
  34. package/dist/astUtils/reflection.js.map +1 -1
  35. package/dist/astUtils/reflection.spec.js +1 -6
  36. package/dist/astUtils/reflection.spec.js.map +1 -1
  37. package/dist/astUtils/visitors.d.ts +4 -11
  38. package/dist/astUtils/visitors.js +0 -7
  39. package/dist/astUtils/visitors.js.map +1 -1
  40. package/dist/astUtils/visitors.spec.js +4 -2
  41. package/dist/astUtils/visitors.spec.js.map +1 -1
  42. package/dist/astUtils/xml.d.ts +9 -9
  43. package/dist/astUtils/xml.js +6 -6
  44. package/dist/astUtils/xml.js.map +1 -1
  45. package/dist/bscPlugin/BscPlugin.js +4 -0
  46. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  47. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
  48. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +2 -2
  49. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  50. package/dist/bscPlugin/hover/HoverProcessor.js +71 -59
  51. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  52. package/dist/bscPlugin/hover/HoverProcessor.spec.js +110 -10
  53. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  54. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +6 -5
  55. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  56. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +1 -1
  57. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -1
  58. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +11 -0
  59. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +53 -0
  60. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
  61. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +4 -0
  62. package/dist/bscPlugin/validation/BrsFileValidator.js +72 -16
  63. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  64. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +1 -1
  65. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
  66. package/dist/bscPlugin/validation/ScopeValidator.d.ts +1 -0
  67. package/dist/bscPlugin/validation/ScopeValidator.js +72 -18
  68. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  69. package/dist/bscPlugin/validation/XmlFileValidator.js +9 -9
  70. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
  71. package/dist/files/BrsFile.Class.spec.js +9 -10
  72. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  73. package/dist/files/BrsFile.d.ts +8 -10
  74. package/dist/files/BrsFile.js +72 -52
  75. package/dist/files/BrsFile.js.map +1 -1
  76. package/dist/files/BrsFile.spec.js +56 -14
  77. package/dist/files/BrsFile.spec.js.map +1 -1
  78. package/dist/files/XmlFile.d.ts +19 -19
  79. package/dist/files/XmlFile.js +24 -42
  80. package/dist/files/XmlFile.js.map +1 -1
  81. package/dist/files/XmlFile.spec.js +61 -9
  82. package/dist/files/XmlFile.spec.js.map +1 -1
  83. package/dist/files/tests/imports.spec.js +8 -11
  84. package/dist/files/tests/imports.spec.js.map +1 -1
  85. package/dist/globalCallables.js +2 -1
  86. package/dist/globalCallables.js.map +1 -1
  87. package/dist/index.d.ts +2 -0
  88. package/dist/index.js +2 -0
  89. package/dist/index.js.map +1 -1
  90. package/dist/interfaces.d.ts +20 -1
  91. package/dist/interfaces.js +13 -0
  92. package/dist/interfaces.js.map +1 -1
  93. package/dist/lexer/TokenKind.d.ts +2 -0
  94. package/dist/lexer/TokenKind.js +5 -1
  95. package/dist/lexer/TokenKind.js.map +1 -1
  96. package/dist/parser/AstNode.d.ts +78 -1
  97. package/dist/parser/AstNode.js +80 -1
  98. package/dist/parser/AstNode.js.map +1 -1
  99. package/dist/parser/Expression.d.ts +87 -53
  100. package/dist/parser/Expression.js +243 -139
  101. package/dist/parser/Expression.js.map +1 -1
  102. package/dist/parser/Parser.Class.spec.js +10 -7
  103. package/dist/parser/Parser.Class.spec.js.map +1 -1
  104. package/dist/parser/Parser.d.ts +9 -5
  105. package/dist/parser/Parser.js +125 -78
  106. package/dist/parser/Parser.js.map +1 -1
  107. package/dist/parser/Parser.spec.d.ts +2 -0
  108. package/dist/parser/Parser.spec.js +117 -5
  109. package/dist/parser/Parser.spec.js.map +1 -1
  110. package/dist/parser/SGParser.d.ts +42 -4
  111. package/dist/parser/SGParser.js +191 -195
  112. package/dist/parser/SGParser.js.map +1 -1
  113. package/dist/parser/SGParser.spec.js +13 -10
  114. package/dist/parser/SGParser.spec.js.map +1 -1
  115. package/dist/parser/SGTypes.d.ts +279 -51
  116. package/dist/parser/SGTypes.js +562 -185
  117. package/dist/parser/SGTypes.js.map +1 -1
  118. package/dist/parser/Statement.d.ts +88 -70
  119. package/dist/parser/Statement.js +212 -136
  120. package/dist/parser/Statement.js.map +1 -1
  121. package/dist/parser/TranspileState.d.ts +1 -1
  122. package/dist/parser/TranspileState.js +5 -2
  123. package/dist/parser/TranspileState.js.map +1 -1
  124. package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
  125. package/dist/parser/tests/expression/TypeExpression.spec.js +127 -0
  126. package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
  127. package/dist/types/ArrayType.d.ts +6 -4
  128. package/dist/types/ArrayType.js +30 -22
  129. package/dist/types/ArrayType.js.map +1 -1
  130. package/dist/types/ArrayType.spec.js +8 -8
  131. package/dist/types/ArrayType.spec.js.map +1 -1
  132. package/dist/types/BooleanType.d.ts +7 -4
  133. package/dist/types/BooleanType.js +13 -8
  134. package/dist/types/BooleanType.js.map +1 -1
  135. package/dist/types/BooleanType.spec.js +9 -3
  136. package/dist/types/BooleanType.spec.js.map +1 -1
  137. package/dist/types/BscType.d.ts +25 -2
  138. package/dist/types/BscType.js +64 -0
  139. package/dist/types/BscType.js.map +1 -1
  140. package/dist/types/BscTypeKind.d.ts +22 -0
  141. package/dist/types/BscTypeKind.js +27 -0
  142. package/dist/types/BscTypeKind.js.map +1 -0
  143. package/dist/types/ClassType.d.ts +11 -0
  144. package/dist/types/ClassType.js +31 -0
  145. package/dist/types/ClassType.js.map +1 -0
  146. package/dist/types/ClassType.spec.d.ts +1 -0
  147. package/dist/types/ClassType.spec.js +75 -0
  148. package/dist/types/ClassType.spec.js.map +1 -0
  149. package/dist/types/DoubleType.d.ts +7 -4
  150. package/dist/types/DoubleType.js +16 -20
  151. package/dist/types/DoubleType.js.map +1 -1
  152. package/dist/types/DoubleType.spec.js +11 -3
  153. package/dist/types/DoubleType.spec.js.map +1 -1
  154. package/dist/types/DynamicType.d.ts +9 -3
  155. package/dist/types/DynamicType.js +16 -2
  156. package/dist/types/DynamicType.js.map +1 -1
  157. package/dist/types/DynamicType.spec.js +15 -4
  158. package/dist/types/DynamicType.spec.js.map +1 -1
  159. package/dist/types/EnumType.d.ts +22 -0
  160. package/dist/types/EnumType.js +59 -0
  161. package/dist/types/EnumType.js.map +1 -0
  162. package/dist/types/EnumType.spec.d.ts +1 -0
  163. package/dist/types/EnumType.spec.js +33 -0
  164. package/dist/types/EnumType.spec.js.map +1 -0
  165. package/dist/types/FloatType.d.ts +7 -4
  166. package/dist/types/FloatType.js +16 -20
  167. package/dist/types/FloatType.js.map +1 -1
  168. package/dist/types/FloatType.spec.js +3 -3
  169. package/dist/types/FloatType.spec.js.map +1 -1
  170. package/dist/types/FunctionType.d.ts +6 -4
  171. package/dist/types/FunctionType.js +22 -19
  172. package/dist/types/FunctionType.js.map +1 -1
  173. package/dist/types/FunctionType.spec.js +5 -5
  174. package/dist/types/FunctionType.spec.js.map +1 -1
  175. package/dist/types/InheritableType.d.ts +25 -0
  176. package/dist/types/InheritableType.js +88 -0
  177. package/dist/types/InheritableType.js.map +1 -0
  178. package/dist/types/IntegerType.d.ts +7 -4
  179. package/dist/types/IntegerType.js +16 -20
  180. package/dist/types/IntegerType.js.map +1 -1
  181. package/dist/types/IntegerType.spec.js +7 -3
  182. package/dist/types/IntegerType.spec.js.map +1 -1
  183. package/dist/types/InterfaceType.d.ts +10 -10
  184. package/dist/types/InterfaceType.js +24 -45
  185. package/dist/types/InterfaceType.js.map +1 -1
  186. package/dist/types/InterfaceType.spec.js +59 -45
  187. package/dist/types/InterfaceType.spec.js.map +1 -1
  188. package/dist/types/InvalidType.d.ts +6 -4
  189. package/dist/types/InvalidType.js +12 -8
  190. package/dist/types/InvalidType.js.map +1 -1
  191. package/dist/types/InvalidType.spec.js +7 -3
  192. package/dist/types/InvalidType.spec.js.map +1 -1
  193. package/dist/types/LongIntegerType.d.ts +7 -4
  194. package/dist/types/LongIntegerType.js +16 -20
  195. package/dist/types/LongIntegerType.js.map +1 -1
  196. package/dist/types/LongIntegerType.spec.js +9 -3
  197. package/dist/types/LongIntegerType.spec.js.map +1 -1
  198. package/dist/types/NamespaceType.d.ts +11 -0
  199. package/dist/types/NamespaceType.js +25 -0
  200. package/dist/types/NamespaceType.js.map +1 -0
  201. package/dist/types/ObjectType.d.ts +8 -4
  202. package/dist/types/ObjectType.js +26 -7
  203. package/dist/types/ObjectType.js.map +1 -1
  204. package/dist/types/ObjectType.spec.js +2 -2
  205. package/dist/types/ObjectType.spec.js.map +1 -1
  206. package/dist/types/ReferenceType.d.ts +51 -0
  207. package/dist/types/ReferenceType.js +274 -0
  208. package/dist/types/ReferenceType.js.map +1 -0
  209. package/dist/types/ReferenceType.spec.d.ts +1 -0
  210. package/dist/types/ReferenceType.spec.js +122 -0
  211. package/dist/types/ReferenceType.spec.js.map +1 -0
  212. package/dist/types/StringType.d.ts +10 -4
  213. package/dist/types/StringType.js +16 -8
  214. package/dist/types/StringType.js.map +1 -1
  215. package/dist/types/StringType.spec.js +2 -2
  216. package/dist/types/StringType.spec.js.map +1 -1
  217. package/dist/types/UninitializedType.d.ts +6 -3
  218. package/dist/types/UninitializedType.js +14 -3
  219. package/dist/types/UninitializedType.js.map +1 -1
  220. package/dist/types/UnionType.d.ts +18 -0
  221. package/dist/types/UnionType.js +91 -0
  222. package/dist/types/UnionType.js.map +1 -0
  223. package/dist/types/UnionType.spec.d.ts +1 -0
  224. package/dist/types/UnionType.spec.js +103 -0
  225. package/dist/types/UnionType.spec.js.map +1 -0
  226. package/dist/types/VoidType.d.ts +7 -4
  227. package/dist/types/VoidType.js +13 -8
  228. package/dist/types/VoidType.js.map +1 -1
  229. package/dist/types/VoidType.spec.js +2 -2
  230. package/dist/types/VoidType.spec.js.map +1 -1
  231. package/dist/types/helper.spec.d.ts +1 -0
  232. package/dist/types/helper.spec.js +130 -0
  233. package/dist/types/helper.spec.js.map +1 -0
  234. package/dist/types/helpers.d.ts +19 -0
  235. package/dist/types/helpers.js +131 -0
  236. package/dist/types/helpers.js.map +1 -0
  237. package/dist/types/index.d.ts +22 -0
  238. package/dist/types/index.js +39 -0
  239. package/dist/types/index.js.map +1 -0
  240. package/dist/util.d.ts +9 -8
  241. package/dist/util.js +78 -32
  242. package/dist/util.js.map +1 -1
  243. package/dist/validators/ClassValidator.d.ts +0 -4
  244. package/dist/validators/ClassValidator.js +6 -30
  245. package/dist/validators/ClassValidator.js.map +1 -1
  246. package/package.json +2 -1
  247. package/dist/types/CustomType.d.ts +0 -9
  248. package/dist/types/CustomType.js +0 -32
  249. package/dist/types/CustomType.js.map +0 -1
@@ -242,14 +242,24 @@ class Parser {
242
242
  */
243
243
  interfaceFieldStatement() {
244
244
  const name = this.identifier(...TokenKind_1.AllowedProperties);
245
+ const [asToken, typeExpression] = this.consumeAsTokenAndTypeExpression();
246
+ return new Statement_1.InterfaceFieldStatement(name, asToken, typeExpression);
247
+ }
248
+ consumeAsTokenAndTypeExpression() {
245
249
  let asToken = this.consumeToken(TokenKind_1.TokenKind.As);
246
- let typeToken = this.typeToken();
247
- const type = util_1.util.tokenToBscType(typeToken);
248
- if (!type) {
249
- this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, typeToken.text)), { range: typeToken.range }));
250
- throw this.lastDiagnosticAsError();
250
+ let typeExpression;
251
+ if (asToken) {
252
+ //if there's nothing after the `as`, add a diagnostic and continue
253
+ if (this.checkEndOfStatement()) {
254
+ this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(asToken.text)), { range: asToken.range }));
255
+ //consume the statement separator
256
+ this.consumeStatementSeparators();
257
+ }
258
+ else {
259
+ typeExpression = this.typeExpression();
260
+ }
251
261
  }
252
- return new Statement_1.InterfaceFieldStatement(name, asToken, typeToken, type);
262
+ return [asToken, typeExpression];
253
263
  }
254
264
  /**
255
265
  * Create a new InterfaceMethodStatement. This should only be called from within `interfaceDeclaration()`
@@ -260,18 +270,14 @@ class Parser {
260
270
  const leftParen = this.consumeToken(TokenKind_1.TokenKind.LeftParen);
261
271
  const params = [];
262
272
  const rightParen = this.consumeToken(TokenKind_1.TokenKind.RightParen);
263
- let asToken = null;
264
- let returnTypeToken = null;
273
+ // let asToken = null as Token;
274
+ // let returnTypeExpression: TypeExpression;
275
+ let asToken;
276
+ let returnTypeExpression;
265
277
  if (this.check(TokenKind_1.TokenKind.As)) {
266
- asToken = this.advance();
267
- returnTypeToken = this.typeToken();
268
- const returnType = util_1.util.tokenToBscType(returnTypeToken);
269
- if (!returnType) {
270
- this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, returnTypeToken.text)), { range: returnTypeToken.range }));
271
- throw this.lastDiagnosticAsError();
272
- }
278
+ [asToken, returnTypeExpression] = this.consumeAsTokenAndTypeExpression();
273
279
  }
274
- return new Statement_1.InterfaceMethodStatement(functionType, name, leftParen, params, rightParen, asToken, returnTypeToken, util_1.util.tokenToBscType(returnTypeToken));
280
+ return new Statement_1.InterfaceMethodStatement(functionType, name, leftParen, params, rightParen, asToken, returnTypeExpression);
275
281
  }
276
282
  interfaceDeclaration() {
277
283
  this.warnIfNotBrighterScriptMode('interface declarations');
@@ -282,7 +288,12 @@ class Parser {
282
288
  let parentInterfaceName;
283
289
  if (this.peek().text.toLowerCase() === 'extends') {
284
290
  extendsToken = this.advance();
285
- parentInterfaceName = this.getNamespacedVariableNameExpression();
291
+ if (this.checkEndOfStatement()) {
292
+ this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(extendsToken.text)), { range: extendsToken.range }));
293
+ }
294
+ else {
295
+ parentInterfaceName = this.typeExpression();
296
+ }
286
297
  }
287
298
  this.consumeStatementSeparators();
288
299
  //gather up all interface members (Fields, Methods)
@@ -396,7 +407,12 @@ class Parser {
396
407
  //see if the class inherits from parent
397
408
  if (this.peek().text.toLowerCase() === 'extends') {
398
409
  extendsKeyword = this.advance();
399
- parentClassName = this.getNamespacedVariableNameExpression();
410
+ if (this.checkEndOfStatement()) {
411
+ this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(extendsKeyword.text)), { range: extendsKeyword.range }));
412
+ }
413
+ else {
414
+ parentClassName = this.typeExpression();
415
+ }
400
416
  }
401
417
  //ensure statement separator
402
418
  this.consumeStatementSeparators();
@@ -466,15 +482,10 @@ class Parser {
466
482
  fieldDeclaration(accessModifier) {
467
483
  let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
468
484
  let asToken;
469
- let fieldType;
485
+ let fieldTypeExpression;
470
486
  //look for `as SOME_TYPE`
471
487
  if (this.check(TokenKind_1.TokenKind.As)) {
472
- asToken = this.advance();
473
- fieldType = this.typeToken();
474
- //no field type specified
475
- if (!util_1.util.tokenToBscType(fieldType)) {
476
- this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedValidTypeToFollowAsKeyword()), { range: this.peek().range }));
477
- }
488
+ [asToken, fieldTypeExpression] = this.consumeAsTokenAndTypeExpression();
478
489
  }
479
490
  let initialValue;
480
491
  let equal;
@@ -483,10 +494,10 @@ class Parser {
483
494
  equal = this.advance();
484
495
  initialValue = this.expression();
485
496
  }
486
- return new Statement_1.FieldStatement(accessModifier, name, asToken, fieldType, equal, initialValue);
497
+ return new Statement_1.FieldStatement(accessModifier, name, asToken, fieldTypeExpression, equal, initialValue);
487
498
  }
488
499
  functionDeclaration(isAnonymous, checkIdentifier = true, onlyCallableAsMember = false) {
489
- var _a, _b;
500
+ var _a;
490
501
  let previousCallExpressions = this.callExpressions;
491
502
  this.callExpressions = [];
492
503
  try {
@@ -533,7 +544,7 @@ class Parser {
533
544
  }
534
545
  let params = [];
535
546
  let asToken;
536
- let typeToken;
547
+ let typeExpression;
537
548
  if (!this.check(TokenKind_1.TokenKind.RightParen)) {
538
549
  do {
539
550
  if (params.length >= Expression_1.CallExpression.MaximumArguments) {
@@ -544,11 +555,7 @@ class Parser {
544
555
  }
545
556
  let rightParen = this.advance();
546
557
  if (this.check(TokenKind_1.TokenKind.As)) {
547
- asToken = this.advance();
548
- typeToken = this.typeToken();
549
- if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript)) {
550
- this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.invalidFunctionReturnType((_a = typeToken.text) !== null && _a !== void 0 ? _a : '')), { range: typeToken.range }));
551
- }
558
+ [asToken, typeExpression] = this.consumeAsTokenAndTypeExpression();
552
559
  }
553
560
  params.reduce((haveFoundOptional, param) => {
554
561
  if (haveFoundOptional && !param.defaultValue) {
@@ -559,12 +566,7 @@ class Parser {
559
566
  this.consumeStatementSeparators(true);
560
567
  let func = new Expression_1.FunctionExpression(params, undefined, //body
561
568
  functionType, undefined, //ending keyword
562
- leftParen, rightParen, asToken, typeToken);
563
- // add the function to the relevant symbol tables
564
- if (!onlyCallableAsMember && name) {
565
- const funcType = func.getFunctionType();
566
- funcType.setName(name.text);
567
- }
569
+ leftParen, rightParen, asToken, typeExpression);
568
570
  this._references.functionExpressions.push(func);
569
571
  //support ending the function with `end sub` OR `end function`
570
572
  func.body = this.block();
@@ -572,7 +574,7 @@ class Parser {
572
574
  if (!func.body) {
573
575
  func.body = new Statement_1.Block([], util_1.util.createRangeFromPositions(func.range.start, func.range.start));
574
576
  }
575
- func.body.symbolTable = new SymbolTable_1.SymbolTable(`Block: Function '${(_b = name === null || name === void 0 ? void 0 : name.text) !== null && _b !== void 0 ? _b : ''}'`, () => func.getSymbolTable());
577
+ func.body.symbolTable = new SymbolTable_1.SymbolTable(`Block: Function '${(_a = name === null || name === void 0 ? void 0 : name.text) !== null && _a !== void 0 ? _a : ''}'`, () => func.getSymbolTable());
576
578
  if (!func.body) {
577
579
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.callableBlockMissingEndKeyword(functionTypeText)), { range: this.peek().range }));
578
580
  throw this.lastDiagnosticAsError();
@@ -611,22 +613,19 @@ class Parser {
611
613
  let name = this.advance();
612
614
  // force the name into an identifier so the AST makes some sense
613
615
  name.kind = TokenKind_1.TokenKind.Identifier;
614
- let typeToken;
616
+ let typeExpression;
615
617
  let defaultValue;
618
+ let equalToken;
616
619
  // parse argument default value
617
- if (this.match(TokenKind_1.TokenKind.Equal)) {
620
+ if ((equalToken = this.consumeTokenIf(TokenKind_1.TokenKind.Equal))) {
618
621
  // it seems any expression is allowed here -- including ones that operate on other arguments!
619
- defaultValue = this.expression();
622
+ defaultValue = this.expression(false);
620
623
  }
621
624
  let asToken = null;
622
625
  if (this.check(TokenKind_1.TokenKind.As)) {
623
- asToken = this.advance();
624
- typeToken = this.typeToken();
625
- if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript)) {
626
- this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, typeToken.text)), { range: typeToken.range }));
627
- }
626
+ [asToken, typeExpression] = this.consumeAsTokenAndTypeExpression();
628
627
  }
629
- return new Expression_1.FunctionParameterExpression(name, typeToken, defaultValue, asToken);
628
+ return new Expression_1.FunctionParameterExpression(name, equalToken, defaultValue, asToken, typeExpression);
630
629
  }
631
630
  assignment() {
632
631
  let name = this.advance();
@@ -863,7 +862,7 @@ class Parser {
863
862
  this.warnIfNotBrighterScriptMode('namespace');
864
863
  let keyword = this.advance();
865
864
  this.namespaceAndFunctionDepth++;
866
- let name = this.getNamespacedVariableNameExpression();
865
+ let name = this.identifyingExpression();
867
866
  //set the current namespace name
868
867
  let result = new Statement_1.NamespaceStatement(keyword, name, null, null);
869
868
  this.globalTerminators.push([TokenKind_1.TokenKind.EndNamespace]);
@@ -889,8 +888,9 @@ class Parser {
889
888
  /**
890
889
  * Get an expression with identifiers separated by periods. Useful for namespaces and class extends
891
890
  */
892
- getNamespacedVariableNameExpression() {
893
- let firstIdentifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(this.previous().text), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
891
+ identifyingExpression(allowedTokenKinds) {
892
+ allowedTokenKinds = allowedTokenKinds !== null && allowedTokenKinds !== void 0 ? allowedTokenKinds : this.allowedLocalIdentifiers;
893
+ let firstIdentifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(this.previous().text), TokenKind_1.TokenKind.Identifier, ...allowedTokenKinds);
894
894
  let expr;
895
895
  if (firstIdentifier) {
896
896
  // force it into an identifier so the AST makes some sense
@@ -903,7 +903,7 @@ class Parser {
903
903
  if (!dot) {
904
904
  break;
905
905
  }
906
- let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers, ...TokenKind_1.AllowedProperties);
906
+ let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...allowedTokenKinds, ...TokenKind_1.AllowedProperties);
907
907
  if (!identifier) {
908
908
  break;
909
909
  }
@@ -912,7 +912,7 @@ class Parser {
912
912
  expr = new Expression_1.DottedGetExpression(expr, identifier, dot);
913
913
  }
914
914
  }
915
- return new Expression_1.NamespacedVariableNameExpression(expr);
915
+ return expr;
916
916
  }
917
917
  /**
918
918
  * Add an 'unexpected token' diagnostic for any token found between current and the first stopToken found.
@@ -1562,8 +1562,26 @@ class Parser {
1562
1562
  }
1563
1563
  this.pendingAnnotations = parentAnnotations;
1564
1564
  }
1565
- expression() {
1566
- const expression = this.anonymousFunction();
1565
+ expression(findTypeCast = true) {
1566
+ let expression = this.anonymousFunction();
1567
+ let asToken;
1568
+ let typeExpression;
1569
+ if (findTypeCast) {
1570
+ do {
1571
+ if (this.check(TokenKind_1.TokenKind.As)) {
1572
+ // Check if this expression is wrapped in any type casts
1573
+ // allows for multiple casts:
1574
+ // myVal = foo() as dynamic as string
1575
+ [asToken, typeExpression] = this.consumeAsTokenAndTypeExpression();
1576
+ if (asToken && typeExpression) {
1577
+ expression = new Expression_1.TypeCastExpression(expression, asToken, typeExpression);
1578
+ }
1579
+ }
1580
+ else {
1581
+ break;
1582
+ }
1583
+ } while (asToken && typeExpression);
1584
+ }
1567
1585
  this._references.expressions.add(expression);
1568
1586
  return expression;
1569
1587
  }
@@ -1676,7 +1694,7 @@ class Parser {
1676
1694
  newExpression() {
1677
1695
  this.warnIfNotBrighterScriptMode(`using 'new' keyword to construct a class`);
1678
1696
  let newToken = this.advance();
1679
- let nameExpr = this.getNamespacedVariableNameExpression();
1697
+ let nameExpr = this.identifyingExpression();
1680
1698
  let leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), TokenKind_1.TokenKind.LeftParen, TokenKind_1.TokenKind.QuestionLeftParen);
1681
1699
  let call = this.finishCall(leftParen, nameExpr);
1682
1700
  //pop the call from the callExpressions list because this is technically something else
@@ -1786,32 +1804,53 @@ class Parser {
1786
1804
  return expression;
1787
1805
  }
1788
1806
  /**
1789
- * Tries to get the next token as a type
1790
- * Allows for built-in types (double, string, etc.) or namespaced custom types in Brighterscript mode
1791
- * Will return a token of whatever is next to be parsed
1807
+ * Creates a TypeExpression, which wraps standard ASTNodes that represent a BscType
1792
1808
  */
1793
- typeToken() {
1794
- let typeToken;
1795
- if (this.checkAny(...TokenKind_1.DeclarableTypes)) {
1796
- // Token is a built in type
1797
- typeToken = this.advance();
1798
- }
1799
- else if (this.options.mode === ParseMode.BrighterScript) {
1800
- try {
1801
- // see if we can get a namespaced identifer
1802
- const qualifiedType = this.getNamespacedVariableNameExpression();
1803
- typeToken = (0, creators_1.createToken)(TokenKind_1.TokenKind.Identifier, qualifiedType.getName(this.options.mode), qualifiedType.range);
1809
+ typeExpression() {
1810
+ const changedTokens = [];
1811
+ try {
1812
+ let expr = this.getTypeExpressionPart(changedTokens);
1813
+ while (this.matchAny(TokenKind_1.TokenKind.Or)) {
1814
+ let operator = this.previous();
1815
+ let right = this.getTypeExpressionPart(changedTokens);
1816
+ if (right) {
1817
+ expr = new Expression_1.BinaryExpression(expr, operator, right);
1818
+ }
1819
+ else {
1820
+ break;
1821
+ }
1804
1822
  }
1805
- catch (_a) {
1806
- //could not get an identifier - just get whatever's next
1807
- typeToken = this.advance();
1823
+ if (expr) {
1824
+ return new Expression_1.TypeExpression(expr);
1808
1825
  }
1809
1826
  }
1827
+ catch (error) {
1828
+ // Something went wrong - reset the kind to what it was previously
1829
+ for (const changedToken of changedTokens) {
1830
+ changedToken.token.kind = changedToken.oldKind;
1831
+ }
1832
+ throw error;
1833
+ }
1834
+ }
1835
+ getTypeExpressionPart(changedTokens) {
1836
+ let expr;
1837
+ if (this.checkAny(...TokenKind_1.DeclarableTypes)) {
1838
+ // if this is just a type, just use directly
1839
+ expr = new Expression_1.VariableExpression(this.advance());
1840
+ }
1810
1841
  else {
1811
- // just get whatever's next
1812
- typeToken = this.advance();
1842
+ if (this.checkAny(...TokenKind_1.AllowedTypeIdentifiers)) {
1843
+ // Since the next token is allowed as a type identifier, change the kind
1844
+ let nextToken = this.peek();
1845
+ changedTokens.push({ token: nextToken, oldKind: nextToken.kind });
1846
+ nextToken.kind = TokenKind_1.TokenKind.Identifier;
1847
+ }
1848
+ expr = this.identifyingExpression(TokenKind_1.AllowedTypeIdentifiers);
1849
+ if (expr) {
1850
+ this._references.expressions.add(expr);
1851
+ }
1813
1852
  }
1814
- return typeToken;
1853
+ return expr;
1815
1854
  }
1816
1855
  primary() {
1817
1856
  switch (true) {
@@ -2028,6 +2067,14 @@ class Parser {
2028
2067
  throw error;
2029
2068
  }
2030
2069
  }
2070
+ /**
2071
+ * Consume next token IF it matches the specified kind. Otherwise, do nothing and return undefined
2072
+ */
2073
+ consumeTokenIf(tokenKind) {
2074
+ if (this.match(tokenKind)) {
2075
+ return this.previous();
2076
+ }
2077
+ }
2031
2078
  consumeToken(tokenKind) {
2032
2079
  return this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedToken(tokenKind), tokenKind);
2033
2080
  }
@@ -2219,7 +2266,7 @@ class Parser {
2219
2266
  ClassStatement: s => {
2220
2267
  this._references.classStatements.push(s);
2221
2268
  },
2222
- ClassFieldStatement: s => {
2269
+ FieldStatement: s => {
2223
2270
  if (s.initialValue) {
2224
2271
  this._references.expressions.add(s.initialValue);
2225
2272
  }