brighterscript 1.0.0-alpha.1 → 1.0.0-alpha.13

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 (316) hide show
  1. package/CHANGELOG.md +362 -248
  2. package/README.md +2 -2
  3. package/bsconfig.schema.json +1 -1
  4. package/dist/CodeActionUtil.d.ts +11 -2
  5. package/dist/CodeActionUtil.js +17 -3
  6. package/dist/CodeActionUtil.js.map +1 -1
  7. package/dist/CommentFlagProcessor.d.ts +4 -4
  8. package/dist/CommentFlagProcessor.js +5 -3
  9. package/dist/CommentFlagProcessor.js.map +1 -1
  10. package/dist/DependencyGraph.js.map +1 -1
  11. package/dist/DiagnosticCollection.js +2 -2
  12. package/dist/DiagnosticCollection.js.map +1 -1
  13. package/dist/DiagnosticFilterer.js +3 -3
  14. package/dist/DiagnosticFilterer.js.map +1 -1
  15. package/dist/DiagnosticMessages.d.ts +15 -5
  16. package/dist/DiagnosticMessages.js +19 -9
  17. package/dist/DiagnosticMessages.js.map +1 -1
  18. package/dist/LanguageServer.d.ts +11 -10
  19. package/dist/LanguageServer.js +87 -58
  20. package/dist/LanguageServer.js.map +1 -1
  21. package/dist/Logger.d.ts +2 -0
  22. package/dist/Logger.js +5 -3
  23. package/dist/Logger.js.map +1 -1
  24. package/dist/Program.d.ts +76 -46
  25. package/dist/Program.js +254 -180
  26. package/dist/Program.js.map +1 -1
  27. package/dist/ProgramBuilder.d.ts +7 -7
  28. package/dist/ProgramBuilder.js +37 -43
  29. package/dist/ProgramBuilder.js.map +1 -1
  30. package/dist/Scope.d.ts +33 -23
  31. package/dist/Scope.js +222 -147
  32. package/dist/Scope.js.map +1 -1
  33. package/dist/SemanticTokenUtils.d.ts +14 -0
  34. package/dist/SemanticTokenUtils.js +81 -0
  35. package/dist/SemanticTokenUtils.js.map +1 -0
  36. package/dist/SymbolTable.d.ts +9 -3
  37. package/dist/SymbolTable.js +40 -13
  38. package/dist/SymbolTable.js.map +1 -1
  39. package/dist/XmlScope.d.ts +7 -2
  40. package/dist/XmlScope.js +67 -29
  41. package/dist/XmlScope.js.map +1 -1
  42. package/dist/astUtils/AstEditor.d.ts +27 -0
  43. package/dist/astUtils/AstEditor.js +97 -0
  44. package/dist/astUtils/AstEditor.js.map +1 -0
  45. package/dist/astUtils/AstEditor.spec.d.ts +1 -0
  46. package/dist/astUtils/AstEditor.spec.js +133 -0
  47. package/dist/astUtils/AstEditor.spec.js.map +1 -0
  48. package/dist/astUtils/creators.d.ts +15 -1
  49. package/dist/astUtils/creators.js +39 -9
  50. package/dist/astUtils/creators.js.map +1 -1
  51. package/dist/astUtils/creators.spec.js +4 -4
  52. package/dist/astUtils/creators.spec.js.map +1 -1
  53. package/dist/astUtils/index.js +1 -1
  54. package/dist/astUtils/reflection.d.ts +20 -8
  55. package/dist/astUtils/reflection.js +42 -1
  56. package/dist/astUtils/reflection.js.map +1 -1
  57. package/dist/astUtils/reflection.spec.js +115 -115
  58. package/dist/astUtils/reflection.spec.js.map +1 -1
  59. package/dist/astUtils/stackedVisitor.js.map +1 -1
  60. package/dist/astUtils/stackedVisitor.spec.js +13 -13
  61. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  62. package/dist/astUtils/visitors.js +1 -1
  63. package/dist/astUtils/visitors.js.map +1 -1
  64. package/dist/astUtils/visitors.spec.js +28 -28
  65. package/dist/astUtils/visitors.spec.js.map +1 -1
  66. package/dist/astUtils/xml.d.ts +4 -3
  67. package/dist/astUtils/xml.js +8 -3
  68. package/dist/astUtils/xml.js.map +1 -1
  69. package/dist/bscPlugin/BscPlugin.d.ts +2 -1
  70. package/dist/bscPlugin/BscPlugin.js +4 -0
  71. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  72. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +5 -6
  73. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  74. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +30 -30
  75. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  76. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.d.ts +7 -0
  77. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +63 -0
  78. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +1 -0
  79. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.d.ts +1 -0
  80. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js +45 -0
  81. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +1 -0
  82. package/dist/diagnosticUtils.d.ts +1 -0
  83. package/dist/diagnosticUtils.js +14 -7
  84. package/dist/diagnosticUtils.js.map +1 -1
  85. package/dist/examples/plugins/removePrint.js +2 -2
  86. package/dist/examples/plugins/removePrint.js.map +1 -1
  87. package/dist/files/BrsFile.Class.spec.js +486 -71
  88. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  89. package/dist/files/BrsFile.d.ts +48 -23
  90. package/dist/files/BrsFile.js +403 -233
  91. package/dist/files/BrsFile.js.map +1 -1
  92. package/dist/files/BrsFile.spec.js +367 -316
  93. package/dist/files/BrsFile.spec.js.map +1 -1
  94. package/dist/files/XmlFile.d.ts +13 -6
  95. package/dist/files/XmlFile.js +27 -21
  96. package/dist/files/XmlFile.js.map +1 -1
  97. package/dist/files/XmlFile.spec.js +274 -228
  98. package/dist/files/XmlFile.spec.js.map +1 -1
  99. package/dist/files/tests/imports.spec.js +49 -49
  100. package/dist/files/tests/imports.spec.js.map +1 -1
  101. package/dist/globalCallables.d.ts +3 -1
  102. package/dist/globalCallables.js +359 -87
  103. package/dist/globalCallables.js.map +1 -1
  104. package/dist/index.js +2 -1
  105. package/dist/index.js.map +1 -1
  106. package/dist/interfaces.d.ts +51 -14
  107. package/dist/lexer/Lexer.d.ts +14 -1
  108. package/dist/lexer/Lexer.js +91 -21
  109. package/dist/lexer/Lexer.js.map +1 -1
  110. package/dist/lexer/Lexer.spec.js +187 -132
  111. package/dist/lexer/Lexer.spec.js.map +1 -1
  112. package/dist/lexer/Token.d.ts +2 -2
  113. package/dist/lexer/TokenKind.d.ts +7 -1
  114. package/dist/lexer/TokenKind.js +51 -3
  115. package/dist/lexer/TokenKind.js.map +1 -1
  116. package/dist/lexer/index.js +2 -1
  117. package/dist/lexer/index.js.map +1 -1
  118. package/dist/parser/BrsTranspileState.d.ts +7 -0
  119. package/dist/parser/BrsTranspileState.js +10 -1
  120. package/dist/parser/BrsTranspileState.js.map +1 -1
  121. package/dist/parser/Expression.d.ts +23 -5
  122. package/dist/parser/Expression.js +124 -75
  123. package/dist/parser/Expression.js.map +1 -1
  124. package/dist/parser/Parser.Class.spec.js +159 -60
  125. package/dist/parser/Parser.Class.spec.js.map +1 -1
  126. package/dist/parser/Parser.d.ts +114 -26
  127. package/dist/parser/Parser.js +471 -126
  128. package/dist/parser/Parser.js.map +1 -1
  129. package/dist/parser/Parser.spec.js +396 -235
  130. package/dist/parser/Parser.spec.js.map +1 -1
  131. package/dist/parser/SGParser.d.ts +41 -4
  132. package/dist/parser/SGParser.js +186 -175
  133. package/dist/parser/SGParser.js.map +1 -1
  134. package/dist/parser/SGParser.spec.js +35 -22
  135. package/dist/parser/SGParser.spec.js.map +1 -1
  136. package/dist/parser/SGTypes.d.ts +206 -38
  137. package/dist/parser/SGTypes.js +470 -161
  138. package/dist/parser/SGTypes.js.map +1 -1
  139. package/dist/parser/SGTypes.spec.d.ts +1 -0
  140. package/dist/parser/SGTypes.spec.js +351 -0
  141. package/dist/parser/SGTypes.spec.js.map +1 -0
  142. package/dist/parser/Statement.d.ts +92 -18
  143. package/dist/parser/Statement.js +287 -58
  144. package/dist/parser/Statement.js.map +1 -1
  145. package/dist/parser/Statement.spec.js +11 -11
  146. package/dist/parser/Statement.spec.js.map +1 -1
  147. package/dist/parser/TranspileState.d.ts +1 -1
  148. package/dist/parser/TranspileState.js +15 -7
  149. package/dist/parser/TranspileState.js.map +1 -1
  150. package/dist/parser/index.js +1 -1
  151. package/dist/parser/tests/Parser.spec.d.ts +8 -7
  152. package/dist/parser/tests/Parser.spec.js +12 -8
  153. package/dist/parser/tests/Parser.spec.js.map +1 -1
  154. package/dist/parser/tests/controlFlow/For.spec.js +50 -50
  155. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  156. package/dist/parser/tests/controlFlow/ForEach.spec.js +31 -31
  157. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  158. package/dist/parser/tests/controlFlow/If.spec.js +174 -156
  159. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  160. package/dist/parser/tests/controlFlow/While.spec.js +32 -32
  161. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  162. package/dist/parser/tests/expression/Additive.spec.js +21 -21
  163. package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
  164. package/dist/parser/tests/expression/ArrayLiterals.spec.js +105 -105
  165. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  166. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +148 -124
  167. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  168. package/dist/parser/tests/expression/Boolean.spec.js +17 -17
  169. package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
  170. package/dist/parser/tests/expression/Call.spec.js +30 -30
  171. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  172. package/dist/parser/tests/expression/Exponential.spec.js +16 -16
  173. package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
  174. package/dist/parser/tests/expression/Function.spec.js +247 -247
  175. package/dist/parser/tests/expression/Function.spec.js.map +1 -1
  176. package/dist/parser/tests/expression/Indexing.spec.js +73 -73
  177. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  178. package/dist/parser/tests/expression/Multiplicative.spec.js +36 -36
  179. package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
  180. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +59 -47
  181. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  182. package/dist/parser/tests/expression/PrefixUnary.spec.js +35 -35
  183. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
  184. package/dist/parser/tests/expression/Primary.spec.js +26 -26
  185. package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
  186. package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
  187. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +170 -0
  188. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
  189. package/dist/parser/tests/expression/Relational.spec.js +42 -42
  190. package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
  191. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +8 -8
  192. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  193. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +12 -12
  194. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  195. package/dist/parser/tests/expression/TernaryExpression.spec.js +100 -100
  196. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  197. package/dist/parser/tests/statement/AssignmentOperators.spec.js +35 -35
  198. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
  199. package/dist/parser/tests/statement/Declaration.spec.js +39 -39
  200. package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
  201. package/dist/parser/tests/statement/Dim.spec.js +21 -21
  202. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  203. package/dist/parser/tests/statement/Function.spec.js +192 -192
  204. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  205. package/dist/parser/tests/statement/Goto.spec.js +11 -11
  206. package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
  207. package/dist/parser/tests/statement/Increment.spec.js +46 -46
  208. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  209. package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
  210. package/dist/parser/tests/statement/InterfaceStatement.spec.js +61 -0
  211. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
  212. package/dist/parser/tests/statement/LibraryStatement.spec.js +10 -10
  213. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
  214. package/dist/parser/tests/statement/Misc.spec.js +37 -36
  215. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  216. package/dist/parser/tests/statement/PrintStatement.spec.js +30 -30
  217. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  218. package/dist/parser/tests/statement/ReturnStatement.spec.js +43 -43
  219. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  220. package/dist/parser/tests/statement/Set.spec.js +69 -69
  221. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  222. package/dist/parser/tests/statement/Stop.spec.js +9 -9
  223. package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
  224. package/dist/parser/tests/statement/Throw.spec.js +5 -5
  225. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  226. package/dist/parser/tests/statement/TryCatch.spec.js +13 -13
  227. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  228. package/dist/preprocessor/Chunk.js.map +1 -1
  229. package/dist/preprocessor/Manifest.d.ts +1 -1
  230. package/dist/preprocessor/Preprocessor.js +1 -1
  231. package/dist/preprocessor/Preprocessor.js.map +1 -1
  232. package/dist/preprocessor/Preprocessor.spec.js +49 -49
  233. package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
  234. package/dist/preprocessor/PreprocessorParser.spec.js +72 -72
  235. package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
  236. package/dist/preprocessor/index.js +1 -1
  237. package/dist/types/ArrayType.js +5 -4
  238. package/dist/types/ArrayType.js.map +1 -1
  239. package/dist/types/ArrayType.spec.js +8 -8
  240. package/dist/types/ArrayType.spec.js.map +1 -1
  241. package/dist/types/BooleanType.js +3 -3
  242. package/dist/types/BooleanType.js.map +1 -1
  243. package/dist/types/BooleanType.spec.js +2 -2
  244. package/dist/types/BooleanType.spec.js.map +1 -1
  245. package/dist/types/BscType.d.ts +19 -5
  246. package/dist/types/BscType.js +9 -0
  247. package/dist/types/BscType.js.map +1 -1
  248. package/dist/types/CustomType.d.ts +8 -5
  249. package/dist/types/CustomType.js +17 -6
  250. package/dist/types/CustomType.js.map +1 -1
  251. package/dist/types/DoubleType.js +8 -8
  252. package/dist/types/DoubleType.js.map +1 -1
  253. package/dist/types/DoubleType.spec.js +2 -2
  254. package/dist/types/DoubleType.spec.js.map +1 -1
  255. package/dist/types/DynamicType.js +1 -1
  256. package/dist/types/DynamicType.js.map +1 -1
  257. package/dist/types/DynamicType.spec.js +2 -2
  258. package/dist/types/DynamicType.spec.js.map +1 -1
  259. package/dist/types/FloatType.d.ts +1 -1
  260. package/dist/types/FloatType.js +8 -8
  261. package/dist/types/FloatType.js.map +1 -1
  262. package/dist/types/FloatType.spec.js +2 -2
  263. package/dist/types/FloatType.spec.js.map +1 -1
  264. package/dist/types/FunctionType.d.ts +5 -11
  265. package/dist/types/FunctionType.js +24 -13
  266. package/dist/types/FunctionType.js.map +1 -1
  267. package/dist/types/FunctionType.spec.js +11 -5
  268. package/dist/types/FunctionType.spec.js.map +1 -1
  269. package/dist/types/IntegerType.d.ts +1 -1
  270. package/dist/types/IntegerType.js +8 -8
  271. package/dist/types/IntegerType.js.map +1 -1
  272. package/dist/types/IntegerType.spec.js +2 -2
  273. package/dist/types/IntegerType.spec.js.map +1 -1
  274. package/dist/types/InterfaceType.d.ts +8 -2
  275. package/dist/types/InterfaceType.js +42 -6
  276. package/dist/types/InterfaceType.js.map +1 -1
  277. package/dist/types/InterfaceType.spec.d.ts +1 -0
  278. package/dist/types/InterfaceType.spec.js +174 -0
  279. package/dist/types/InterfaceType.spec.js.map +1 -0
  280. package/dist/types/InvalidType.js +4 -4
  281. package/dist/types/InvalidType.js.map +1 -1
  282. package/dist/types/InvalidType.spec.js +2 -2
  283. package/dist/types/InvalidType.spec.js.map +1 -1
  284. package/dist/types/LazyType.d.ts +9 -7
  285. package/dist/types/LazyType.js +22 -10
  286. package/dist/types/LazyType.js.map +1 -1
  287. package/dist/types/LongIntegerType.d.ts +1 -1
  288. package/dist/types/LongIntegerType.js +8 -8
  289. package/dist/types/LongIntegerType.js.map +1 -1
  290. package/dist/types/LongIntegerType.spec.js +2 -2
  291. package/dist/types/LongIntegerType.spec.js.map +1 -1
  292. package/dist/types/ObjectType.d.ts +7 -4
  293. package/dist/types/ObjectType.js +6 -3
  294. package/dist/types/ObjectType.js.map +1 -1
  295. package/dist/types/ObjectType.spec.js +2 -2
  296. package/dist/types/ObjectType.spec.js.map +1 -1
  297. package/dist/types/StringType.js +3 -3
  298. package/dist/types/StringType.js.map +1 -1
  299. package/dist/types/StringType.spec.js +2 -2
  300. package/dist/types/StringType.spec.js.map +1 -1
  301. package/dist/types/UninitializedType.js +3 -3
  302. package/dist/types/UninitializedType.js.map +1 -1
  303. package/dist/types/VoidType.js +3 -3
  304. package/dist/types/VoidType.js.map +1 -1
  305. package/dist/types/VoidType.spec.js +2 -2
  306. package/dist/types/VoidType.spec.js.map +1 -1
  307. package/dist/types/helpers.d.ts +42 -0
  308. package/dist/types/helpers.js +113 -0
  309. package/dist/types/helpers.js.map +1 -0
  310. package/dist/util.d.ts +77 -17
  311. package/dist/util.js +247 -59
  312. package/dist/util.js.map +1 -1
  313. package/dist/validators/ClassValidator.d.ts +5 -1
  314. package/dist/validators/ClassValidator.js +59 -24
  315. package/dist/validators/ClassValidator.js.map +1 -1
  316. package/package.json +13 -13
