brighterscript 0.66.0-alpha.2 → 0.66.0-alpha.3

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 (124) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +0 -6
  3. package/dist/BsConfig.d.ts +0 -5
  4. package/dist/Cache.js +3 -3
  5. package/dist/Cache.js.map +1 -1
  6. package/dist/CodeActionUtil.d.ts +2 -2
  7. package/dist/DiagnosticCollection.js +8 -5
  8. package/dist/DiagnosticCollection.js.map +1 -1
  9. package/dist/DiagnosticMessages.d.ts +6 -1
  10. package/dist/DiagnosticMessages.js +5 -0
  11. package/dist/DiagnosticMessages.js.map +1 -1
  12. package/dist/FunctionScope.d.ts +1 -1
  13. package/dist/LanguageServer.d.ts +5 -1
  14. package/dist/LanguageServer.js +7 -0
  15. package/dist/LanguageServer.js.map +1 -1
  16. package/dist/Logger.d.ts +2 -1
  17. package/dist/Logger.js +10 -2
  18. package/dist/Logger.js.map +1 -1
  19. package/dist/Program.d.ts +1 -3
  20. package/dist/Program.js +4 -12
  21. package/dist/Program.js.map +1 -1
  22. package/dist/ProgramBuilder.js +1 -1
  23. package/dist/ProgramBuilder.js.map +1 -1
  24. package/dist/Scope.d.ts +11 -6
  25. package/dist/Scope.js +77 -93
  26. package/dist/Scope.js.map +1 -1
  27. package/dist/SymbolTable.d.ts +11 -5
  28. package/dist/SymbolTable.js +21 -8
  29. package/dist/SymbolTable.js.map +1 -1
  30. package/dist/astUtils/reflection.d.ts +4 -0
  31. package/dist/astUtils/reflection.js +9 -1
  32. package/dist/astUtils/reflection.js.map +1 -1
  33. package/dist/bscPlugin/hover/HoverProcessor.d.ts +5 -0
  34. package/dist/bscPlugin/hover/HoverProcessor.js +108 -77
  35. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  36. package/dist/bscPlugin/hover/HoverProcessor.spec.js +83 -29
  37. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  38. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +0 -4
  39. package/dist/bscPlugin/validation/BrsFileValidator.js +10 -16
  40. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  41. package/dist/bscPlugin/validation/ScopeValidator.d.ts +4 -0
  42. package/dist/bscPlugin/validation/ScopeValidator.js +77 -42
  43. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  44. package/dist/bscPlugin/validation/ScopeValidator.spec.js +684 -0
  45. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
  46. package/dist/cli.js +95 -13
  47. package/dist/cli.js.map +1 -1
  48. package/dist/files/BrsFile.Class.spec.js +5 -0
  49. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  50. package/dist/files/BrsFile.d.ts +1 -11
  51. package/dist/files/BrsFile.js +9 -101
  52. package/dist/files/BrsFile.js.map +1 -1
  53. package/dist/files/BrsFile.spec.js +3 -267
  54. package/dist/files/BrsFile.spec.js.map +1 -1
  55. package/dist/globalCallables.js +78 -78
  56. package/dist/globalCallables.js.map +1 -1
  57. package/dist/index.d.ts +1 -0
  58. package/dist/index.js +1 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/interfaces.d.ts +7 -5
  61. package/dist/interfaces.js.map +1 -1
  62. package/dist/parser/Expression.d.ts +4 -3
  63. package/dist/parser/Expression.js +32 -9
  64. package/dist/parser/Expression.js.map +1 -1
  65. package/dist/parser/SGParser.d.ts +2 -2
  66. package/dist/parser/Statement.d.ts +11 -6
  67. package/dist/parser/Statement.js +54 -21
  68. package/dist/parser/Statement.js.map +1 -1
  69. package/dist/parser/tests/expression/TernaryExpression.spec.js +2 -2
  70. package/dist/types/BaseFunctionType.d.ts +8 -0
  71. package/dist/types/BaseFunctionType.js +25 -0
  72. package/dist/types/BaseFunctionType.js.map +1 -0
  73. package/dist/types/BooleanType.js +2 -1
  74. package/dist/types/BooleanType.js.map +1 -1
  75. package/dist/types/BscTypeKind.d.ts +1 -0
  76. package/dist/types/BscTypeKind.js +1 -0
  77. package/dist/types/BscTypeKind.js.map +1 -1
  78. package/dist/types/ClassType.js +1 -1
  79. package/dist/types/ClassType.js.map +1 -1
  80. package/dist/types/DoubleType.js +1 -0
  81. package/dist/types/DoubleType.js.map +1 -1
  82. package/dist/types/EnumType.d.ts +20 -4
  83. package/dist/types/EnumType.js +14 -2
  84. package/dist/types/EnumType.js.map +1 -1
  85. package/dist/types/FloatType.js +1 -0
  86. package/dist/types/FloatType.js.map +1 -1
  87. package/dist/types/FunctionType.d.ts +6 -19
  88. package/dist/types/FunctionType.js +12 -44
  89. package/dist/types/FunctionType.js.map +1 -1
  90. package/dist/types/IntegerType.js +1 -0
  91. package/dist/types/IntegerType.js.map +1 -1
  92. package/dist/types/InterfaceType.js +3 -3
  93. package/dist/types/InterfaceType.js.map +1 -1
  94. package/dist/types/InvalidType.d.ts +1 -0
  95. package/dist/types/InvalidType.js +3 -1
  96. package/dist/types/InvalidType.js.map +1 -1
  97. package/dist/types/LongIntegerType.js +1 -0
  98. package/dist/types/LongIntegerType.js.map +1 -1
  99. package/dist/types/ObjectType.js +2 -9
  100. package/dist/types/ObjectType.js.map +1 -1
  101. package/dist/types/ReferenceType.spec.js +6 -6
  102. package/dist/types/ReferenceType.spec.js.map +1 -1
  103. package/dist/types/StringType.js +4 -1
  104. package/dist/types/StringType.js.map +1 -1
  105. package/dist/types/TypedFunctionType.d.ts +27 -0
  106. package/dist/types/TypedFunctionType.js +69 -0
  107. package/dist/types/TypedFunctionType.js.map +1 -0
  108. package/dist/types/TypedFunctionType.spec.d.ts +1 -0
  109. package/dist/types/TypedFunctionType.spec.js +23 -0
  110. package/dist/types/TypedFunctionType.spec.js.map +1 -0
  111. package/dist/types/UnionType.js +1 -1
  112. package/dist/types/UnionType.js.map +1 -1
  113. package/dist/types/VoidType.js +2 -1
  114. package/dist/types/VoidType.js.map +1 -1
  115. package/dist/types/index.d.ts +1 -1
  116. package/dist/types/index.js +1 -1
  117. package/dist/types/index.js.map +1 -1
  118. package/dist/util.d.ts +22 -5
  119. package/dist/util.js +245 -79
  120. package/dist/util.js.map +1 -1
  121. package/package.json +3 -1
  122. package/dist/types/FunctionType.spec.js +0 -23
  123. package/dist/types/FunctionType.spec.js.map +0 -1
  124. /package/dist/{types/FunctionType.spec.d.ts → bscPlugin/validation/ScopeValidator.spec.d.ts} +0 -0