@@ -8,8 +8,6 @@ const path = require("path");
8
8
  const DiagnosticMessages_1 = require("../DiagnosticMessages");
9
9
  const lexer_1 = require("../lexer");
10
10
  const parser_1 = require("../parser");
11
- const FunctionType_1 = require("../types/FunctionType");
12
- const VoidType_1 = require("../types/VoidType");
13
11
  const util_1 = require("../util");
14
12
  const BrsTranspileState_1 = require("../parser/BrsTranspileState");
15
13
  const Preprocessor_1 = require("../preprocessor/Preprocessor");
@@ -18,17 +16,26 @@ const serialize_error_1 = require("serialize-error");
18
16
  const reflection_1 = require("../astUtils/reflection");
19
17
  const visitors_1 = require("../astUtils/visitors");
20
18
  const CommentFlagProcessor_1 = require("../CommentFlagProcessor");
19
+ const BscType_1 = require("../types/BscType");
20
+ const UninitializedType_1 = require("../types/UninitializedType");
21
+ const InvalidType_1 = require("../types/InvalidType");
22
+ const globalCallables_1 = require("../globalCallables");
23
+ const DynamicType_1 = require("../types/DynamicType");
21
24
  /**
22
25
  * Holds all details about this file within the scope of the whole program
23
26
  */