@@ -12,7 +12,8 @@ class VoidType extends BscType_1.BscType {
12
12
  }
13
13
  isTypeCompatible(targetType) {
14
14
  return ((0, reflection_1.isVoidType)(targetType) ||
15
- (0, reflection_1.isDynamicType)(targetType));
15
+ (0, reflection_1.isDynamicType)(targetType) ||
16
+ (0, reflection_1.isObjectType)(targetType));
16
17
  }
17
18
  toString() {
18
19
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"VoidType.js","sourceRoot":"","sources":["../../src/types/VoidType.ts"],"names":[],"mappings":";;;AAAA,uDAAmE;AACnE,uCAAoC;AACpC,+CAA4C;AAE5C,MAAa,QAAS,SAAQ,iBAAO;IACjC,YACW,QAAiB;QAExB,KAAK,EAAE,CAAC;QAFD,aAAQ,GAAR,QAAQ,CAAS;QAKZ,SAAI,GAAG,yBAAW,CAAC,QAAQ,CAAC;IAF5C,CAAC;IAMM,gBAAgB,CAAC,UAAmB;QACvC,OAAO,CACH,IAAA,uBAAU,EAAC,UAAU,CAAC;YACtB,IAAA,0BAAa,EAAC,UAAU,CAAC,CAC5B,CAAC;IACN,CAAC;IAEM,QAAQ;;QACX,OAAO,MAAA,IAAI,CAAC,QAAQ,mCAAI,MAAM,CAAC;IACnC,CAAC;IAEM,YAAY;QACf,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;IAEM,OAAO,CAAC,UAAmB;QAC9B,OAAO,IAAA,uBAAU,EAAC,UAAU,CAAC,CAAC;IAClC,CAAC;;AA5BL,4BA6BC;AApBiB,iBAAQ,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"VoidType.js","sourceRoot":"","sources":["../../src/types/VoidType.ts"],"names":[],"mappings":";;;AAAA,uDAAiF;AACjF,uCAAoC;AACpC,+CAA4C;AAE5C,MAAa,QAAS,SAAQ,iBAAO;IACjC,YACW,QAAiB;QAExB,KAAK,EAAE,CAAC;QAFD,aAAQ,GAAR,QAAQ,CAAS;QAKZ,SAAI,GAAG,yBAAW,CAAC,QAAQ,CAAC;IAF5C,CAAC;IAMM,gBAAgB,CAAC,UAAmB;QACvC,OAAO,CACH,IAAA,uBAAU,EAAC,UAAU,CAAC;YACtB,IAAA,0BAAa,EAAC,UAAU,CAAC;YACzB,IAAA,yBAAY,EAAC,UAAU,CAAC,CAC3B,CAAC;IACN,CAAC;IAEM,QAAQ;;QACX,OAAO,MAAA,IAAI,CAAC,QAAQ,mCAAI,MAAM,CAAC;IACnC,CAAC;IAEM,YAAY;QACf,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;IAEM,OAAO,CAAC,UAAmB;QAC9B,OAAO,IAAA,uBAAU,EAAC,UAAU,CAAC,CAAC;IAClC,CAAC;;AA7BL,4BA8BC;AArBiB,iBAAQ,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC"}
@@ -6,7 +6,7 @@ export * from './DoubleType';
6
6
  export * from './DynamicType';
7
7
  export * from './EnumType';
8
8
  export * from './FloatType';
9
- export * from './FunctionType';
9
+ export * from './TypedFunctionType';
10
10
  export * from './helpers';
11
11
  export * from './InheritableType';
12
12
  export * from './IntegerType';
@@ -22,7 +22,7 @@ __exportStar(require("./DoubleType"), exports);
22
22
  __exportStar(require("./DynamicType"), exports);
23
23
  __exportStar(require("./EnumType"), exports);
24
24
  __exportStar(require("./FloatType"), exports);
25
- __exportStar(require("./FunctionType"), exports);
25
+ __exportStar(require("./TypedFunctionType"), exports);
26
26
  __exportStar(require("./helpers"), exports);
27
27
  __exportStar(require("./InheritableType"), exports);
28
28
  __exportStar(require("./IntegerType"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,gDAA8B;AAC9B,4CAA0B;AAC1B,8CAA4B;AAC5B,+CAA6B;AAC7B,gDAA8B;AAC9B,6CAA2B;AAC3B,8CAA4B;AAC5B,iDAA+B;AAC/B,4CAA0B;AAC1B,oDAAkC;AAClC,gDAA8B;AAC9B,kDAAgC;AAChC,gDAA8B;AAC9B,oDAAkC;AAClC,kDAAgC;AAChC,+CAA6B;AAC7B,kDAAgC;AAChC,+CAA6B;AAC7B,sDAAoC;AACpC,8CAA4B;AAC5B,6CAA2B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,gDAA8B;AAC9B,4CAA0B;AAC1B,8CAA4B;AAC5B,+CAA6B;AAC7B,gDAA8B;AAC9B,6CAA2B;AAC3B,8CAA4B;AAC5B,sDAAoC;AACpC,4CAA0B;AAC1B,oDAAkC;AAClC,gDAA8B;AAC9B,kDAAgC;AAChC,gDAA8B;AAC9B,oDAAkC;AAClC,kDAAgC;AAChC,+CAA6B;AAC7B,kDAAgC;AAChC,+CAA6B;AAC7B,sDAAoC;AACpC,8CAA4B;AAC5B,6CAA2B"}
package/dist/util.d.ts CHANGED
@@ -5,7 +5,6 @@ import { BooleanType } from './types/BooleanType';
5
5
  import { DoubleType } from './types/DoubleType';
6
6
  import { DynamicType } from './types/DynamicType';
7
7
  import { FloatType } from './types/FloatType';
8
- import { FunctionType } from './types/FunctionType';
9
8
  import { IntegerType } from './types/IntegerType';
10
9
  import { InvalidType } from './types/InvalidType';
11
10
  import { LongIntegerType } from './types/LongIntegerType';
@@ -18,7 +17,10 @@ import type { Identifier, Locatable, Token } from './lexer/Token';
18
17
  import { SourceNode } from 'source-map';
19
18
  import type { BrsFile } from './files/BrsFile';
20
19
  import type { XmlFile } from './files/XmlFile';
21
- import type { Expression, Statement } from './parser/AstNode';
20
+ import type { AstNode } from './parser/AstNode';
21
+ import { type Expression, type Statement } from './parser/AstNode';
22
+ import type { BscType } from './types/BscType';
23
+ import { FunctionType } from './types/FunctionType';
22
24
  export declare class Util {
23
25
  clearConsole(): void;
24
26
  /**
@@ -288,7 +290,17 @@ export declare class Util {
288
290
  /**
289
291
  * Convert a token into a BscType
290
292
  */
291
- tokenToBscType(token: Token): DynamicType | FloatType | IntegerType | DoubleType | LongIntegerType | StringType | BooleanType | InvalidType | VoidType | FunctionType | ObjectType;
293
+ tokenToBscType(token: Token): DynamicType | ObjectType | FloatType | IntegerType | DoubleType | LongIntegerType | StringType | BooleanType | InvalidType | VoidType | FunctionType;
294
+ isNumberType(targetType: BscType): boolean;
295
+ /**
296
+ * Return the type of the result of a binary operator
297
+ * Note: compound assignments (eg. +=) internally use a binary expression, so that's why TokenKind.PlusEqual, etc. are here too
298
+ */
299
+ binaryOperatorResultType(leftType: BscType, operator: Token, rightType: BscType): BscType;
300
+ /**
301
+ * Return the type of the result of a binary operator
302
+ */
303
+ unaryOperatorResultType(operator: Token, exprType: BscType): BscType;
292
304
  /**
293
305
  * Get the extension for the given file path. Basically the part after the final dot, except for
294
306
  * `d.bs` which is treated as single extension
@@ -322,7 +334,7 @@ export declare class Util {
322
334
  * @param relatedInformationFallbackLocation a default location to use for all `relatedInformation` entries that are missing a location
323
335
  */
324
336
  toDiagnostic(diagnostic: Diagnostic | BsDiagnostic, relatedInformationFallbackLocation: string): {
325
- severity: import("vscode-languageserver-types").DiagnosticSeverity;
337
+ severity: import("vscode-languageserver").DiagnosticSeverity;
326
338
  range: Range;
327
339
  message: string;
328
340
  relatedInformation: {
@@ -359,8 +371,13 @@ export declare class Util {
359
371
  * @param node any ast expression
360
372
  * @returns an array of the parts of the dotted get. If not fully a dotted get, then returns undefined
361
373
  */
362
- getAllDottedGetParts(node: Expression | Statement): Identifier[] | undefined;
374
+ getAllDottedGetParts(node: AstNode): Identifier[] | undefined;
375
+ /**
376
+ * Given an expression, return all the DottedGet name parts as a string.
377
+ * Mostly used to convert namespaced item full names to a strings
378
+ */
363
379
  getAllDottedGetPartsAsString(node: Expression | Statement, parseMode?: ParseMode): string;
380
+ stringJoin(strings: string[], separator: string): string;
364
381
  /**
365
382
  * Break an expression into each part.
366
383
  */
package/dist/util.js CHANGED
@@ -13,7 +13,6 @@ const BooleanType_1 = require("./types/BooleanType");
13
13
  const DoubleType_1 = require("./types/DoubleType");
14
14
  const DynamicType_1 = require("./types/DynamicType");
15
15
  const FloatType_1 = require("./types/FloatType");
16
- const FunctionType_1 = require("./types/FunctionType");
17
16
  const IntegerType_1 = require("./types/IntegerType");
18
17
  const InvalidType_1 = require("./types/InvalidType");
19
18
  const LongIntegerType_1 = require("./types/LongIntegerType");
@@ -27,7 +26,9 @@ const reflection_1 = require("./astUtils/reflection");
27
26
  const visitors_1 = require("./astUtils/visitors");
28
27
  const source_map_1 = require("source-map");
29
28
  const requireRelative = require("require-relative");
29
+ const AstNode_1 = require("./parser/AstNode");
30
30
  const creators_1 = require("./astUtils/creators");
31
+ const FunctionType_1 = require("./types/FunctionType");
31
32
  class Util {
32
33
  clearConsole() {
33
34
  // process.stdout.write('\x1Bc');
@@ -315,7 +316,6 @@ class Util {
315
316
  config.allowBrighterScriptInBrightScript = config.allowBrighterScriptInBrightScript === true ? true : false;
316
317
  config.emitDefinitions = config.emitDefinitions === true ? true : false;
317
318
  config.removeParameterTypes = config.removeParameterTypes === true ? true : false;
318
- config.enableTypeValidation = config.enableTypeValidation === true ? true : false;
319
319
  if (typeof config.logLevel === 'string') {
320
320
  config.logLevel = Logger_1.LogLevel[config.logLevel.toLowerCase()];
321
321
  }
@@ -649,7 +649,7 @@ class Util {
649
649
  const diagnosticCode = typeof diagnostic.code === 'string' ? diagnostic.code.toLowerCase() : diagnostic.code;
650
650
  for (let flag of (_b = (_a = diagnostic.file) === null || _a === void 0 ? void 0 : _a.commentFlags) !== null && _b !== void 0 ? _b : []) {
651
651
  //this diagnostic is affected by this flag
652
- if (this.rangeContains(flag.affectedRange, diagnostic.range.start)) {
652
+ if (diagnostic.range && this.rangeContains(flag.affectedRange, diagnostic.range.start)) {
653
653
  //if the flag acts upon this diagnostic's code
654
654
  if (flag.codes === null || flag.codes.includes(diagnosticCode)) {
655
655
  return true;
@@ -938,8 +938,7 @@ class Util {
938
938
  case TokenKind_1.TokenKind.FloatLiteral:
939
939
  return FloatType_1.FloatType.instance;
940
940
  case TokenKind_1.TokenKind.Function:
941
- //TODO should there be a more generic function type without a signature that's assignable to all other function types?
942
- return new FunctionType_1.FunctionType(new DynamicType_1.DynamicType(token.text));
941
+ return new FunctionType_1.FunctionType(token.text);
943
942
  case TokenKind_1.TokenKind.Integer:
944
943
  return new IntegerType_1.IntegerType(token.text);
945
944
  case TokenKind_1.TokenKind.IntegerLiteral:
@@ -972,7 +971,7 @@ class Util {
972
971
  case 'float':
973
972
  return new FloatType_1.FloatType(token.text);
974
973
  case 'function':
975
- return new FunctionType_1.FunctionType(new DynamicType_1.DynamicType(token.text));
974
+ return new FunctionType_1.FunctionType(token.text);
976
975
  case 'integer':
977
976
  return new IntegerType_1.IntegerType(token.text);
978
977
  case 'invalid':
@@ -988,6 +987,157 @@ class Util {
988
987
  }
989
988
  }
990
989
  }
990
+ isNumberType(targetType) {
991
+ return (0, reflection_1.isIntegerType)(targetType) ||
992
+ (0, reflection_1.isFloatType)(targetType) ||
993
+ (0, reflection_1.isDoubleType)(targetType) ||
994
+ (0, reflection_1.isLongIntegerType)(targetType);
995
+ }
996
+ /**
997
+ * Return the type of the result of a binary operator
998
+ * Note: compound assignments (eg. +=) internally use a binary expression, so that's why TokenKind.PlusEqual, etc. are here too
999
+ */
1000
+ binaryOperatorResultType(leftType, operator, rightType) {
1001
+ let hasDouble = (0, reflection_1.isDoubleType)(leftType) || (0, reflection_1.isDoubleType)(rightType);
1002
+ let hasFloat = (0, reflection_1.isFloatType)(leftType) || (0, reflection_1.isFloatType)(rightType);
1003
+ let hasLongInteger = (0, reflection_1.isLongIntegerType)(leftType) || (0, reflection_1.isLongIntegerType)(rightType);
1004
+ let hasInvalid = (0, reflection_1.isInvalidType)(leftType) || (0, reflection_1.isInvalidType)(rightType);
1005
+ let bothNumbers = this.isNumberType(leftType) && this.isNumberType(rightType);
1006
+ let bothStrings = (0, reflection_1.isStringType)(leftType) && (0, reflection_1.isStringType)(rightType);
1007
+ let eitherBooleanOrNum = (this.isNumberType(leftType) || (0, reflection_1.isBooleanType)(leftType)) && (this.isNumberType(rightType) || (0, reflection_1.isBooleanType)(rightType));
1008
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
1009
+ switch (operator.kind) {
1010
+ // Math operators
1011
+ case TokenKind_1.TokenKind.Plus:
1012
+ case TokenKind_1.TokenKind.PlusEqual:
1013
+ if (bothStrings) {
1014
+ // "string" + "string" is the only binary expression allowed with strings
1015
+ return StringType_1.StringType.instance;
1016
+ }
1017
+ // eslint-disable-next-line no-fallthrough
1018
+ case TokenKind_1.TokenKind.Minus:
1019
+ case TokenKind_1.TokenKind.MinusEqual:
1020
+ case TokenKind_1.TokenKind.Star:
1021
+ case TokenKind_1.TokenKind.StarEqual:
1022
+ case TokenKind_1.TokenKind.Mod:
1023
+ if (bothNumbers) {
1024
+ if (hasDouble) {
1025
+ return DoubleType_1.DoubleType.instance;
1026
+ }
1027
+ else if (hasFloat) {
1028
+ return FloatType_1.FloatType.instance;
1029
+ }
1030
+ else if (hasLongInteger) {
1031
+ return LongIntegerType_1.LongIntegerType.instance;
1032
+ }
1033
+ return IntegerType_1.IntegerType.instance;
1034
+ }
1035
+ break;
1036
+ case TokenKind_1.TokenKind.Forwardslash:
1037
+ case TokenKind_1.TokenKind.ForwardslashEqual:
1038
+ if (bothNumbers) {
1039
+ if (hasDouble) {
1040
+ return DoubleType_1.DoubleType.instance;
1041
+ }
1042
+ else if (hasFloat) {
1043
+ return FloatType_1.FloatType.instance;
1044
+ }
1045
+ else if (hasLongInteger) {
1046
+ return LongIntegerType_1.LongIntegerType.instance;
1047
+ }
1048
+ return FloatType_1.FloatType.instance;
1049
+ }
1050
+ break;
1051
+ case TokenKind_1.TokenKind.Backslash:
1052
+ case TokenKind_1.TokenKind.BackslashEqual:
1053
+ if (bothNumbers) {
1054
+ if (hasLongInteger) {
1055
+ return LongIntegerType_1.LongIntegerType.instance;
1056
+ }
1057
+ return IntegerType_1.IntegerType.instance;
1058
+ }
1059
+ break;
1060
+ case TokenKind_1.TokenKind.Caret:
1061
+ if (bothNumbers) {
1062
+ if (hasDouble || hasLongInteger) {
1063
+ return DoubleType_1.DoubleType.instance;
1064
+ }
1065
+ else if (hasFloat) {
1066
+ return FloatType_1.FloatType.instance;
1067
+ }
1068
+ return IntegerType_1.IntegerType.instance;
1069
+ }
1070
+ break;
1071
+ // Bitshift operators
1072
+ case TokenKind_1.TokenKind.LeftShift:
1073
+ case TokenKind_1.TokenKind.LeftShiftEqual:
1074
+ case TokenKind_1.TokenKind.RightShift:
1075
+ case TokenKind_1.TokenKind.RightShiftEqual:
1076
+ if (bothNumbers) {
1077
+ if (hasLongInteger) {
1078
+ return LongIntegerType_1.LongIntegerType.instance;
1079
+ }
1080
+ // Bitshifts are allowed with non-integer numerics
1081
+ // but will always truncate to ints
1082
+ return IntegerType_1.IntegerType.instance;
1083
+ }
1084
+ break;
1085
+ // Comparison operators
1086
+ // All comparison operators result in boolean
1087
+ case TokenKind_1.TokenKind.Equal:
1088
+ case TokenKind_1.TokenKind.LessGreater:
1089
+ // = and <> can accept invalid
1090
+ if (hasInvalid || bothStrings || eitherBooleanOrNum) {
1091
+ return BooleanType_1.BooleanType.instance;
1092
+ }
1093
+ break;
1094
+ case TokenKind_1.TokenKind.Greater:
1095
+ case TokenKind_1.TokenKind.Less:
1096
+ case TokenKind_1.TokenKind.GreaterEqual:
1097
+ case TokenKind_1.TokenKind.LessEqual:
1098
+ if (bothStrings || bothNumbers) {
1099
+ return BooleanType_1.BooleanType.instance;
1100
+ }
1101
+ break;
1102
+ // Logical operators
1103
+ case TokenKind_1.TokenKind.Or:
1104
+ case TokenKind_1.TokenKind.And:
1105
+ if (eitherBooleanOrNum) {
1106
+ return BooleanType_1.BooleanType.instance;
1107
+ }
1108
+ break;
1109
+ }
1110
+ return DynamicType_1.DynamicType.instance;
1111
+ }
1112
+ /**
1113
+ * Return the type of the result of a binary operator
1114
+ */
1115
+ unaryOperatorResultType(operator, exprType) {
1116
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
1117
+ switch (operator.kind) {
1118
+ // Math operators
1119
+ case TokenKind_1.TokenKind.Minus:
1120
+ if (this.isNumberType(exprType)) {
1121
+ // a negative number will be the same type, eg, double->double, int->int, etc.
1122
+ return exprType;
1123
+ }
1124
+ break;
1125
+ case TokenKind_1.TokenKind.Not:
1126
+ if ((0, reflection_1.isBooleanType)(exprType)) {
1127
+ return BooleanType_1.BooleanType.instance;
1128
+ }
1129
+ else if (this.isNumberType(exprType)) {
1130
+ //numbers can be "notted"
1131
+ // by default they go to ints, except longints, which stay that way
1132
+ if ((0, reflection_1.isLongIntegerType)(exprType)) {
1133
+ return LongIntegerType_1.LongIntegerType.instance;
1134
+ }
1135
+ return IntegerType_1.IntegerType.instance;
1136
+ }
1137
+ break;
1138
+ }
1139
+ return DynamicType_1.DynamicType.instance;
1140
+ }
991
1141
  /**
992
1142
  * Get the extension for the given file path. Basically the part after the final dot, except for
993
1143
  * `d.bs` which is treated as single extension
@@ -1222,55 +1372,70 @@ class Util {
1222
1372
  * @returns an array of the parts of the dotted get. If not fully a dotted get, then returns undefined
1223
1373
  */
1224
1374
  getAllDottedGetParts(node) {
1375
+ //this is a hot function and has been optimized. Don't rewrite unless necessary
1225
1376
  const parts = [];
1226
1377
  let nextPart = node;
1227
- while (nextPart) {
1228
- if ((0, reflection_1.isAssignmentStatement)(node)) {
1229
- return [node.name];
1230
- }
1231
- else if ((0, reflection_1.isDottedGetExpression)(nextPart)) {
1232
- parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.name);
1233
- nextPart = nextPart.obj;
1234
- }
1235
- else if ((0, reflection_1.isCallExpression)(nextPart)) {
1236
- nextPart = nextPart.callee;
1237
- }
1238
- else if ((0, reflection_1.isTypeExpression)(nextPart)) {
1239
- nextPart = nextPart.expression;
1240
- }
1241
- else if ((0, reflection_1.isVariableExpression)(nextPart)) {
1242
- parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.name);
1243
- break;
1244
- }
1245
- else if ((0, reflection_1.isLiteralExpression)(nextPart)) {
1246
- parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.token);
1247
- break;
1248
- }
1249
- else if ((0, reflection_1.isIndexedGetExpression)(nextPart)) {
1250
- nextPart = nextPart.obj;
1251
- }
1252
- else if ((0, reflection_1.isFunctionParameterExpression)(nextPart)) {
1253
- return [nextPart.name];
1254
- }
1255
- else if ((0, reflection_1.isGroupingExpression)(nextPart)) {
1256
- parts.push((0, creators_1.createIdentifier)('()', nextPart.range));
1257
- break;
1258
- }
1259
- else {
1260
- //we found a non-DottedGet expression, so return because this whole operation is invalid.
1261
- return undefined;
1378
+ loop: while (nextPart) {
1379
+ switch (nextPart === null || nextPart === void 0 ? void 0 : nextPart.kind) {
1380
+ case AstNode_1.AstNodeKind.AssignmentStatement:
1381
+ return [node.name];
1382
+ case AstNode_1.AstNodeKind.DottedGetExpression:
1383
+ parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.name);
1384
+ nextPart = nextPart.obj;
1385
+ continue;
1386
+ case AstNode_1.AstNodeKind.CallExpression:
1387
+ nextPart = nextPart.callee;
1388
+ continue;
1389
+ case AstNode_1.AstNodeKind.TypeExpression:
1390
+ nextPart = nextPart.expression;
1391
+ continue;
1392
+ case AstNode_1.AstNodeKind.VariableExpression:
1393
+ parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.name);
1394
+ break loop;
1395
+ case AstNode_1.AstNodeKind.LiteralExpression:
1396
+ parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.token);
1397
+ break loop;
1398
+ case AstNode_1.AstNodeKind.IndexedGetExpression:
1399
+ nextPart = nextPart.obj;
1400
+ continue;
1401
+ case AstNode_1.AstNodeKind.FunctionParameterExpression:
1402
+ return [nextPart.name];
1403
+ case AstNode_1.AstNodeKind.GroupingExpression:
1404
+ parts.push((0, creators_1.createIdentifier)('()', nextPart.range));
1405
+ break loop;
1406
+ default:
1407
+ //we found a non-DottedGet expression, so return because this whole operation is invalid.
1408
+ return undefined;
1262
1409
  }
1263
1410
  }
1264
1411
  return parts.reverse();
1265
1412
  }
1413
+ /**
1414
+ * Given an expression, return all the DottedGet name parts as a string.
1415
+ * Mostly used to convert namespaced item full names to a strings
1416
+ */
1266
1417
  getAllDottedGetPartsAsString(node, parseMode = Parser_1.ParseMode.BrighterScript) {
1418
+ var _a, _b;
1419
+ //this is a hot function and has been optimized. Don't rewrite unless necessary
1420
+ /* eslint-disable no-var */
1421
+ var sep = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
1422
+ const parts = (_a = this.getAllDottedGetParts(node)) !== null && _a !== void 0 ? _a : [];
1423
+ var result = (_b = parts[0]) === null || _b === void 0 ? void 0 : _b.text;
1424
+ for (var i = 1; i < parts.length; i++) {
1425
+ result += sep + parts[i].text;
1426
+ }
1427
+ return result;
1428
+ /* eslint-enable no-var */
1429
+ }
1430
+ stringJoin(strings, separator) {
1267
1431
  var _a;
1268
- const sep = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
1269
- const hello = (_a = this.getAllDottedGetParts(node)) === null || _a === void 0 ? void 0 : _a.map(part => part.text).join(sep);
1270
- if (!hello) {
1271
- console.log(node);
1432
+ // eslint-disable-next-line no-var
1433
+ var result = (_a = strings[0]) !== null && _a !== void 0 ? _a : '';
1434
+ // eslint-disable-next-line no-var
1435
+ for (var i = 1; i < strings.length; i++) {
1436
+ result += separator + strings[i];
1272
1437
  }
1273
- return hello;
1438
+ return result;
1274
1439
  }
1275
1440
  /**
1276
1441
  * Break an expression into each part.
@@ -1301,36 +1466,37 @@ class Util {
1301
1466
  getDottedGetPath(expression) {
1302
1467
  let parts = [];
1303
1468
  let nextPart = expression;
1304
- while (nextPart) {
1305
- if ((0, reflection_1.isDottedGetExpression)(nextPart)) {
1306
- parts.unshift(nextPart);
1307
- nextPart = nextPart.obj;
1308
- }
1309
- else if ((0, reflection_1.isIndexedGetExpression)(nextPart) || (0, reflection_1.isXmlAttributeGetExpression)(nextPart)) {
1310
- nextPart = nextPart.obj;
1311
- parts = [];
1312
- }
1313
- else if ((0, reflection_1.isCallExpression)(nextPart) || (0, reflection_1.isCallfuncExpression)(nextPart)) {
1314
- nextPart = nextPart.callee;
1315
- parts = [];
1316
- }
1317
- else if ((0, reflection_1.isNewExpression)(nextPart)) {
1318
- nextPart = nextPart.call.callee;
1319
- parts = [];
1320
- }
1321
- else if ((0, reflection_1.isTypeExpression)(nextPart)) {
1322
- nextPart = nextPart.expression;
1323
- }
1324
- else if ((0, reflection_1.isVariableExpression)(nextPart)) {
1325
- parts.unshift(nextPart);
1326
- break;
1327
- }
1328
- else {
1329
- parts = [];
1330
- break;
1469
+ loop: while (nextPart) {
1470
+ switch (nextPart === null || nextPart === void 0 ? void 0 : nextPart.kind) {
1471
+ case AstNode_1.AstNodeKind.DottedGetExpression:
1472
+ parts.push(nextPart);
1473
+ nextPart = nextPart.obj;
1474
+ continue;
1475
+ case AstNode_1.AstNodeKind.IndexedGetExpression:
1476
+ case AstNode_1.AstNodeKind.XmlAttributeGetExpression:
1477
+ nextPart = nextPart.obj;
1478
+ parts = [];
1479
+ continue;
1480
+ case AstNode_1.AstNodeKind.CallExpression:
1481
+ case AstNode_1.AstNodeKind.CallfuncExpression:
1482
+ nextPart = nextPart.callee;
1483
+ parts = [];
1484
+ continue;
1485
+ case AstNode_1.AstNodeKind.NewExpression:
1486
+ nextPart = nextPart.call.callee;
1487
+ parts = [];
1488
+ continue;
1489
+ case AstNode_1.AstNodeKind.TypeExpression:
1490
+ nextPart = nextPart.expression;
1491
+ continue;
1492
+ case AstNode_1.AstNodeKind.VariableExpression:
1493
+ parts.push(nextPart);
1494
+ break loop;
1495
+ default:
1496
+ return [];
1331
1497
  }
1332
1498
  }
1333
- return parts;
1499
+ return parts.reverse();
1334
1500
  }
1335
1501
  /**
1336
1502
  * Returns an integer if valid, or undefined. Eliminates checking for NaN
@@ -1380,7 +1546,7 @@ class Util {
1380
1546
  processTypeChain(typeChain) {
1381
1547
  let fullChainName = '';
1382
1548
  let fullErrorName = '';
1383
- let missingItemName = '';
1549
+ let itemName = '';
1384
1550
  let previousTypeName = '';
1385
1551
  let parentTypeName = '';
1386
1552
  let errorRange;
@@ -1393,16 +1559,16 @@ class Util {
1393
1559
  parentTypeName = previousTypeName;
1394
1560
  fullErrorName = previousTypeName ? `${previousTypeName}.${chainItem.name}` : chainItem.name;
1395
1561
  previousTypeName = chainItem.type.toString();
1396
- missingItemName = chainItem.name;
1562
+ itemName = chainItem.name;
1397
1563
  if (!chainItem.isResolved) {
1398
1564
  errorRange = chainItem.range;
1399
1565
  break;
1400
1566
  }
1401
1567
  }
1402
1568
  return {
1403
- missingItemName: missingItemName,
1404
- missingItemParentTypeName: parentTypeName,
1405
- fullNameOfMissingItem: fullErrorName,
1569
+ itemName: itemName,
1570
+ itemParentTypeName: parentTypeName,
1571
+ fullNameOfItem: fullErrorName,
1406
1572
  fullChainName: fullChainName,
1407
1573
  range: errorRange
1408
1574
  };