24
27
  class BrsFile {
25
- constructor(pathAbsolute,
28
+ constructor(
26
29
  /**
27
- * The full pkg path to this file
30
+ * The absolute path to the source file on disk (e.g. '/usr/you/projects/RokuApp/source/main.brs' or 'c:/projects/RokuApp/source/main.brs').
31
+ */
32
+ srcPath,
33
+ /**
34
+ * The full pkg path (i.e. `pkg:/path/to/file.brs`)
28
35
  */
29
36
  pkgPath, program) {
30
37
  var _a;
31
- this.pathAbsolute = pathAbsolute;
38
+ this.srcPath = srcPath;
32
39
  this.pkgPath = pkgPath;
33
40
  this.program = program;
34
41
  /**
@@ -51,10 +58,9 @@ class BrsFile {
51
58
  * Does this file need to be transpiled?
52
59
  */
53
60
  this.needsTranspiled = false;
54
- this.pathAbsolute = util_1.standardizePath `${this.pathAbsolute}`;
55
- this.pkgPath = util_1.standardizePath `${this.pkgPath}`;
61
+ this.srcPath = (0, util_1.standardizePath) `${this.srcPath}`;
56
62
  this.dependencyGraphKey = this.pkgPath.toLowerCase();
57
- this.extension = util_1.util.getExtension(this.pathAbsolute);
63
+ this.extension = util_1.util.getExtension(this.srcPath);
58
64
  //all BrighterScript files need to be transpiled
59
65
  if ((_a = this.extension) === null || _a === void 0 ? void 0 : _a.endsWith('.bs')) {
60
66
  this.needsTranspiled = true;
@@ -62,7 +68,7 @@ class BrsFile {
62
68
  }
63
69
  this.isTypedef = this.extension === '.d.bs';
64
70
  if (!this.isTypedef) {
65
- this.typedefKey = util_1.util.getTypedefPath(this.pathAbsolute);
71
+ this.typedefSrcPath = util_1.util.getTypedefPath(this.srcPath);
66
72
  }
67
73
  //global file doesn't have a program, so only resolve typedef info if we have a program
68
74
  if (this.program) {
@@ -81,17 +87,6 @@ class BrsFile {
81
87
  get ast() {
82
88
  return this.parser.ast;
83
89
  }
84
- /**
85
- * Get the token at the specified position
86
- * @param position
87
- */
88
- getTokenAt(position) {
89
- for (let token of this.parser.tokens) {
90
- if (util_1.util.rangeContains(token.range, position)) {
91
- return token;
92
- }
93
- }
94
- }
95
90
  get parser() {
96
91
  if (!this._parser) {
97
92
  //remove the typedef file (if it exists)
@@ -108,7 +103,7 @@ class BrsFile {
108
103
  * Find and set the typedef variables (if a matching typedef file exists)
109
104
  */
110
105
  resolveTypedef() {
111
- this.typedefFile = this.program.getFileByPathAbsolute(this.typedefKey);
106
+ this.typedefFile = this.program.getFile(this.typedefSrcPath);
112
107
  this.hasTypedef = !!this.typedefFile;
113
108
  }
114
109
  /**
@@ -143,7 +138,7 @@ class BrsFile {
143
138
  return;
144
139
  }
145
140
  //tokenize the input file
146
- let lexer = this.program.logger.time(Logger_1.LogLevel.debug, ['lexer.lex', chalk_1.default.green(this.pathAbsolute)], () => {
141
+ let lexer = this.program.logger.time(Logger_1.LogLevel.debug, ['lexer.lex', chalk_1.default.green(this.srcPath)], () => {
147
142
  return lexer_1.Lexer.scan(fileContents, {
148
143
  includeWhitespace: false
149
144
  });
@@ -154,7 +149,7 @@ class BrsFile {
154
149
  //TODO preprocessor should go away in favor of the AST handling this internally (because it affects transpile)
155
150
  //currently the preprocessor throws exceptions on syntax errors...so we need to catch it
156
151
  try {
157
- this.program.logger.time(Logger_1.LogLevel.debug, ['preprocessor.process', chalk_1.default.green(this.pathAbsolute)], () => {
152
+ this.program.logger.time(Logger_1.LogLevel.debug, ['preprocessor.process', chalk_1.default.green(this.srcPath)], () => {
158
153
  preprocessor.process(lexer.tokens, this.program.getManifest());
159
154
  });
160
155
  }
@@ -166,7 +161,7 @@ class BrsFile {
166
161
  }
167
162
  //if the preprocessor generated tokens, use them.
168
163
  let tokens = preprocessor.processedTokens.length > 0 ? preprocessor.processedTokens : lexer.tokens;
169
- this.program.logger.time(Logger_1.LogLevel.debug, ['parser.parse', chalk_1.default.green(this.pathAbsolute)], () => {
164
+ this.program.logger.time(Logger_1.LogLevel.debug, ['parser.parse', chalk_1.default.green(this.srcPath)], () => {
170
165
  this._parser = parser_1.Parser.parse(tokens, {
171
166
  mode: this.parseMode,
172
167
  logger: this.program.logger
@@ -186,7 +181,7 @@ class BrsFile {
186
181
  }
187
182
  catch (e) {
188
183
  this._parser = new parser_1.Parser();
189
- this.diagnostics.push(Object.assign({ file: this, range: util_1.util.createRange(0, 0, 0, Number.MAX_VALUE) }, DiagnosticMessages_1.DiagnosticMessages.genericParserMessage('Critical error parsing file: ' + JSON.stringify(serialize_error_1.serializeError(e)))));
184
+ this.diagnostics.push(Object.assign({ file: this, range: util_1.util.createRange(0, 0, 0, Number.MAX_VALUE) }, DiagnosticMessages_1.DiagnosticMessages.genericParserMessage('Critical error parsing file: ' + JSON.stringify((0, serialize_error_1.serializeError)(e)))));
190
185
  }
191
186
  }
192
187
  validate() { }
@@ -195,11 +190,11 @@ class BrsFile {
195
190
  let topOfFileIncludeStatements = [];
196
191
  for (let stmt of this.ast.statements) {
197
192
  //skip comments
198
- if (reflection_1.isCommentStatement(stmt)) {
193
+ if ((0, reflection_1.isCommentStatement)(stmt)) {
199
194
  continue;
200
195
  }
201
196
  //if we found a non-library statement, this statement is not at the top of the file
202
- if (reflection_1.isLibraryStatement(stmt) || reflection_1.isImportStatement(stmt)) {
197
+ if ((0, reflection_1.isLibraryStatement)(stmt) || (0, reflection_1.isImportStatement)(stmt)) {
203
198
  topOfFileIncludeStatements.push(stmt);
204
199
  }
205
200
  else {
@@ -213,7 +208,7 @@ class BrsFile {
213
208
  ];
214
209
  for (let result of statements) {
215
210
  //register import statements
216
- if (reflection_1.isImportStatement(result) && result.filePathToken) {
211
+ if ((0, reflection_1.isImportStatement)(result) && result.filePathToken) {
217
212
  this.ownScriptImports.push({
218
213
  filePathRange: result.filePathToken.range,
219
214
  pkgPath: util_1.util.getPkgPathFromTarget(this.pkgPath, result.filePath),
@@ -224,10 +219,10 @@ class BrsFile {
224
219
  //if this statement is not one of the top-of-file statements,
225
220
  //then add a diagnostic explaining that it is invalid
226
221
  if (!topOfFileIncludeStatements.includes(result)) {
227
- if (reflection_1.isLibraryStatement(result)) {
222
+ if ((0, reflection_1.isLibraryStatement)(result)) {
228
223
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.libraryStatementMustBeDeclaredAtTopOfFile()), { range: result.range, file: this }));
229
224
  }
230
- else if (reflection_1.isImportStatement(result)) {
225
+ else if ((0, reflection_1.isImportStatement)(result)) {
231
226
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.importStatementMustBeDeclaredAtTopOfFile()), { range: result.range, file: this }));
232
227
  }
233
228
  }
@@ -288,31 +283,14 @@ class BrsFile {
288
283
  findCallables() {
289
284
  var _a;
290
285
  for (let statement of (_a = this.parser.references.functionStatements) !== null && _a !== void 0 ? _a : []) {
291
- let functionType = new FunctionType_1.FunctionType(statement.func.returnType);
286
+ let functionType = statement.func.getFunctionType();
292
287
  functionType.setName(statement.name.text);
293
- functionType.isSub = statement.func.functionType.text.toLowerCase() === 'sub';
294
- if (functionType.isSub) {
295
- functionType.returnType = new VoidType_1.VoidType();
296
- }
297
- //extract the parameters
298
- let params = [];
299
- for (let param of statement.func.parameters) {
300
- let callableParam = {
301
- name: param.name.text,
302
- type: param.type,
303
- isOptional: !!param.defaultValue,
304
- isRestArgument: false
305
- };
306
- params.push(callableParam);
307
- let isRequired = !param.defaultValue;
308
- functionType.addParameter(callableParam.name, callableParam.type, isRequired);
309
- }
310
288
  this.callables.push({
311
289
  isSub: statement.func.functionType.text.toLowerCase() === 'sub',
312
290
  name: statement.name.text,
313
291
  nameRange: statement.name.range,
314
292
  file: this,
315
- params: params,
293
+ params: functionType.params,
316
294
  range: statement.func.range,
317
295
  type: functionType,
318
296
  getName: statement.getName.bind(statement),
@@ -322,21 +300,24 @@ class BrsFile {
322
300
  }
323
301
  }
324
302
  findFunctionCalls() {
303
+ var _a;
325
304
  this.functionCalls = [];
326
305
  //for every function in the file
327
306
  for (let func of this._parser.references.functionExpressions) {
328
307
  //for all function calls in this function
329
308
  for (let expression of func.callExpressions) {
330
309
  if (
331
- //filter out dotted function invocations (i.e. object.doSomething()) (not currently supported. TODO support it)
332
- expression.callee.obj ||
333
- //filter out method calls on method calls for now (i.e. getSomething().getSomethingElse())
334
- expression.callee.callee ||
310
+ //filter out method calls on method calls for now (i.e. getSomething().getSomethingElse())
311
+ expression.callee.callee ||
312
+ //filter out method calls on regexp literals for now
313
+ (0, reflection_1.isRegexLiteralExpression)((_a = expression.callee) === null || _a === void 0 ? void 0 : _a.obj) ||
335
314
  //filter out callees without a name (immediately-invoked function expressions)
336
315
  !expression.callee.name) {
337
316
  continue;
338
317
  }
339
- let functionName = expression.callee.name.text;
318
+ //Flag dotted function invocations (i.e. object.doSomething())
319
+ const dottedInvocation = expression.callee.obj;
320
+ let functionName = expression.callee.name;
340
321
  //callee is the name of the function being called
341
322
  let callee = expression.callee;
342
323
  let columnIndexBegin = callee.range.start.character;
@@ -344,7 +325,7 @@ class BrsFile {
344
325
  let args = [];
345
326
  //TODO convert if stmts to use instanceof instead
346
327
  for (let arg of expression.args) {
347
- let impliedType = parser_1.getBscTypeFromExpression(arg, func);
328
+ let inferredType = (0, parser_1.getBscTypeFromExpression)(arg, func);
348
329
  let argText = '';
349
330
  // Get the text to display for the arg
350
331
  if (arg.token) {
@@ -352,23 +333,25 @@ class BrsFile {
352
333
  //is a function call being passed into argument
353
334
  }
354
335
  else if (arg.name) {
355
- if (lexer_1.isToken(arg.name)) {
336
+ if ((0, lexer_1.isToken)(arg.name)) {
356
337
  argText = arg.name.text;
357
338
  }
358
339
  }
359
340
  else if (arg.value) {
360
341
  /* istanbul ignore next: TODO figure out why value is undefined sometimes */
361
342
  if (arg.value.value) {
362
- argText = arg.value.value.toString();
343
+ if (arg.value.value.toString) {
344
+ argText = arg.value.value.toString();
345
+ }
363
346
  }
364
347
  //wrap the value in quotes because that's how it appears in the code
365
- if (reflection_1.isStringType(impliedType)) {
348
+ if (argText && (0, reflection_1.isStringType)(inferredType)) {
366
349
  argText = '"' + argText + '"';
367
350
  }
368
351
  }
369
352
  args.push({
370
353
  range: arg.range,
371
- type: impliedType,
354
+ type: inferredType,
372
355
  text: argText
373
356
  });
374
357
  }
@@ -378,8 +361,8 @@ class BrsFile {
378
361
  file: this,
379
362
  name: functionName,
380
363
  nameRange: util_1.util.createRange(callee.range.start.line, columnIndexBegin, callee.range.start.line, columnIndexEnd),
381
- //TODO keep track of parameters
382
- args: args
364
+ args: args,
365
+ isDottedInvocation: dottedInvocation
383
366
  };
384
367
  this.functionCalls.push(functionCall);
385
368
  }
@@ -409,6 +392,7 @@ class BrsFile {
409
392
  * Get completions available at the given cursor. This aggregates all values from this file and the current scope.
410
393
  */
411
394
  getCompletions(position, scope) {
395
+ var _a;
412
396
  let result = [];
413
397
  //a map of lower-case names of all added options
414
398
  let names = {};
@@ -418,7 +402,7 @@ class BrsFile {
418
402
  return this.program.getScriptImportCompletions(this.pkgPath, scriptImport);
419
403
  }
420
404
  //if cursor is within a comment, disable completions
421
- let currentToken = this.getTokenAt(position);
405
+ let currentToken = this.parser.getTokenAt(position);
422
406
  const tokenKind = currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind;
423
407
  if (tokenKind === lexer_1.TokenKind.Comment) {
424
408
  return [];
@@ -427,9 +411,9 @@ class BrsFile {
427
411
  const match = /^("?)(pkg|libpkg):/.exec(currentToken.text);
428
412
  if (match) {
429
413
  const [, openingQuote, fileProtocol] = match;
430
- //include every absolute file path from this scope
414
+ //include every pkgPath from this scope
431
415
  for (const file of scope.getAllFiles()) {
432
- const pkgPath = `${fileProtocol}:/${file.pkgPath.replace(/\\/g, '/')}`;
416
+ const pkgPath = `${fileProtocol}:/${file.pkgPath.replace('pkg:/', '')}`;
433
417
  result.push({
434
418
  label: pkgPath,
435
419
  textEdit: vscode_languageserver_1.TextEdit.replace(util_1.util.createRange(currentToken.range.start.line,
@@ -455,7 +439,7 @@ class BrsFile {
455
439
  let functionExpression = this.getFunctionExpressionAtPosition(position);
456
440
  if (!functionExpression) {
457
441
  //we aren't in any function scope, so return the keyword completions and namespaces
458
- if (this.getTokenBefore(currentToken, lexer_1.TokenKind.New)) {
442
+ if (this.parser.getTokenBefore(currentToken, lexer_1.TokenKind.New)) {
459
443
  // there's a new keyword, so only class types are viable here
460
444
  return [...this.getGlobalClassStatementCompletions(currentToken, this.parseMode)];
461
445
  }
@@ -464,17 +448,17 @@ class BrsFile {
464
448
  }
465
449
  }
466
450
  const classNameCompletions = this.getGlobalClassStatementCompletions(currentToken, this.parseMode);
467
- const newToken = this.getTokenBefore(currentToken, lexer_1.TokenKind.New);
451
+ const newToken = this.parser.getTokenBefore(currentToken, lexer_1.TokenKind.New);
468
452
  if (newToken) {
469
453
  //we are after a new keyword; so we can only be namespaces or classes at this point
470
454
  result.push(...classNameCompletions);
471
455
  result.push(...namespaceCompletions);
472
456
  return result;
473
457
  }
474
- if (this.tokenFollows(currentToken, lexer_1.TokenKind.Goto)) {
458
+ if (this.parser.tokenFollows(currentToken, lexer_1.TokenKind.Goto)) {
475
459
  return this.getLabelCompletion(functionExpression);
476
460
  }
477
- if (this.isPositionNextToTokenKind(position, lexer_1.TokenKind.Dot)) {
461
+ if (this.parser.isPositionNextToTokenKind(position, lexer_1.TokenKind.Dot)) {
478
462
  if (namespaceCompletions.length > 0) {
479
463
  //if we matched a namespace, after a dot, it can't be anything else but something from our namespace completions
480
464
  return namespaceCompletions;
@@ -483,7 +467,12 @@ class BrsFile {
483
467
  if (selfClassMemberCompletions.size > 0) {
484
468
  return [...selfClassMemberCompletions.values()].filter((i) => i.label !== 'new');
485
469
  }
486
- if (!this.getClassFromMReference(position, currentToken, functionExpression)) {
470
+ const tokenLookup = this.getSymbolTypeFromToken(currentToken, functionExpression, scope);
471
+ if ((_a = tokenLookup.symbolContainer) === null || _a === void 0 ? void 0 : _a.memberTable) {
472
+ return this.getCompletionsFromSymbolTable(tokenLookup.symbolContainer.memberTable);
473
+ }
474
+ const foundClassLink = this.getClassFromTokenLookup(tokenLookup, scope);
475
+ if (!foundClassLink) {
487
476
  //and anything from any class in scope to a non m class
488
477
  let classMemberCompletions = scope.getAllClassMemberCompletions();
489
478
  result.push(...classMemberCompletions.values());
@@ -508,19 +497,21 @@ class BrsFile {
508
497
  names.m = true;
509
498
  result.push(...exports.KeywordCompletions);
510
499
  //include local variables
511
- for (let symbol of functionExpression.symbolTable.ownSymbols) {
500
+ for (let symbol of functionExpression.symbolTable.getOwnSymbols()) {
512
501
  const symbolNameLower = symbol.name.toLowerCase();
513
502
  //skip duplicate variable names
514
503
  if (names[symbolNameLower]) {
515
504
  continue;
516
505
  }
517
506
  names[symbolNameLower] = true;
507
+ // TODO TYPES (This may be a performance hit?)
508
+ // const foundType = getTypeFromContext(symbol.type, { scope: scope, file: this });
518
509
  result.push({
519
510
  //TODO does this work?
520
511
  label: symbol.name,
521
- //TODO find type for local vars
512
+ //TODO TYPES find type for local vars - SEE above
522
513
  kind: vscode_languageserver_1.CompletionItemKind.Variable
523
- // kind: isFunctionType(variable.type) ? CompletionItemKind.Function : CompletionItemKind.Variable
514
+ // kind: isFunctionType(foundType) ? CompletionItemKind.Function : CompletionItemKind.Variable
524
515
  });
525
516
  }
526
517
  if (this.parseMode === parser_1.ParseMode.BrighterScript) {
@@ -542,6 +533,14 @@ class BrsFile {
542
533
  }
543
534
  return result;
544
535
  }
536
+ getCompletionsFromSymbolTable(symbolTable) {
537
+ return symbolTable.getAllSymbols().map(bscType => {
538
+ return {
539
+ label: bscType.name,
540
+ kind: (0, reflection_1.isFunctionType)(bscType.type) ? vscode_languageserver_1.CompletionItemKind.Method : vscode_languageserver_1.CompletionItemKind.Field
541
+ };
542
+ });
543
+ }
545
544
  getLabelCompletion(func) {
546
545
  return func.labelStatements.map(label => ({
547
546
  label: label.tokens.identifier.text,
@@ -549,17 +548,17 @@ class BrsFile {
549
548
  }));
550
549
  }
551
550
  getClassMemberCompletions(position, currentToken, functionExpression, scope) {
552
- var _a, _b;
553
- let classStatement = this.getClassFromMReference(position, currentToken, functionExpression);
551
+ var _a, _b, _c, _d;
552
+ let classStatement = this.getClassFromToken(currentToken, functionExpression, scope);
554
553
  let results = new Map();
555
554
  if (classStatement) {
556
555
  let classes = scope.getClassHierarchy(classStatement.item.getName(parser_1.ParseMode.BrighterScript).toLowerCase());
557
556
  for (let cs of classes) {
558
- for (let member of [...(_a = cs === null || cs === void 0 ? void 0 : cs.item) === null || _a === void 0 ? void 0 : _a.fields, ...(_b = cs === null || cs === void 0 ? void 0 : cs.item) === null || _b === void 0 ? void 0 : _b.methods]) {
557
+ for (let member of [...(_b = (_a = cs === null || cs === void 0 ? void 0 : cs.item) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : [], ...(_d = (_c = cs === null || cs === void 0 ? void 0 : cs.item) === null || _c === void 0 ? void 0 : _c.methods) !== null && _d !== void 0 ? _d : []]) {
559
558
  if (!results.has(member.name.text.toLowerCase())) {
560
559
  results.set(member.name.text.toLowerCase(), {
561
560
  label: member.name.text,
562
- kind: reflection_1.isClassFieldStatement(member) ? vscode_languageserver_1.CompletionItemKind.Field : vscode_languageserver_1.CompletionItemKind.Function
561
+ kind: (0, reflection_1.isClassFieldStatement)(member) ? vscode_languageserver_1.CompletionItemKind.Field : vscode_languageserver_1.CompletionItemKind.Function
563
562
  });
564
563
  }
565
564
  }
@@ -567,16 +566,265 @@ class BrsFile {
567
566
  }
568
567
  return results;
569
568
  }
570
- getClassFromMReference(position, currentToken, functionExpression) {
571
- let previousToken = this.getPreviousToken(currentToken);
572
- if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === lexer_1.TokenKind.Dot) {
573
- previousToken = this.getPreviousToken(previousToken);
569
+ /**
570
+ * Gets the class (if any) of a given token based on the scope
571
+ * @param currentToken token in question
572
+ * @param functionExpression current functionExpression
573
+ * @param scope the current scope
574
+ * @returns A fileLink of the ClassStatement, if it is a class, otherwise undefined
575
+ */
576
+ getClassFromToken(currentToken, functionExpression, scope) {
577
+ const tokenLookup = this.getSymbolTypeFromToken(currentToken, functionExpression, scope);
578
+ return this.getClassFromTokenLookup(tokenLookup, scope);
579
+ }
580
+ /**
581
+ * Gets the class (if any) of a given token based on the scope
582
+ * @param currentToken token in question
583
+ * @param functionExpression current functionExpression
584
+ * @param scope the current scope
585
+ * @returns A fileLink of the ClassStatement, if it is a class, otherwise undefined
586
+ */
587
+ getClassFromTokenLookup(tokenLookup, scope) {
588
+ const currentClass = tokenLookup === null || tokenLookup === void 0 ? void 0 : tokenLookup.symbolContainer;
589
+ if ((0, reflection_1.isClassStatement)(currentClass)) {
590
+ return { item: currentClass, file: this };
574
591
  }
575
- if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === lexer_1.TokenKind.Identifier && (previousToken === null || previousToken === void 0 ? void 0 : previousToken.text.toLowerCase()) === 'm' && reflection_1.isClassMethodStatement(functionExpression.functionStatement)) {
576
- return { item: this.parser.references.classStatements.find((cs) => util_1.util.rangeContains(cs.range, position)), file: this };
592
+ else if ((0, reflection_1.isCustomType)(currentClass)) {
593
+ const foundClass = scope.getClass(currentClass.name);
594
+ if (foundClass) {
595
+ return { item: foundClass, file: this };
596
+ }
577
597
  }
578
598
  return undefined;
579
599
  }
600
+ findNamespaceFromTokenChain(originalTokenChain, scope) {
601
+ let namespaceTokens = [];
602
+ let startsWithNamespace = '';
603
+ let namespaceContainer;
604
+ let tokenChain = [...originalTokenChain];
605
+ while (tokenChain[0] && tokenChain[0].usage === parser_1.TokenUsage.Direct) {
606
+ const namespaceNameToCheck = `${startsWithNamespace}${startsWithNamespace.length > 0 ? '.' : ''}${tokenChain[0].token.text}`.toLowerCase();
607
+ const foundNamespace = scope.namespaceLookup.get(namespaceNameToCheck);
608
+ if (foundNamespace) {
609
+ namespaceContainer = foundNamespace;
610
+ namespaceTokens.push(tokenChain[0].token);
611
+ startsWithNamespace = namespaceTokens.map(token => token.text).join('.');
612
+ tokenChain.shift();
613
+ }
614
+ else {
615
+ break;
616
+ }
617
+ }
618
+ if (namespaceTokens.length > 0) {
619
+ namespaceContainer = scope.namespaceLookup.get(startsWithNamespace.toLowerCase());
620
+ }
621
+ return { namespaceContainer: namespaceContainer, tokenChain: tokenChain };
622
+ }
623
+ checkForSpecialClassSymbol(currentToken, scope, func) {
624
+ var _a;
625
+ const containingClass = this.parser.getContainingClass(currentToken);
626
+ let symbolType;
627
+ let currentClassRef;
628
+ const currentTokenLower = currentToken.text.toLowerCase();
629
+ const typeContext = { file: this, scope: scope, position: currentToken.range.start };
630
+ if (containingClass) {
631
+ // Special cases for a single token inside a class
632
+ let expandedText = '';
633
+ let useExpandedTextOnly = false;
634
+ if (containingClass.name === currentToken) {
635
+ symbolType = containingClass.getCustomType();
636
+ expandedText = `class ${containingClass.getName(parser_1.ParseMode.BrighterScript)}`;
637
+ useExpandedTextOnly = true;
638
+ currentClassRef = containingClass;
639
+ }
640
+ else if (currentTokenLower === 'm') {
641
+ symbolType = containingClass.getCustomType();
642
+ expandedText = currentToken.text;
643
+ currentClassRef = containingClass;
644
+ }
645
+ else if (currentTokenLower === 'super') {
646
+ symbolType = (0, BscType_1.getTypeFromContext)(containingClass.symbolTable.getSymbolType(currentTokenLower, true, typeContext), typeContext);
647
+ if ((0, reflection_1.isFunctionType)(symbolType)) {
648
+ currentClassRef = scope.getParentClass(containingClass);
649
+ }
650
+ }
651
+ else if (((_a = func === null || func === void 0 ? void 0 : func.functionStatement) === null || _a === void 0 ? void 0 : _a.name) === currentToken) {
652
+ // check if this is a method declaration
653
+ currentClassRef = containingClass;
654
+ symbolType = containingClass === null || containingClass === void 0 ? void 0 : containingClass.memberTable.getSymbolType(currentTokenLower, true, { file: this, scope: scope });
655
+ expandedText = [containingClass.getName(parser_1.ParseMode.BrighterScript), currentToken.text].join('.');
656
+ }
657
+ else if (!func) {
658
+ // check if this is a field declaration
659
+ currentClassRef = containingClass;
660
+ symbolType = containingClass === null || containingClass === void 0 ? void 0 : containingClass.memberTable.getSymbolType(currentTokenLower, true, { file: this, scope: scope });
661
+ expandedText = [containingClass.getName(parser_1.ParseMode.BrighterScript), currentToken.text].join('.');
662
+ }
663
+ if (symbolType) {
664
+ return { type: symbolType, expandedTokenText: expandedText, symbolContainer: currentClassRef, useExpandedTextOnly: useExpandedTextOnly };
665
+ }
666
+ }
667
+ }
668
+ checkForSpecialCaseToken(nameSpacedTokenChain, functionExpression, scope) {
669
+ var _a;
670
+ const tokenChain = (_a = nameSpacedTokenChain.tokenChain) !== null && _a !== void 0 ? _a : [];
671
+ if (nameSpacedTokenChain.namespaceContainer && tokenChain.length === 0) {
672
+ //currentToken was part of a namespace
673
+ return {
674
+ type: null,
675
+ expandedTokenText: `namespace ${nameSpacedTokenChain.namespaceContainer.fullName}`,
676
+ useExpandedTextOnly: true
677
+ };
678
+ }
679
+ const specialCase = tokenChain.length === 1 ? this.checkForSpecialClassSymbol(tokenChain[0].token, scope, functionExpression) : null;
680
+ if (specialCase) {
681
+ return specialCase;
682
+ }
683
+ }
684
+ /**
685
+ * Checks previous tokens for the start of a symbol chain (eg. m.property.subProperty.method())
686
+ * @param currentToken The token to check
687
+ * @param functionExpression The current function context
688
+ * @param scope use this scope for finding class maps
689
+ * @returns the BscType, expanded text (e.g <Class.field>) and classStatement (if available) for the token
690
+ */
691
+ getSymbolTypeFromToken(currentToken, functionExpression, scope) {
692
+ var _a, _b, _c, _d, _e;
693
+ if (!scope) {
694
+ return undefined;
695
+ }
696
+ const cachedSymbolData = scope.symbolCache.get(currentToken);
697
+ if (cachedSymbolData) {
698
+ return cachedSymbolData;
699
+ }
700
+ const tokenChainResponse = this.parser.getTokenChain(currentToken);
701
+ if (tokenChainResponse.includesUnknowableTokenType) {
702
+ const symbolData = { type: new DynamicType_1.DynamicType(), expandedTokenText: currentToken.text };
703
+ scope.symbolCache.set(currentToken, symbolData);
704
+ return symbolData;
705
+ }
706
+ const nameSpacedTokenChain = this.findNamespaceFromTokenChain(tokenChainResponse.chain, scope);
707
+ const specialCase = this.checkForSpecialCaseToken(nameSpacedTokenChain, functionExpression, scope);
708
+ if (specialCase) {
709
+ scope.symbolCache.set(currentToken, specialCase);
710
+ return specialCase;
711
+ }
712
+ const tokenChain = nameSpacedTokenChain.tokenChain;
713
+ let symbolContainer = this.parser.getContainingAA(currentToken) || this.parser.getContainingClass(currentToken);
714
+ let currentSymbolTable = (_b = (_a = nameSpacedTokenChain.namespaceContainer) === null || _a === void 0 ? void 0 : _a.symbolTable) !== null && _b !== void 0 ? _b : functionExpression === null || functionExpression === void 0 ? void 0 : functionExpression.symbolTable;
715
+ let tokenFoundCount = 0;
716
+ let symbolTypeBeforeReference;
717
+ let symbolType;
718
+ let tokenText = [];
719
+ let justReturnDynamic = false;
720
+ const typeContext = { file: this, scope: scope, position: (_c = tokenChain[0]) === null || _c === void 0 ? void 0 : _c.token.range.start };
721
+ for (const tokenChainMember of tokenChain) {
722
+ const token = tokenChainMember === null || tokenChainMember === void 0 ? void 0 : tokenChainMember.token;
723
+ const tokenLowerText = token.text.toLowerCase();
724
+ if (tokenLowerText === 'super' && (0, reflection_1.isClassStatement)(symbolContainer) && tokenFoundCount === 0) {
725
+ /// Special cases for first item in chain inside a class
726
+ symbolContainer = scope === null || scope === void 0 ? void 0 : scope.getParentClass(symbolContainer);
727
+ currentSymbolTable = (_d = symbolContainer) === null || _d === void 0 ? void 0 : _d.memberTable;
728
+ if (symbolContainer && currentSymbolTable) {
729
+ tokenText.push(symbolContainer.getName(parser_1.ParseMode.BrighterScript));
730
+ tokenFoundCount++;
731
+ continue;
732
+ }
733
+ }
734
+ if (!currentSymbolTable) {
735
+ // uh oh... no symbol table to continue to check
736
+ break;
737
+ }
738
+ symbolType = currentSymbolTable.getSymbolType(tokenLowerText, true, typeContext);
739
+ if (tokenFoundCount === 0 && !symbolType) {
740
+ //check for global callable
741
+ symbolType = (_e = globalCallables_1.globalCallableMap.get(tokenLowerText)) === null || _e === void 0 ? void 0 : _e.type;
742
+ }
743
+ if (symbolType) {
744
+ // found this symbol, and it's valid. increase found counter
745
+ tokenFoundCount++;
746
+ }
747
+ symbolTypeBeforeReference = symbolType;
748
+ if ((0, reflection_1.isFunctionType)(symbolType)) {
749
+ // this is a function, and it is in the start or middle of the chain
750
+ // the next symbol to check will be the return value of this function
751
+ symbolType = (0, BscType_1.getTypeFromContext)(symbolType.returnType, typeContext);
752
+ if (tokenFoundCount < tokenChain.length) {
753
+ // We're still
754
+ symbolTypeBeforeReference = symbolType;
755
+ }
756
+ }
757
+ if (symbolType === null || symbolType === void 0 ? void 0 : symbolType.memberTable) {
758
+ if ((0, reflection_1.isCustomType)(symbolType)) {
759
+ // we're currently looking at a customType, that has it's own symbol table
760
+ // use the name of the custom type
761
+ // TODO TYPES: get proper parent name for methods/fields defined in super classes
762
+ tokenText.push(tokenChain.length === 1 ? token.text : symbolType.name);
763
+ }
764
+ else {
765
+ justReturnDynamic = true;
766
+ tokenText.push(token.text);
767
+ }
768
+ symbolContainer = symbolType;
769
+ currentSymbolTable = symbolContainer === null || symbolContainer === void 0 ? void 0 : symbolContainer.memberTable;
770
+ }
771
+ else if ((0, reflection_1.isObjectType)(symbolType) || (0, reflection_1.isArrayType)(symbolType) || (0, reflection_1.isDynamicType)(symbolType)) {
772
+ // this is an object that has no member table
773
+ // this could happen if a parameter is marked as object
774
+ // assume all fields are dynamic
775
+ symbolContainer = undefined;
776
+ tokenText.push(token.text);
777
+ justReturnDynamic = true;
778
+ break;
779
+ }
780
+ else {
781
+ // No further symbol tables were found
782
+ symbolContainer = undefined;
783
+ tokenText.push(token.text);
784
+ break;
785
+ }
786
+ if (tokenText.length > 2) {
787
+ tokenText.shift(); // only care about last two symbols
788
+ }
789
+ }
790
+ let expandedTokenText = tokenText.join('.');
791
+ let backUpReturnType;
792
+ if (tokenFoundCount === tokenChain.length) {
793
+ // did we complete the chain? if so, we have a valid token at the end
794
+ const symbolData = { type: symbolTypeBeforeReference, expandedTokenText: tokenText.join('.'), symbolContainer: symbolContainer };
795
+ scope.symbolCache.set(currentToken, symbolData);
796
+ return symbolData;
797
+ }
798
+ if ((0, reflection_1.isDynamicType)(symbolTypeBeforeReference) || (0, reflection_1.isArrayType)(symbolTypeBeforeReference) || justReturnDynamic) {
799
+ // last type in chain is dynamic... so currentToken could be anything.
800
+ backUpReturnType = new DynamicType_1.DynamicType();
801
+ expandedTokenText = currentToken.text;
802
+ }
803
+ else if ((0, reflection_1.isPrimitiveType)(symbolTypeBeforeReference)) {
804
+ // last type in chain is dynamic... so currentToken could be anything.
805
+ backUpReturnType = new DynamicType_1.DynamicType();
806
+ expandedTokenText = currentToken.text;
807
+ }
808
+ else if (tokenChain.length === 1) {
809
+ // variable that has not been assigned
810
+ expandedTokenText = currentToken.text;
811
+ backUpReturnType = new UninitializedType_1.UninitializedType();
812
+ }
813
+ else if (tokenFoundCount === tokenChain.length - 1) {
814
+ // member field that is not known
815
+ if (symbolContainer) {
816
+ backUpReturnType = new InvalidType_1.InvalidType();
817
+ }
818
+ else {
819
+ // TODO TYPES: once we have stricter object/node member type checking, we could say this is invalid, but until then, call it dynamic
820
+ backUpReturnType = new DynamicType_1.DynamicType();
821
+ expandedTokenText = currentToken.text;
822
+ }
823
+ }
824
+ const symbolData = { type: backUpReturnType, expandedTokenText: expandedTokenText };
825
+ scope.symbolCache.set(currentToken, symbolData);
826
+ return symbolData;
827
+ }
580
828
  getGlobalClassStatementCompletions(currentToken, parseMode) {
581
829
  var _a;
582
830
  if (parseMode === parser_1.ParseMode.BrightScript) {
@@ -615,11 +863,9 @@ class BrsFile {
615
863
  //remove any trailing identifer and then any trailing dot, to give us the
616
864
  //name of its immediate parent namespace
617
865
  let closestParentNamespaceName = completionName.replace(/\.([a-z0-9_]*)?$/gi, '');
618
- let newToken = this.getTokenBefore(currentToken, lexer_1.TokenKind.New);
619
- let namespaceLookup = scope.namespaceLookup;
866
+ let newToken = this.parser.getTokenBefore(currentToken, lexer_1.TokenKind.New);
620
867
  let result = new Map();
621
- for (let key in namespaceLookup) {
622
- let namespace = namespaceLookup[key.toLowerCase()];
868
+ for (let [, namespace] of scope.namespaceLookup) {
623
869
  //completionName = "NameA."
624
870
  //completionName = "NameA.Na
625
871
  //NameA
@@ -627,9 +873,8 @@ class BrsFile {
627
873
  //NameA.NameB.NameC
628
874
  if (namespace.fullName.toLowerCase() === closestParentNamespaceName.toLowerCase()) {
629
875
  //add all of this namespace's immediate child namespaces, bearing in mind if we are after a new keyword
630
- for (let childKey in namespace.namespaces) {
631
- const ns = namespace.namespaces[childKey];
632
- if (!newToken || ns.statements.find((s) => reflection_1.isClassStatement(s))) {
876
+ for (let [, ns] of namespace.namespaces) {
877
+ if (!newToken || ns.statements.find((s) => (0, reflection_1.isClassStatement)(s))) {
633
878
  if (!result.has(ns.lastPartName)) {
634
879
  result.set(ns.lastPartName, {
635
880
  label: ns.lastPartName,
@@ -640,7 +885,7 @@ class BrsFile {
640
885
  }
641
886
  //add function and class statement completions
642
887
  for (let stmt of namespace.statements) {
643
- if (reflection_1.isClassStatement(stmt)) {
888
+ if ((0, reflection_1.isClassStatement)(stmt)) {
644
889
  if (!result.has(stmt.name.text)) {
645
890
  result.set(stmt.name.text, {
646
891
  label: stmt.name.text,
@@ -648,7 +893,7 @@ class BrsFile {
648
893
  });
649
894
  }
650
895
  }
651
- else if (reflection_1.isFunctionStatement(stmt) && !newToken) {
896
+ else if ((0, reflection_1.isFunctionStatement)(stmt) && !newToken) {
652
897
  if (!result.has(stmt.name.text)) {
653
898
  result.set(stmt.name.text, {
654
899
  label: stmt.name.text,
@@ -674,11 +919,11 @@ class BrsFile {
674
919
  if (!location && statement.getName(parser_1.ParseMode.BrighterScript).toLowerCase() === namespaceName) {
675
920
  const namespaceItemStatementHandler = (statement) => {
676
921
  if (!location && statement.name.text.toLowerCase() === endName) {
677
- const uri = util_1.util.pathToUri(file.pathAbsolute);
922
+ const uri = util_1.util.pathToUri(file.srcPath);
678
923
  location = vscode_languageserver_1.Location.create(uri, statement.range);
679
924
  }
680
925
  };
681
- file.parser.ast.walk(visitors_1.createVisitor({
926
+ file.parser.ast.walk((0, visitors_1.createVisitor)({
682
927
  ClassStatement: namespaceItemStatementHandler,
683
928
  FunctionStatement: namespaceItemStatementHandler
684
929
  }), {
@@ -686,7 +931,7 @@ class BrsFile {
686
931
  });
687
932
  }
688
933
  };
689
- file.parser.ast.walk(visitors_1.createVisitor({
934
+ file.parser.ast.walk((0, visitors_1.createVisitor)({
690
935
  NamespaceStatement: statementHandler
691
936
  }), {
692
937
  walkMode: visitors_1.WalkMode.visitStatements
@@ -718,79 +963,21 @@ class BrsFile {
718
963
  return undefined;
719
964
  }
720
965
  }
721
- isPositionNextToTokenKind(position, tokenKind) {
722
- const closestToken = this.getClosestToken(position);
723
- const previousToken = this.getPreviousToken(closestToken);
724
- const previousTokenKind = previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind;
725
- //next to matched token
726
- if (!closestToken || closestToken.kind === lexer_1.TokenKind.Eof) {
727
- return false;
728
- }
729
- else if (closestToken.kind === tokenKind) {
730
- return true;
731
- }
732
- else if (closestToken.kind === lexer_1.TokenKind.Newline || previousTokenKind === lexer_1.TokenKind.Newline) {
733
- return false;
734
- //next to an identifier, which is next to token kind
735
- }
736
- else if (closestToken.kind === lexer_1.TokenKind.Identifier && previousTokenKind === tokenKind) {
737
- return true;
738
- }
739
- else {
740
- return false;
741
- }
742
- }
743
- getTokenBefore(currentToken, tokenKind) {
744
- const index = this.parser.tokens.indexOf(currentToken);
745
- for (let i = index - 1; i >= 0; i--) {
746
- currentToken = this.parser.tokens[i];
747
- if (currentToken.kind === lexer_1.TokenKind.Newline) {
748
- break;
749
- }
750
- else if (currentToken.kind === tokenKind) {
751
- return currentToken;
752
- }
753
- }
754
- return undefined;
755
- }
756
- tokenFollows(currentToken, tokenKind) {
757
- const index = this.parser.tokens.indexOf(currentToken);
758
- if (index > 0) {
759
- return this.parser.tokens[index - 1].kind === tokenKind;
760
- }
761
- return false;
762
- }
763
- getTokensUntil(currentToken, tokenKind, direction = -1) {
764
- let tokens = [];
765
- for (let i = this.parser.tokens.indexOf(currentToken); direction === -1 ? i >= 0 : i === this.parser.tokens.length; i += direction) {
766
- currentToken = this.parser.tokens[i];
767
- if (currentToken.kind === lexer_1.TokenKind.Newline || currentToken.kind === tokenKind) {
768
- break;
769
- }
770
- tokens.push(currentToken);
771
- }
772
- return tokens;
773
- }
774
- getPreviousToken(token) {
775
- const parser = this.parser;
776
- let idx = parser.tokens.indexOf(token);
777
- return parser.tokens[idx - 1];
778
- }
779
966
  /**
780
967
  * Find the first scope that has a namespace with this name.
781
968
  * Returns false if no namespace was found with that name
782
969
  */
783
970
  calleeStartsWithNamespace(callee) {
784
971
  let left = callee;
785
- while (reflection_1.isDottedGetExpression(left)) {
972
+ while ((0, reflection_1.isDottedGetExpression)(left)) {
786
973
  left = left.obj;
787
974
  }
788
- if (reflection_1.isVariableExpression(left)) {
975
+ if ((0, reflection_1.isVariableExpression)(left)) {
789
976
  let lowerName = left.name.text.toLowerCase();
790
977
  //find the first scope that contains this namespace
791
978
  let scopes = this.program.getScopesForFile(this);
792
979
  for (let scope of scopes) {
793
- if (scope.namespaceLookup[lowerName]) {
980
+ if (scope.namespaceLookup.has(lowerName)) {
794
981
  return true;
795
982
  }
796
983
  }
@@ -803,12 +990,12 @@ class BrsFile {
803
990
  calleeIsKnownNamespaceFunction(callee, namespaceName) {
804
991
  var _a, _b;
805
992
  //if we have a variable and a namespace
806
- if (reflection_1.isVariableExpression(callee) && namespaceName) {
993
+ if ((0, reflection_1.isVariableExpression)(callee) && namespaceName) {
807
994
  let lowerCalleeName = (_b = (_a = callee === null || callee === void 0 ? void 0 : callee.name) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.toLowerCase();
808
995
  if (lowerCalleeName) {
809
996
  let scopes = this.program.getScopesForFile(this);
810
997
  for (let scope of scopes) {
811
- let namespace = scope.namespaceLookup[namespaceName.toLowerCase()];
998
+ let namespace = scope.namespaceLookup.get(namespaceName.toLowerCase());
812
999
  if (namespace.functionStatements[lowerCalleeName]) {
813
1000
  return true;
814
1001
  }
@@ -817,28 +1004,6 @@ class BrsFile {
817
1004
  }
818
1005
  return false;
819
1006
  }
820
- /**
821
- * Get the token closest to the position. if no token is found, the previous token is returned
822
- * @param position
823
- * @param tokens
824
- */
825
- getClosestToken(position) {
826
- let tokens = this.parser.tokens;
827
- for (let i = 0; i < tokens.length; i++) {
828
- let token = tokens[i];
829
- if (util_1.util.rangeContains(token.range, position)) {
830
- return token;
831
- }
832
- //if the position less than this token range, then this position touches no token,
833
- if (util_1.util.positionIsGreaterThanRange(position, token.range) === false) {
834
- let t = tokens[i - 1];
835
- //return the token or the first token
836
- return t ? t : tokens[0];
837
- }
838
- }
839
- //return the last token
840
- return tokens[tokens.length - 1];
841
- }
842
1007
  /**
843
1008
  * Builds a list of document symbols for this file. Used by LanguageServer's onDocumentSymbol functionality
844
1009
  */
@@ -878,16 +1043,16 @@ class BrsFile {
878
1043
  getDocumentSymbol(statement) {
879
1044
  let symbolKind;
880
1045
  const children = [];
881
- if (reflection_1.isFunctionStatement(statement)) {
1046
+ if ((0, reflection_1.isFunctionStatement)(statement)) {
882
1047
  symbolKind = vscode_languageserver_1.SymbolKind.Function;
883
1048
  }
884
- else if (reflection_1.isClassMethodStatement(statement)) {
1049
+ else if ((0, reflection_1.isClassMethodStatement)(statement)) {
885
1050
  symbolKind = vscode_languageserver_1.SymbolKind.Method;
886
1051
  }
887
- else if (reflection_1.isClassFieldStatement(statement)) {
1052
+ else if ((0, reflection_1.isClassFieldStatement)(statement)) {
888
1053
  symbolKind = vscode_languageserver_1.SymbolKind.Field;
889
1054
  }
890
- else if (reflection_1.isNamespaceStatement(statement)) {
1055
+ else if ((0, reflection_1.isNamespaceStatement)(statement)) {
891
1056
  symbolKind = vscode_languageserver_1.SymbolKind.Namespace;
892
1057
  for (const childStatement of statement.body.statements) {
893
1058
  const symbol = this.getDocumentSymbol(childStatement);
@@ -896,7 +1061,7 @@ class BrsFile {
896
1061
  }
897
1062
  }
898
1063
  }
899
- else if (reflection_1.isClassStatement(statement)) {
1064
+ else if ((0, reflection_1.isClassStatement)(statement)) {
900
1065
  symbolKind = vscode_languageserver_1.SymbolKind.Class;
901
1066
  for (const childStatement of statement.body) {
902
1067
  const symbol = this.getDocumentSymbol(childStatement);
@@ -908,7 +1073,7 @@ class BrsFile {
908
1073
  else {
909
1074
  return;
910
1075
  }
911
- const name = reflection_1.isClassFieldStatement(statement) ? statement.name.text : statement.getName(parser_1.ParseMode.BrighterScript);
1076
+ const name = (0, reflection_1.isClassFieldStatement)(statement) ? statement.name.text : statement.getName(parser_1.ParseMode.BrighterScript);
912
1077
  return vscode_languageserver_1.DocumentSymbol.create(name, '', symbolKind, statement.range, statement.range, children);
913
1078
  }
914
1079
  /**
@@ -917,13 +1082,13 @@ class BrsFile {
917
1082
  generateWorkspaceSymbols(statement, containerStatement) {
918
1083
  let symbolKind;
919
1084
  const symbols = [];
920
- if (reflection_1.isFunctionStatement(statement)) {
1085
+ if ((0, reflection_1.isFunctionStatement)(statement)) {
921
1086
  symbolKind = vscode_languageserver_1.SymbolKind.Function;
922
1087
  }
923
- else if (reflection_1.isClassMethodStatement(statement)) {
1088
+ else if ((0, reflection_1.isClassMethodStatement)(statement)) {
924
1089
  symbolKind = vscode_languageserver_1.SymbolKind.Method;
925
1090
  }
926
- else if (reflection_1.isNamespaceStatement(statement)) {
1091
+ else if ((0, reflection_1.isNamespaceStatement)(statement)) {
927
1092
  symbolKind = vscode_languageserver_1.SymbolKind.Namespace;
928
1093
  for (const childStatement of statement.body.statements) {
929
1094
  for (const symbol of this.generateWorkspaceSymbols(childStatement, statement)) {
@@ -931,7 +1096,7 @@ class BrsFile {
931
1096
  }
932
1097
  }
933
1098
  }
934
- else if (reflection_1.isClassStatement(statement)) {
1099
+ else if ((0, reflection_1.isClassStatement)(statement)) {
935
1100
  symbolKind = vscode_languageserver_1.SymbolKind.Class;
936
1101
  for (const childStatement of statement.body) {
937
1102
  for (const symbol of this.generateWorkspaceSymbols(childStatement, statement)) {
@@ -943,7 +1108,7 @@ class BrsFile {
943
1108
  return symbols;
944
1109
  }
945
1110
  const name = statement.getName(parser_1.ParseMode.BrighterScript);
946
- const uri = util_1.util.pathToUri(this.pathAbsolute);
1111
+ const uri = util_1.util.pathToUri(this.srcPath);
947
1112
  const symbol = vscode_languageserver_1.SymbolInformation.create(name, symbolKind, statement.range, uri, containerStatement === null || containerStatement === void 0 ? void 0 : containerStatement.getName(parser_1.ParseMode.BrighterScript));
948
1113
  symbols.push(symbol);
949
1114
  return symbols;
@@ -955,7 +1120,7 @@ class BrsFile {
955
1120
  getDefinition(position) {
956
1121
  let results = [];
957
1122
  //get the token at the position
958
- const token = this.getTokenAt(position);
1123
+ const token = this.parser.getTokenAt(position);
959
1124
  // While certain other tokens are allowed as local variables (AllowedLocalIdentifiers: https://github.com/rokucommunity/brighterscript/blob/master/src/lexer/TokenKind.ts#L418), these are converted by the parser to TokenKind.Identifier by the time we retrieve the token using getTokenAt
960
1125
  let definitionTokenTypes = [
961
1126
  lexer_1.TokenKind.Identifier,
@@ -966,25 +1131,25 @@ class BrsFile {
966
1131
  return results;
967
1132
  }
968
1133
  let textToSearchFor = token.text.toLowerCase();
969
- const previousToken = this.getTokenAt({ line: token.range.start.line, character: token.range.start.character });
1134
+ const previousToken = this.parser.getTokenAt({ line: token.range.start.line, character: token.range.start.character });
970
1135
  if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === lexer_1.TokenKind.Callfunc) {
971
1136
  for (const scope of this.program.getScopes()) {
972
1137
  //to only get functions defined in interface methods
973
1138
  const callable = scope.getAllCallables().find((c) => c.callable.name.toLowerCase() === textToSearchFor); // eslint-disable-line @typescript-eslint/no-loop-func
974
1139
  if (callable) {
975
- results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(callable.callable.file.pathAbsolute), callable.callable.functionStatement.range));
1140
+ results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(callable.callable.file.srcPath), callable.callable.functionStatement.range));
976
1141
  }
977
1142
  }
978
1143
  return results;
979
1144
  }
980
- let classToken = this.getTokenBefore(token, lexer_1.TokenKind.Class);
1145
+ let classToken = this.parser.getTokenBefore(token, lexer_1.TokenKind.Class);
981
1146
  if (classToken) {
982
1147
  let cs = this.parser.references.classStatements.find((cs) => cs.classKeyword.range === classToken.range);
983
1148
  if (cs === null || cs === void 0 ? void 0 : cs.parentClassName) {
984
1149
  const nameParts = cs.parentClassName.getNameParts();
985
1150
  let extendedClass = this.getClassFileLink(nameParts[nameParts.length - 1], nameParts.slice(0, -1).join('.'));
986
1151
  if (extendedClass) {
987
- results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(extendedClass.file.pathAbsolute), extendedClass.item.range));
1152
+ results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(extendedClass.file.srcPath), extendedClass.item.range));
988
1153
  }
989
1154
  }
990
1155
  return results;
@@ -1001,17 +1166,17 @@ class BrsFile {
1001
1166
  const func = this.getFunctionExpressionAtPosition(position);
1002
1167
  //look through local variables first
1003
1168
  //find any variable with this name
1004
- for (const symbol of func.symbolTable.ownSymbols) {
1169
+ for (const symbol of func.symbolTable.getOwnSymbols()) {
1005
1170
  //we found a variable declaration with this token text
1006
1171
  if (symbol.name.toLowerCase() === textToSearchFor) {
1007
- const uri = util_1.util.pathToUri(this.pathAbsolute);
1172
+ const uri = util_1.util.pathToUri(this.srcPath);
1008
1173
  results.push(vscode_languageserver_1.Location.create(uri, symbol.range));
1009
1174
  }
1010
1175
  }
1011
- if (this.tokenFollows(token, lexer_1.TokenKind.Goto)) {
1176
+ if (this.parser.tokenFollows(token, lexer_1.TokenKind.Goto)) {
1012
1177
  for (const label of func.labelStatements) {
1013
1178
  if (label.tokens.identifier.text.toLocaleLowerCase() === textToSearchFor) {
1014
- const uri = util_1.util.pathToUri(this.pathAbsolute);
1179
+ const uri = util_1.util.pathToUri(this.srcPath);
1015
1180
  results.push(vscode_languageserver_1.Location.create(uri, label.tokens.identifier.range));
1016
1181
  }
1017
1182
  }
@@ -1020,7 +1185,7 @@ class BrsFile {
1020
1185
  //look through all files in scope for matches
1021
1186
  for (const scope of this.program.getScopesForFile(this)) {
1022
1187
  for (const file of scope.getAllFiles()) {
1023
- if (reflection_1.isXmlFile(file) || filesSearched.has(file)) {
1188
+ if ((0, reflection_1.isXmlFile)(file) || filesSearched.has(file)) {
1024
1189
  continue;
1025
1190
  }
1026
1191
  filesSearched.add(file);
@@ -1033,11 +1198,11 @@ class BrsFile {
1033
1198
  }
1034
1199
  const statementHandler = (statement) => {
1035
1200
  if (statement.getName(this.parseMode).toLowerCase() === textToSearchFor) {
1036
- const uri = util_1.util.pathToUri(file.pathAbsolute);
1201
+ const uri = util_1.util.pathToUri(file.srcPath);
1037
1202
  results.push(vscode_languageserver_1.Location.create(uri, statement.range));
1038
1203
  }
1039
1204
  };
1040
- file.parser.ast.walk(visitors_1.createVisitor({
1205
+ file.parser.ast.walk((0, visitors_1.createVisitor)({
1041
1206
  FunctionStatement: statementHandler
1042
1207
  }), {
1043
1208
  walkMode: visitors_1.WalkMode.visitStatements
@@ -1051,15 +1216,15 @@ class BrsFile {
1051
1216
  //get class fields and members
1052
1217
  const statementHandler = (statement) => {
1053
1218
  if (statement.getName(file.parseMode).toLowerCase() === textToSearchFor) {
1054
- results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(file.pathAbsolute), statement.range));
1219
+ results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(file.srcPath), statement.range));
1055
1220
  }
1056
1221
  };
1057
1222
  const fieldStatementHandler = (statement) => {
1058
1223
  if (statement.name.text.toLowerCase() === textToSearchFor) {
1059
- results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(file.pathAbsolute), statement.range));
1224
+ results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(file.srcPath), statement.range));
1060
1225
  }
1061
1226
  };
1062
- file.parser.ast.walk(visitors_1.createVisitor({
1227
+ file.parser.ast.walk((0, visitors_1.createVisitor)({
1063
1228
  ClassMethodStatement: statementHandler,
1064
1229
  ClassFieldStatement: fieldStatementHandler
1065
1230
  }), {
@@ -1068,9 +1233,9 @@ class BrsFile {
1068
1233
  return results;
1069
1234
  }
1070
1235
  getHover(position) {
1071
- var _a;
1236
+ var _a, _b, _c;
1072
1237
  //get the token at the position
1073
- let token = this.getTokenAt(position);
1238
+ let token = this.parser.getTokenAt(position);
1074
1239
  let hoverTokenTypes = [
1075
1240
  lexer_1.TokenKind.Identifier,
1076
1241
  lexer_1.TokenKind.Function,
@@ -1086,27 +1251,33 @@ class BrsFile {
1086
1251
  //look through local variables first
1087
1252
  {
1088
1253
  const func = this.getFunctionExpressionAtPosition(position);
1089
- for (const labelStatement of func.labelStatements) {
1090
- if (labelStatement.tokens.identifier.text.toLocaleLowerCase() === lowerTokenText) {
1091
- return {
1092
- range: token.range,
1093
- contents: `${labelStatement.tokens.identifier.text}: label`
1094
- };
1254
+ if (func) {
1255
+ // this identifier could possibly be a class field, so no function expression is available
1256
+ for (const labelStatement of (_a = func === null || func === void 0 ? void 0 : func.labelStatements) !== null && _a !== void 0 ? _a : []) {
1257
+ if (labelStatement.tokens.identifier.text.toLocaleLowerCase() === lowerTokenText) {
1258
+ return {
1259
+ range: token.range,
1260
+ contents: `${labelStatement.tokens.identifier.text}: label`
1261
+ };
1262
+ }
1095
1263
  }
1096
1264
  }
1097
1265
  const typeTexts = [];
1098
1266
  for (const scope of this.program.getScopesForFile(this)) {
1099
1267
  scope.linkSymbolTable();
1100
- if (func.symbolTable.hasSymbol(lowerTokenText)) {
1101
- const type = (_a = func.symbolTable) === null || _a === void 0 ? void 0 : _a.getSymbolType(lowerTokenText);
1268
+ const typeTextPair = this.getSymbolTypeFromToken(token, func, scope);
1269
+ if (typeTextPair) {
1102
1270
  let scopeTypeText = '';
1103
- if (reflection_1.isFunctionType(type)) {
1104
- scopeTypeText = type.toString();
1271
+ if ((0, reflection_1.isFunctionType)(typeTextPair.type)) {
1272
+ scopeTypeText = (_b = typeTextPair.type) === null || _b === void 0 ? void 0 : _b.toString();
1273
+ }
1274
+ else if (typeTextPair.useExpandedTextOnly) {
1275
+ scopeTypeText = typeTextPair.expandedTokenText;
1105
1276
  }
1106
1277
  else {
1107
- scopeTypeText = `${token.text} as ${type.toString()}`;
1278
+ scopeTypeText = `${typeTextPair.expandedTokenText} as ${(_c = typeTextPair.type) === null || _c === void 0 ? void 0 : _c.toString()}`;
1108
1279
  }
1109
- if (!typeTexts.includes(scopeTypeText)) {
1280
+ if (scopeTypeText && !typeTexts.includes(scopeTypeText)) {
1110
1281
  typeTexts.push(scopeTypeText);
1111
1282
  }
1112
1283
  }
@@ -1139,10 +1310,8 @@ class BrsFile {
1139
1310
  if (!dottedGetText) {
1140
1311
  return [];
1141
1312
  }
1142
- let namespaceLookup = scope.namespaceLookup;
1143
1313
  let resultsMap = new Map();
1144
- for (let key in namespaceLookup) {
1145
- let namespace = namespaceLookup[key.toLowerCase()];
1314
+ for (let [, namespace] of scope.namespaceLookup) {
1146
1315
  //completionName = "NameA."
1147
1316
  //completionName = "NameA.Na
1148
1317
  //NameA
@@ -1151,7 +1320,7 @@ class BrsFile {
1151
1320
  if (namespace.fullName.toLowerCase() === dottedGetText.toLowerCase()) {
1152
1321
  //add function and class statement completions
1153
1322
  for (let stmt of namespace.statements) {
1154
- if (reflection_1.isFunctionStatement(stmt) && stmt.name.text.toLowerCase() === callableName.toLowerCase()) {
1323
+ if ((0, reflection_1.isFunctionStatement)(stmt) && stmt.name.text.toLowerCase() === callableName.toLowerCase()) {
1155
1324
  const result = (_a = namespace.file) === null || _a === void 0 ? void 0 : _a.getSignatureHelpForStatement(stmt);
1156
1325
  if (!resultsMap.has(result.key)) {
1157
1326
  resultsMap.set(result.key, result);
@@ -1163,16 +1332,16 @@ class BrsFile {
1163
1332
  return [...resultsMap.values()];
1164
1333
  }
1165
1334
  getSignatureHelpForStatement(statement) {
1166
- if (!reflection_1.isFunctionStatement(statement) && !reflection_1.isClassMethodStatement(statement)) {
1335
+ if (!(0, reflection_1.isFunctionStatement)(statement) && !(0, reflection_1.isClassMethodStatement)(statement)) {
1167
1336
  return undefined;
1168
1337
  }
1169
1338
  const func = statement.func;
1170
1339
  const funcStartPosition = func.range.start;
1171
1340
  // Get function comments in reverse order
1172
- let currentToken = this.getTokenAt(funcStartPosition);
1341
+ let currentToken = this.parser.getTokenAt(funcStartPosition);
1173
1342
  let functionComments = [];
1174
1343
  while (currentToken) {
1175
- currentToken = this.getPreviousToken(currentToken);
1344
+ currentToken = this.parser.getPreviousToken(currentToken);
1176
1345
  if (!currentToken) {
1177
1346
  break;
1178
1347
  }
@@ -1216,7 +1385,8 @@ class BrsFile {
1216
1385
  }
1217
1386
  getClassMethod(classStatement, name, walkParents = true) {
1218
1387
  var _a;
1219
- //TODO - would like to write this with getClassHieararchy; but got stuck on working out the scopes to use... :(
1388
+ //TODO - would like to write this with getClassHierarchy; but got stuck on working out the scopes to use... :(
1389
+ //TODO types - this could be solved with symbolTable?
1220
1390
  let statement;
1221
1391
  const statementHandler = (e) => {
1222
1392
  if (!statement && e.name.text.toLowerCase() === name.toLowerCase()) {
@@ -1224,7 +1394,7 @@ class BrsFile {
1224
1394
  }
1225
1395
  };
1226
1396
  while (classStatement) {
1227
- classStatement.walk(visitors_1.createVisitor({
1397
+ classStatement.walk((0, visitors_1.createVisitor)({
1228
1398
  ClassMethodStatement: statementHandler
1229
1399
  }), {
1230
1400
  walkMode: visitors_1.WalkMode.visitStatements
@@ -1252,21 +1422,21 @@ class BrsFile {
1252
1422
  return sigHelp;
1253
1423
  }
1254
1424
  getReferences(position) {
1255
- const callSiteToken = this.getTokenAt(position);
1425
+ const callSiteToken = this.parser.getTokenAt(position);
1256
1426
  let locations = [];
1257
1427
  const searchFor = callSiteToken.text.toLowerCase();
1258
1428
  const scopes = this.program.getScopesForFile(this);
1259
1429
  for (const scope of scopes) {
1260
1430
  const processedFiles = new Set();
1261
1431
  for (const file of scope.getAllFiles()) {
1262
- if (reflection_1.isXmlFile(file) || processedFiles.has(file)) {
1432
+ if ((0, reflection_1.isXmlFile)(file) || processedFiles.has(file)) {
1263
1433
  continue;
1264
1434
  }
1265
1435
  processedFiles.add(file);
1266
- file.ast.walk(visitors_1.createVisitor({
1436
+ file.ast.walk((0, visitors_1.createVisitor)({
1267
1437
  VariableExpression: (e) => {
1268
1438
  if (e.name.text.toLowerCase() === searchFor) {
1269
- locations.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(file.pathAbsolute), e.range));
1439
+ locations.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(file.srcPath), e.range));
1270
1440
  }
1271
1441
  }
1272
1442
  }), {
@@ -1310,7 +1480,7 @@ class BrsFile {
1310
1480
  getTypedef() {
1311
1481
  const state = new BrsTranspileState_1.BrsTranspileState(this);
1312
1482
  const typedef = this.ast.getTypedef(state);
1313
- const programNode = new source_map_1.SourceNode(null, null, this.pathAbsolute, typedef);
1483
+ const programNode = new source_map_1.SourceNode(null, null, this.srcPath, typedef);
1314
1484
  return programNode.toString();
1315
1485
  }
1316
1486
  dispose() {