brighterscript 0.66.0-alpha.9 → 0.67.1

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 (472) hide show
  1. package/CHANGELOG.md +123 -73
  2. package/README.md +14 -418
  3. package/dist/BsConfig.d.ts +25 -2
  4. package/dist/Cache.js +3 -3
  5. package/dist/Cache.js.map +1 -1
  6. package/dist/CodeActionUtil.d.ts +3 -3
  7. package/dist/CodeActionUtil.js.map +1 -1
  8. package/dist/CommentFlagProcessor.d.ts +3 -4
  9. package/dist/CommentFlagProcessor.js +4 -3
  10. package/dist/CommentFlagProcessor.js.map +1 -1
  11. package/dist/DependencyGraph.js +8 -8
  12. package/dist/DependencyGraph.js.map +1 -1
  13. package/dist/DiagnosticFilterer.d.ts +8 -4
  14. package/dist/DiagnosticFilterer.js +71 -38
  15. package/dist/DiagnosticFilterer.js.map +1 -1
  16. package/dist/DiagnosticMessages.d.ts +15 -36
  17. package/dist/DiagnosticMessages.js +15 -61
  18. package/dist/DiagnosticMessages.js.map +1 -1
  19. package/dist/DiagnosticSeverityAdjuster.js +3 -0
  20. package/dist/DiagnosticSeverityAdjuster.js.map +1 -1
  21. package/dist/FunctionScope.d.ts +2 -3
  22. package/dist/FunctionScope.js +0 -3
  23. package/dist/FunctionScope.js.map +1 -1
  24. package/dist/LanguageServer.d.ts +1 -2
  25. package/dist/LanguageServer.js +31 -35
  26. package/dist/LanguageServer.js.map +1 -1
  27. package/dist/Logger.d.ts +5 -9
  28. package/dist/Logger.js +18 -22
  29. package/dist/Logger.js.map +1 -1
  30. package/dist/PluginInterface.d.ts +13 -15
  31. package/dist/PluginInterface.js +16 -70
  32. package/dist/PluginInterface.js.map +1 -1
  33. package/dist/Program.d.ts +105 -138
  34. package/dist/Program.js +479 -702
  35. package/dist/Program.js.map +1 -1
  36. package/dist/ProgramBuilder.d.ts +8 -19
  37. package/dist/ProgramBuilder.js +85 -89
  38. package/dist/ProgramBuilder.js.map +1 -1
  39. package/dist/Scope.d.ts +56 -46
  40. package/dist/Scope.js +281 -217
  41. package/dist/Scope.js.map +1 -1
  42. package/dist/Stopwatch.js +1 -1
  43. package/dist/Stopwatch.js.map +1 -1
  44. package/dist/SymbolTable.d.ts +12 -68
  45. package/dist/SymbolTable.js +28 -213
  46. package/dist/SymbolTable.js.map +1 -1
  47. package/dist/XmlScope.d.ts +5 -7
  48. package/dist/XmlScope.js +36 -76
  49. package/dist/XmlScope.js.map +1 -1
  50. package/dist/astUtils/{Editor.d.ts → AstEditor.d.ts} +1 -6
  51. package/dist/astUtils/{Editor.js → AstEditor.js} +3 -9
  52. package/dist/astUtils/AstEditor.js.map +1 -0
  53. package/dist/astUtils/{Editor.spec.js → AstEditor.spec.js} +6 -10
  54. package/dist/astUtils/AstEditor.spec.js.map +1 -0
  55. package/dist/astUtils/creators.d.ts +8 -19
  56. package/dist/astUtils/creators.js +22 -54
  57. package/dist/astUtils/creators.js.map +1 -1
  58. package/dist/astUtils/creators.spec.js +0 -10
  59. package/dist/astUtils/creators.spec.js.map +1 -1
  60. package/dist/astUtils/reflection.d.ts +45 -81
  61. package/dist/astUtils/reflection.js +157 -220
  62. package/dist/astUtils/reflection.js.map +1 -1
  63. package/dist/astUtils/reflection.spec.js +19 -96
  64. package/dist/astUtils/reflection.spec.js.map +1 -1
  65. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  66. package/dist/astUtils/visitors.d.ts +14 -18
  67. package/dist/astUtils/visitors.js +9 -22
  68. package/dist/astUtils/visitors.js.map +1 -1
  69. package/dist/astUtils/visitors.spec.js +9 -62
  70. package/dist/astUtils/visitors.spec.js.map +1 -1
  71. package/dist/astUtils/xml.d.ts +9 -9
  72. package/dist/astUtils/xml.js +6 -6
  73. package/dist/astUtils/xml.js.map +1 -1
  74. package/dist/bscPlugin/BscPlugin.d.ts +8 -11
  75. package/dist/bscPlugin/BscPlugin.js +21 -29
  76. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  77. package/dist/bscPlugin/CallExpressionInfo.d.ts +6 -5
  78. package/dist/bscPlugin/CallExpressionInfo.js +2 -2
  79. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
  80. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +11 -11
  81. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  82. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +4 -4
  83. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  84. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +1 -49
  85. package/dist/bscPlugin/completions/CompletionsProcessor.js +23 -424
  86. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  87. package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
  88. package/dist/bscPlugin/definition/DefinitionProvider.js +200 -0
  89. package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
  90. package/dist/bscPlugin/definition/DefinitionProvider.spec.js +87 -0
  91. package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
  92. package/dist/bscPlugin/hover/HoverProcessor.d.ts +3 -7
  93. package/dist/bscPlugin/hover/HoverProcessor.js +88 -128
  94. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  95. package/dist/bscPlugin/hover/HoverProcessor.spec.js +24 -336
  96. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  97. package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
  98. package/dist/bscPlugin/references/ReferencesProvider.js +56 -0
  99. package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
  100. package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
  101. package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
  102. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +0 -1
  103. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +5 -49
  104. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  105. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +0 -22
  106. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
  107. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.d.ts +7 -0
  108. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js +22 -0
  109. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js.map +1 -0
  110. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +290 -0
  111. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +1 -0
  112. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.d.ts +7 -0
  113. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js +26 -0
  114. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js.map +1 -0
  115. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +245 -0
  116. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +1 -0
  117. package/dist/bscPlugin/symbols/symbolUtils.d.ts +5 -0
  118. package/dist/bscPlugin/symbols/symbolUtils.js +140 -0
  119. package/dist/bscPlugin/symbols/symbolUtils.js.map +1 -0
  120. package/dist/bscPlugin/transpile/{BrsFileTranspileProcessor.d.ts → BrsFilePreTranspileProcessor.d.ts} +2 -4
  121. package/dist/bscPlugin/transpile/{BrsFileTranspileProcessor.js → BrsFilePreTranspileProcessor.js} +15 -36
  122. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -0
  123. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +46 -0
  124. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +1 -0
  125. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +1 -0
  126. package/dist/bscPlugin/validation/BrsFileValidator.js +30 -41
  127. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  128. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +2 -2
  129. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
  130. package/dist/bscPlugin/validation/ProgramValidator.d.ts +3 -3
  131. package/dist/bscPlugin/validation/ProgramValidator.js +6 -6
  132. package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -1
  133. package/dist/bscPlugin/validation/ScopeValidator.d.ts +6 -28
  134. package/dist/bscPlugin/validation/ScopeValidator.js +166 -387
  135. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  136. package/dist/bscPlugin/validation/XmlFileValidator.js +9 -9
  137. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
  138. package/dist/diagnosticUtils.d.ts +2 -3
  139. package/dist/diagnosticUtils.js +5 -5
  140. package/dist/diagnosticUtils.js.map +1 -1
  141. package/dist/examples/plugins/removePrint.js +1 -1
  142. package/dist/examples/plugins/removePrint.js.map +1 -1
  143. package/dist/files/BrsFile.Class.spec.js +143 -114
  144. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  145. package/dist/files/BrsFile.d.ts +61 -83
  146. package/dist/files/BrsFile.js +559 -612
  147. package/dist/files/BrsFile.js.map +1 -1
  148. package/dist/files/BrsFile.spec.js +1365 -1201
  149. package/dist/files/BrsFile.spec.js.map +1 -1
  150. package/dist/files/XmlFile.d.ts +28 -56
  151. package/dist/files/XmlFile.js +103 -89
  152. package/dist/files/XmlFile.js.map +1 -1
  153. package/dist/files/XmlFile.spec.js +179 -122
  154. package/dist/files/XmlFile.spec.js.map +1 -1
  155. package/dist/files/tests/imports.spec.js +19 -29
  156. package/dist/files/tests/imports.spec.js.map +1 -1
  157. package/dist/files/tests/optionalChaning.spec.js +14 -14
  158. package/dist/files/tests/optionalChaning.spec.js.map +1 -1
  159. package/dist/globalCallables.js +83 -88
  160. package/dist/globalCallables.js.map +1 -1
  161. package/dist/index.d.ts +1 -9
  162. package/dist/index.js +1 -9
  163. package/dist/index.js.map +1 -1
  164. package/dist/interfaces.d.ts +173 -423
  165. package/dist/interfaces.js +0 -24
  166. package/dist/interfaces.js.map +1 -1
  167. package/dist/lexer/Lexer.d.ts +9 -15
  168. package/dist/lexer/Lexer.js +35 -46
  169. package/dist/lexer/Lexer.js.map +1 -1
  170. package/dist/lexer/Lexer.spec.js +48 -40
  171. package/dist/lexer/Lexer.spec.js.map +1 -1
  172. package/dist/lexer/Token.d.ts +1 -5
  173. package/dist/lexer/Token.js +1 -1
  174. package/dist/lexer/Token.js.map +1 -1
  175. package/dist/lexer/TokenKind.d.ts +0 -6
  176. package/dist/lexer/TokenKind.js +2 -14
  177. package/dist/lexer/TokenKind.js.map +1 -1
  178. package/dist/logging.d.ts +9 -0
  179. package/dist/logging.js +16 -0
  180. package/dist/logging.js.map +1 -0
  181. package/dist/parser/AstNode.d.ts +6 -90
  182. package/dist/parser/AstNode.js +5 -96
  183. package/dist/parser/AstNode.js.map +1 -1
  184. package/dist/parser/AstNode.spec.js.map +1 -1
  185. package/dist/parser/BrsTranspileState.d.ts +3 -4
  186. package/dist/parser/BrsTranspileState.js +2 -3
  187. package/dist/parser/BrsTranspileState.js.map +1 -1
  188. package/dist/parser/Expression.d.ts +114 -137
  189. package/dist/parser/Expression.js +244 -373
  190. package/dist/parser/Expression.js.map +1 -1
  191. package/dist/parser/Parser.Class.spec.js +19 -46
  192. package/dist/parser/Parser.Class.spec.js.map +1 -1
  193. package/dist/parser/Parser.d.ts +18 -14
  194. package/dist/parser/Parser.js +196 -175
  195. package/dist/parser/Parser.js.map +1 -1
  196. package/dist/parser/Parser.spec.d.ts +0 -2
  197. package/dist/parser/Parser.spec.js +10 -674
  198. package/dist/parser/Parser.spec.js.map +1 -1
  199. package/dist/parser/SGParser.d.ts +6 -44
  200. package/dist/parser/SGParser.js +198 -194
  201. package/dist/parser/SGParser.js.map +1 -1
  202. package/dist/parser/SGParser.spec.js +11 -14
  203. package/dist/parser/SGParser.spec.js.map +1 -1
  204. package/dist/parser/SGTypes.d.ts +52 -280
  205. package/dist/parser/SGTypes.js +185 -562
  206. package/dist/parser/SGTypes.js.map +1 -1
  207. package/dist/parser/Statement.d.ts +140 -172
  208. package/dist/parser/Statement.js +201 -337
  209. package/dist/parser/Statement.js.map +1 -1
  210. package/dist/parser/Statement.spec.js.map +1 -1
  211. package/dist/parser/TranspileState.d.ts +3 -2
  212. package/dist/parser/TranspileState.js +8 -10
  213. package/dist/parser/TranspileState.js.map +1 -1
  214. package/dist/parser/tests/Parser.spec.js +3 -5
  215. package/dist/parser/tests/Parser.spec.js.map +1 -1
  216. package/dist/parser/tests/controlFlow/For.spec.js +8 -16
  217. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  218. package/dist/parser/tests/controlFlow/ForEach.spec.js +6 -12
  219. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  220. package/dist/parser/tests/controlFlow/While.spec.js +4 -8
  221. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  222. package/dist/parser/tests/expression/Call.spec.js +4 -4
  223. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  224. package/dist/parser/tests/expression/Indexing.spec.js +25 -0
  225. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  226. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +73 -29
  227. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  228. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
  229. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
  230. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
  231. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  232. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +47 -35
  233. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  234. package/dist/parser/tests/expression/TernaryExpression.spec.js +83 -36
  235. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  236. package/dist/parser/tests/expression/UnaryExpression.spec.js +2 -2
  237. package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -1
  238. package/dist/parser/tests/statement/ConstStatement.spec.js +26 -27
  239. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
  240. package/dist/parser/tests/statement/Continue.spec.js +2 -2
  241. package/dist/parser/tests/statement/Continue.spec.js.map +1 -1
  242. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  243. package/dist/parser/tests/statement/Enum.spec.js +393 -90
  244. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  245. package/dist/parser/tests/statement/For.spec.js +6 -6
  246. package/dist/parser/tests/statement/For.spec.js.map +1 -1
  247. package/dist/parser/tests/statement/ForEach.spec.js +4 -4
  248. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
  249. package/dist/parser/tests/statement/Function.spec.js +1 -1
  250. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  251. package/dist/parser/tests/statement/InterfaceStatement.spec.js +18 -18
  252. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  253. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  254. package/dist/parser/tests/statement/PrintStatement.spec.js +13 -16
  255. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  256. package/dist/parser/tests/statement/ReturnStatement.spec.js +3 -5
  257. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  258. package/dist/parser/tests/statement/Set.spec.js +13 -26
  259. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  260. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  261. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  262. package/dist/preprocessor/Chunk.js +1 -2
  263. package/dist/preprocessor/Chunk.js.map +1 -1
  264. package/dist/preprocessor/Preprocessor.d.ts +3 -4
  265. package/dist/preprocessor/Preprocessor.js +3 -3
  266. package/dist/preprocessor/Preprocessor.js.map +1 -1
  267. package/dist/preprocessor/PreprocessorParser.js +8 -1
  268. package/dist/preprocessor/PreprocessorParser.js.map +1 -1
  269. package/dist/roku-types/data.json +293 -243
  270. package/dist/roku-types/index.d.ts +38 -17
  271. package/dist/types/ArrayType.d.ts +4 -9
  272. package/dist/types/ArrayType.js +24 -72
  273. package/dist/types/ArrayType.js.map +1 -1
  274. package/dist/types/ArrayType.spec.js +10 -39
  275. package/dist/types/ArrayType.spec.js.map +1 -1
  276. package/dist/types/BooleanType.d.ts +4 -8
  277. package/dist/types/BooleanType.js +8 -19
  278. package/dist/types/BooleanType.js.map +1 -1
  279. package/dist/types/BooleanType.spec.js +3 -9
  280. package/dist/types/BooleanType.spec.js.map +1 -1
  281. package/dist/types/BscType.d.ts +2 -29
  282. package/dist/types/BscType.js +0 -113
  283. package/dist/types/BscType.js.map +1 -1
  284. package/dist/types/CustomType.d.ts +9 -0
  285. package/dist/types/CustomType.js +32 -0
  286. package/dist/types/CustomType.js.map +1 -0
  287. package/dist/types/DoubleType.d.ts +4 -8
  288. package/dist/types/DoubleType.js +20 -23
  289. package/dist/types/DoubleType.js.map +1 -1
  290. package/dist/types/DoubleType.spec.js +3 -11
  291. package/dist/types/DoubleType.spec.js.map +1 -1
  292. package/dist/types/DynamicType.d.ts +3 -9
  293. package/dist/types/DynamicType.js +2 -18
  294. package/dist/types/DynamicType.js.map +1 -1
  295. package/dist/types/DynamicType.spec.js +4 -15
  296. package/dist/types/DynamicType.spec.js.map +1 -1
  297. package/dist/types/FloatType.d.ts +4 -8
  298. package/dist/types/FloatType.js +20 -23
  299. package/dist/types/FloatType.js.map +1 -1
  300. package/dist/types/FloatType.spec.js +3 -3
  301. package/dist/types/FloatType.spec.js.map +1 -1
  302. package/dist/types/FunctionType.d.ts +20 -10
  303. package/dist/types/FunctionType.js +52 -27
  304. package/dist/types/FunctionType.js.map +1 -1
  305. package/dist/types/FunctionType.spec.js +23 -0
  306. package/dist/types/FunctionType.spec.js.map +1 -0
  307. package/dist/types/IntegerType.d.ts +4 -8
  308. package/dist/types/IntegerType.js +20 -23
  309. package/dist/types/IntegerType.js.map +1 -1
  310. package/dist/types/IntegerType.spec.js +3 -7
  311. package/dist/types/IntegerType.spec.js.map +1 -1
  312. package/dist/types/InterfaceType.d.ts +10 -12
  313. package/dist/types/InterfaceType.js +48 -23
  314. package/dist/types/InterfaceType.js.map +1 -1
  315. package/dist/types/InterfaceType.spec.js +45 -82
  316. package/dist/types/InterfaceType.spec.js.map +1 -1
  317. package/dist/types/InvalidType.d.ts +4 -7
  318. package/dist/types/InvalidType.js +8 -18
  319. package/dist/types/InvalidType.js.map +1 -1
  320. package/dist/types/InvalidType.spec.js +3 -7
  321. package/dist/types/InvalidType.spec.js.map +1 -1
  322. package/dist/types/LongIntegerType.d.ts +4 -8
  323. package/dist/types/LongIntegerType.js +20 -23
  324. package/dist/types/LongIntegerType.js.map +1 -1
  325. package/dist/types/LongIntegerType.spec.js +3 -9
  326. package/dist/types/LongIntegerType.spec.js.map +1 -1
  327. package/dist/types/ObjectType.d.ts +4 -8
  328. package/dist/types/ObjectType.js +7 -21
  329. package/dist/types/ObjectType.js.map +1 -1
  330. package/dist/types/ObjectType.spec.js +2 -2
  331. package/dist/types/ObjectType.spec.js.map +1 -1
  332. package/dist/types/StringType.d.ts +4 -11
  333. package/dist/types/StringType.js +8 -23
  334. package/dist/types/StringType.js.map +1 -1
  335. package/dist/types/StringType.spec.js +2 -2
  336. package/dist/types/StringType.spec.js.map +1 -1
  337. package/dist/types/UninitializedType.d.ts +3 -7
  338. package/dist/types/UninitializedType.js +3 -14
  339. package/dist/types/UninitializedType.js.map +1 -1
  340. package/dist/types/VoidType.d.ts +4 -8
  341. package/dist/types/VoidType.js +8 -18
  342. package/dist/types/VoidType.js.map +1 -1
  343. package/dist/types/VoidType.spec.js +2 -2
  344. package/dist/types/VoidType.spec.js.map +1 -1
  345. package/dist/util.d.ts +43 -104
  346. package/dist/util.js +243 -640
  347. package/dist/util.js.map +1 -1
  348. package/dist/validators/ClassValidator.d.ts +6 -1
  349. package/dist/validators/ClassValidator.js +61 -20
  350. package/dist/validators/ClassValidator.js.map +1 -1
  351. package/package.json +13 -11
  352. package/dist/ActionPipeline.d.ts +0 -10
  353. package/dist/ActionPipeline.js +0 -40
  354. package/dist/ActionPipeline.js.map +0 -1
  355. package/dist/AstValidationSegmenter.d.ts +0 -25
  356. package/dist/AstValidationSegmenter.js +0 -150
  357. package/dist/AstValidationSegmenter.js.map +0 -1
  358. package/dist/CacheVerifier.d.ts +0 -7
  359. package/dist/CacheVerifier.js +0 -20
  360. package/dist/CacheVerifier.js.map +0 -1
  361. package/dist/astUtils/Editor.js.map +0 -1
  362. package/dist/astUtils/Editor.spec.js.map +0 -1
  363. package/dist/bscPlugin/FileWriter.d.ts +0 -6
  364. package/dist/bscPlugin/FileWriter.js +0 -24
  365. package/dist/bscPlugin/FileWriter.js.map +0 -1
  366. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +0 -1658
  367. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +0 -1
  368. package/dist/bscPlugin/fileProviders/FileProvider.d.ts +0 -9
  369. package/dist/bscPlugin/fileProviders/FileProvider.js +0 -51
  370. package/dist/bscPlugin/fileProviders/FileProvider.js.map +0 -1
  371. package/dist/bscPlugin/serialize/BslibInjector.spec.js +0 -19
  372. package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +0 -1
  373. package/dist/bscPlugin/serialize/BslibManager.d.ts +0 -9
  374. package/dist/bscPlugin/serialize/BslibManager.js +0 -40
  375. package/dist/bscPlugin/serialize/BslibManager.js.map +0 -1
  376. package/dist/bscPlugin/serialize/FileSerializer.d.ts +0 -9
  377. package/dist/bscPlugin/serialize/FileSerializer.js +0 -72
  378. package/dist/bscPlugin/serialize/FileSerializer.js.map +0 -1
  379. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +0 -1
  380. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +0 -41
  381. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +0 -1
  382. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +0 -11
  383. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +0 -53
  384. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +0 -1
  385. package/dist/bscPlugin/validation/ScopeValidator.spec.js +0 -2004
  386. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +0 -1
  387. package/dist/files/AssetFile.d.ts +0 -26
  388. package/dist/files/AssetFile.js +0 -26
  389. package/dist/files/AssetFile.js.map +0 -1
  390. package/dist/files/Factory.d.ts +0 -25
  391. package/dist/files/Factory.js +0 -22
  392. package/dist/files/Factory.js.map +0 -1
  393. package/dist/files/File.d.ts +0 -106
  394. package/dist/files/File.js +0 -16
  395. package/dist/files/File.js.map +0 -1
  396. package/dist/files/LazyFileData.d.ts +0 -20
  397. package/dist/files/LazyFileData.js +0 -54
  398. package/dist/files/LazyFileData.js.map +0 -1
  399. package/dist/files/LazyFileData.spec.js +0 -27
  400. package/dist/files/LazyFileData.spec.js.map +0 -1
  401. package/dist/parser/tests/expression/TypeExpression.spec.js +0 -127
  402. package/dist/parser/tests/expression/TypeExpression.spec.js.map +0 -1
  403. package/dist/types/AssociativeArrayType.d.ts +0 -11
  404. package/dist/types/AssociativeArrayType.js +0 -52
  405. package/dist/types/AssociativeArrayType.js.map +0 -1
  406. package/dist/types/BaseFunctionType.d.ts +0 -9
  407. package/dist/types/BaseFunctionType.js +0 -25
  408. package/dist/types/BaseFunctionType.js.map +0 -1
  409. package/dist/types/BscTypeKind.d.ts +0 -25
  410. package/dist/types/BscTypeKind.js +0 -30
  411. package/dist/types/BscTypeKind.js.map +0 -1
  412. package/dist/types/BuiltInInterfaceAdder.d.ts +0 -23
  413. package/dist/types/BuiltInInterfaceAdder.js +0 -160
  414. package/dist/types/BuiltInInterfaceAdder.js.map +0 -1
  415. package/dist/types/BuiltInInterfaceAdder.spec.d.ts +0 -1
  416. package/dist/types/BuiltInInterfaceAdder.spec.js +0 -116
  417. package/dist/types/BuiltInInterfaceAdder.spec.js.map +0 -1
  418. package/dist/types/ClassType.d.ts +0 -17
  419. package/dist/types/ClassType.js +0 -58
  420. package/dist/types/ClassType.js.map +0 -1
  421. package/dist/types/ClassType.spec.d.ts +0 -1
  422. package/dist/types/ClassType.spec.js +0 -77
  423. package/dist/types/ClassType.spec.js.map +0 -1
  424. package/dist/types/ComponentType.d.ts +0 -26
  425. package/dist/types/ComponentType.js +0 -83
  426. package/dist/types/ComponentType.js.map +0 -1
  427. package/dist/types/EnumType.d.ts +0 -40
  428. package/dist/types/EnumType.js +0 -81
  429. package/dist/types/EnumType.js.map +0 -1
  430. package/dist/types/EnumType.spec.d.ts +0 -1
  431. package/dist/types/EnumType.spec.js +0 -33
  432. package/dist/types/EnumType.spec.js.map +0 -1
  433. package/dist/types/InheritableType.d.ts +0 -28
  434. package/dist/types/InheritableType.js +0 -152
  435. package/dist/types/InheritableType.js.map +0 -1
  436. package/dist/types/NamespaceType.d.ts +0 -12
  437. package/dist/types/NamespaceType.js +0 -28
  438. package/dist/types/NamespaceType.js.map +0 -1
  439. package/dist/types/ReferenceType.d.ts +0 -63
  440. package/dist/types/ReferenceType.js +0 -423
  441. package/dist/types/ReferenceType.js.map +0 -1
  442. package/dist/types/ReferenceType.spec.d.ts +0 -1
  443. package/dist/types/ReferenceType.spec.js +0 -137
  444. package/dist/types/ReferenceType.spec.js.map +0 -1
  445. package/dist/types/TypedFunctionType.d.ts +0 -33
  446. package/dist/types/TypedFunctionType.js +0 -106
  447. package/dist/types/TypedFunctionType.js.map +0 -1
  448. package/dist/types/TypedFunctionType.spec.d.ts +0 -1
  449. package/dist/types/TypedFunctionType.spec.js +0 -122
  450. package/dist/types/TypedFunctionType.spec.js.map +0 -1
  451. package/dist/types/UnionType.d.ts +0 -20
  452. package/dist/types/UnionType.js +0 -123
  453. package/dist/types/UnionType.js.map +0 -1
  454. package/dist/types/UnionType.spec.d.ts +0 -1
  455. package/dist/types/UnionType.spec.js +0 -130
  456. package/dist/types/UnionType.spec.js.map +0 -1
  457. package/dist/types/helper.spec.d.ts +0 -1
  458. package/dist/types/helper.spec.js +0 -145
  459. package/dist/types/helper.spec.js.map +0 -1
  460. package/dist/types/helpers.d.ts +0 -24
  461. package/dist/types/helpers.js +0 -178
  462. package/dist/types/helpers.js.map +0 -1
  463. package/dist/types/index.d.ts +0 -22
  464. package/dist/types/index.js +0 -39
  465. package/dist/types/index.js.map +0 -1
  466. /package/dist/astUtils/{Editor.spec.d.ts → AstEditor.spec.d.ts} +0 -0
  467. /package/dist/bscPlugin/{completions/CompletionsProcessor.spec.d.ts → definition/DefinitionProvider.spec.d.ts} +0 -0
  468. /package/dist/bscPlugin/{serialize/BslibInjector.spec.d.ts → references/ReferencesProvider.spec.d.ts} +0 -0
  469. /package/dist/bscPlugin/{transpile/BrsFileTranspileProcessor.spec.d.ts → symbols/DocumentSymbolProcessor.spec.d.ts} +0 -0
  470. /package/dist/bscPlugin/{validation/ScopeValidator.spec.d.ts → symbols/WorkspaceSymbolProcessor.spec.d.ts} +0 -0
  471. /package/dist/{files/LazyFileData.spec.d.ts → bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts} +0 -0
  472. /package/dist/{parser/tests/expression/TypeExpression.spec.d.ts → types/FunctionType.spec.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BrsFile = void 0;
3
+ exports.KeywordCompletions = exports.BrsFile = void 0;
4
4
  const source_map_1 = require("source-map");
5
5
  const vscode_languageserver_1 = require("vscode-languageserver");
6
6
  const vscode_languageserver_2 = require("vscode-languageserver");
@@ -12,25 +12,32 @@ const Lexer_1 = require("../lexer/Lexer");
12
12
  const TokenKind_1 = require("../lexer/TokenKind");
13
13
  const Parser_1 = require("../parser/Parser");
14
14
  const DynamicType_1 = require("../types/DynamicType");
15
+ const FunctionType_1 = require("../types/FunctionType");
16
+ const VoidType_1 = require("../types/VoidType");
15
17
  const util_1 = require("../util");
16
18
  const BrsTranspileState_1 = require("../parser/BrsTranspileState");
17
19
  const Preprocessor_1 = require("../preprocessor/Preprocessor");
18
- const Logger_1 = require("../Logger");
19
20
  const serialize_error_1 = require("serialize-error");
20
21
  const reflection_1 = require("../astUtils/reflection");
21
22
  const visitors_1 = require("../astUtils/visitors");
22
23
  const CommentFlagProcessor_1 = require("../CommentFlagProcessor");
23
- const vscode_uri_1 = require("vscode-uri");
24
- const SymbolTable_1 = require("../SymbolTable");
25
- const Editor_1 = require("../astUtils/Editor");
26
- const AstValidationSegmenter_1 = require("../AstValidationSegmenter");
24
+ const DefinitionProvider_1 = require("../bscPlugin/definition/DefinitionProvider");
25
+ const ReferencesProvider_1 = require("../bscPlugin/references/ReferencesProvider");
26
+ const DocumentSymbolProcessor_1 = require("../bscPlugin/symbols/DocumentSymbolProcessor");
27
+ const WorkspaceSymbolProcessor_1 = require("../bscPlugin/symbols/WorkspaceSymbolProcessor");
27
28
  /**
28
29
  * Holds all details about this file within the scope of the whole program
29
30
  */
30
31
  class BrsFile {
31
- constructor(options) {
32
- var _a, _b, _c;
33
- this.type = 'BrsFile';
32
+ constructor(srcPath,
33
+ /**
34
+ * The full pkg path to this file
35
+ */
36
+ pkgPath, program) {
37
+ var _a, _b;
38
+ this.srcPath = srcPath;
39
+ this.pkgPath = pkgPath;
40
+ this.program = program;
34
41
  /**
35
42
  * The parseMode used for the parser for this file
36
43
  */
@@ -47,53 +54,69 @@ class BrsFile {
47
54
  this.commentFlags = [];
48
55
  this.callables = [];
49
56
  this.functionCalls = [];
57
+ /**
58
+ * Does this file need to be transpiled?
59
+ */
60
+ this.needsTranspiled = false;
50
61
  this.scopesByFunc = new Map();
51
- this.validationSegmenter = new AstValidationSegmenter_1.AstValidationSegmenter();
52
- if (options) {
53
- this.srcPath = (0, util_1.standardizePath) `${options.srcPath}`;
54
- this.destPath = (0, util_1.standardizePath) `${options.destPath}`;
55
- this.program = options.program;
56
- this.extension = util_1.util.getExtension(this.srcPath);
57
- if (options.pkgPath) {
58
- this.pkgPath = options.pkgPath;
59
- }
60
- else {
61
- //don't rename .d.bs files to .d.brs
62
- if (this.extension === '.d.bs') {
63
- this.pkgPath = this.destPath;
64
- }
65
- else {
66
- this.pkgPath = this.destPath.replace(/\.bs$/i, '.brs');
67
- }
68
- }
69
- //all BrighterScript files need to be transpiled
70
- if (((_a = this.extension) === null || _a === void 0 ? void 0 : _a.endsWith('.bs')) || ((_c = (_b = this.program) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.allowBrighterScriptInBrightScript)) {
71
- this.parseMode = Parser_1.ParseMode.BrighterScript;
72
- }
73
- this.isTypedef = this.extension === '.d.bs';
74
- if (!this.isTypedef) {
75
- this.typedefKey = util_1.util.getTypedefPath(this.srcPath);
76
- }
77
- //global file doesn't have a program, so only resolve typedef info if we have a program
78
- if (this.program) {
79
- this.resolveTypedef();
80
- }
62
+ this.srcPath = (0, util_1.standardizePath) `${this.srcPath}`;
63
+ this.pkgPath = (0, util_1.standardizePath) `${this.pkgPath}`;
64
+ this.dependencyGraphKey = this.pkgPath.toLowerCase();
65
+ this.extension = util_1.util.getExtension(this.srcPath);
66
+ //all BrighterScript files need to be transpiled
67
+ if (((_a = this.extension) === null || _a === void 0 ? void 0 : _a.endsWith('.bs')) || ((_b = program === null || program === void 0 ? void 0 : program.options) === null || _b === void 0 ? void 0 : _b.allowBrighterScriptInBrightScript)) {
68
+ this.needsTranspiled = true;
69
+ this.parseMode = Parser_1.ParseMode.BrighterScript;
70
+ }
71
+ this.isTypedef = this.extension === '.d.bs';
72
+ if (!this.isTypedef) {
73
+ this.typedefKey = util_1.util.getTypedefPath(this.srcPath);
74
+ }
75
+ //global file doesn't have a program, so only resolve typedef info if we have a program
76
+ if (this.program) {
77
+ this.resolveTypedef();
81
78
  }
82
79
  }
83
80
  /**
84
- * @deprecated use `.diagnostics` instead
81
+ * The absolute path to the source location for this file
82
+ * @deprecated use `srcPath` instead
83
+ */
84
+ get pathAbsolute() {
85
+ return this.srcPath;
86
+ }
87
+ set pathAbsolute(value) {
88
+ this.srcPath = value;
89
+ }
90
+ /**
91
+ * Will this file result in only comment or whitespace output? If so, it can be excluded from the output if that bsconfig setting is enabled.
85
92
  */
93
+ get canBePruned() {
94
+ let canPrune = true;
95
+ this.ast.walk((0, visitors_1.createVisitor)({
96
+ FunctionStatement: () => {
97
+ canPrune = false;
98
+ },
99
+ ClassStatement: () => {
100
+ canPrune = false;
101
+ }
102
+ }), {
103
+ walkMode: visitors_1.WalkMode.visitStatements
104
+ });
105
+ return canPrune;
106
+ }
86
107
  getDiagnostics() {
87
- return this.diagnostics;
108
+ return [...this.diagnostics];
88
109
  }
89
110
  addDiagnostic(diagnostic) {
90
- if (!diagnostic.file) {
91
- diagnostic.file = this;
92
- }
93
- this.diagnostics.push(diagnostic);
111
+ this.addDiagnostics([diagnostic]);
94
112
  }
95
113
  addDiagnostics(diagnostics) {
96
- this.diagnostics.push(...diagnostics);
114
+ for (const diagnostic of diagnostics) {
115
+ if (!diagnostic.file) {
116
+ diagnostic.file = this;
117
+ }
118
+ this.diagnostics.push(diagnostic);
119
+ }
97
120
  }
98
121
  get functionScopes() {
99
122
  if (!this._functionScopes) {
@@ -119,7 +142,7 @@ class BrsFile {
119
142
  if ((0, reflection_1.isImportStatement)(statement) && statement.filePathToken) {
120
143
  result.push({
121
144
  filePathRange: statement.filePathToken.range,
122
- destPath: util_1.util.getPkgPathFromTarget(this.destPath, statement.filePath),
145
+ pkgPath: util_1.util.getPkgPathFromTarget(this.pkgPath, statement.filePath),
123
146
  sourceFile: this,
124
147
  text: (_d = statement.filePathToken) === null || _d === void 0 ? void 0 : _d.text
125
148
  });
@@ -129,26 +152,11 @@ class BrsFile {
129
152
  })) !== null && _b !== void 0 ? _b : [];
130
153
  return result;
131
154
  }
132
- /**
133
- * Does this file need to be transpiled?
134
- * @deprecated use the `.editor` property to push changes to the file, which will force transpilation
135
- */
136
- get needsTranspiled() {
137
- var _a, _b, _c, _d;
138
- if (this._needsTranspiled !== undefined) {
139
- return this._needsTranspiled;
140
- }
141
- return !!(((_a = this.extension) === null || _a === void 0 ? void 0 : _a.endsWith('.bs')) || ((_c = (_b = this.program) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.allowBrighterScriptInBrightScript) || ((_d = this.editor) === null || _d === void 0 ? void 0 : _d.hasChanges));
142
- }
143
- set needsTranspiled(value) {
144
- this._needsTranspiled = value;
145
- }
146
155
  /**
147
156
  * The AST for this file
148
157
  */
149
158
  get ast() {
150
- var _a;
151
- return (_a = this.parser) === null || _a === void 0 ? void 0 : _a.ast;
159
+ return this.parser.ast;
152
160
  }
153
161
  /**
154
162
  * Get the token at the specified position
@@ -202,25 +210,23 @@ class BrsFile {
202
210
  this.typedefFile = this.program.getFile(this.typedefKey);
203
211
  this.hasTypedef = !!this.typedefFile;
204
212
  }
205
- onDependenciesChanged() {
206
- this.resolveTypedef();
207
- }
208
213
  /**
209
214
  * Attach the file to the dependency graph so it can monitor changes.
210
215
  * Also notify the dependency graph of our current dependencies so other dependents can be notified.
211
- * @deprecated this does nothing. This functionality is now handled by the file api and will be deleted in v1
212
- */
213
- attachDependencyGraph(dependencyGraph) { }
214
- /**
215
- * The list of files that this file depends on
216
216
  */
217
- get dependencies() {
218
- const result = this.ownScriptImports.filter(x => !!x.destPath).map(x => x.destPath.toLowerCase());
217
+ attachDependencyGraph(dependencyGraph) {
218
+ var _a;
219
+ (_a = this.unsubscribeFromDependencyGraph) === null || _a === void 0 ? void 0 : _a.call(this);
220
+ //event that fires anytime a dependency changes
221
+ this.unsubscribeFromDependencyGraph = dependencyGraph.onchange(this.dependencyGraphKey, () => {
222
+ this.resolveTypedef();
223
+ });
224
+ const dependencies = this.ownScriptImports.filter(x => !!x.pkgPath).map(x => x.pkgPath.toLowerCase());
219
225
  //if this is a .brs file, watch for typedef changes
220
226
  if (this.extension === '.brs') {
221
- result.push(util_1.util.getTypedefPath(this.destPath));
227
+ dependencies.push(util_1.util.getTypedefPath(this.pkgPath));
222
228
  }
223
- return result;
229
+ dependencyGraph.addOrReplace(this.dependencyGraphKey, dependencies);
224
230
  }
225
231
  /**
226
232
  * Calculate the AST for this file
@@ -237,7 +243,7 @@ class BrsFile {
237
243
  return;
238
244
  }
239
245
  //tokenize the input file
240
- let lexer = this.program.logger.time(Logger_1.LogLevel.debug, ['lexer.lex', chalk_1.default.green(this.srcPath)], () => {
246
+ let lexer = this.program.logger.time('debug', ['lexer.lex', chalk_1.default.green(this.srcPath)], () => {
241
247
  return Lexer_1.Lexer.scan(fileContents, {
242
248
  includeWhitespace: false
243
249
  });
@@ -248,7 +254,7 @@ class BrsFile {
248
254
  //TODO preprocessor should go away in favor of the AST handling this internally (because it affects transpile)
249
255
  //currently the preprocessor throws exceptions on syntax errors...so we need to catch it
250
256
  try {
251
- this.program.logger.time(Logger_1.LogLevel.debug, ['preprocessor.process', chalk_1.default.green(this.srcPath)], () => {
257
+ this.program.logger.time('debug', ['preprocessor.process', chalk_1.default.green(this.srcPath)], () => {
252
258
  preprocessor.process(lexer.tokens, this.program.getManifest());
253
259
  });
254
260
  }
@@ -260,7 +266,7 @@ class BrsFile {
260
266
  }
261
267
  //if the preprocessor generated tokens, use them.
262
268
  let tokens = preprocessor.processedTokens.length > 0 ? preprocessor.processedTokens : lexer.tokens;
263
- this.program.logger.time(Logger_1.LogLevel.debug, ['parser.parse', chalk_1.default.green(this.srcPath)], () => {
269
+ this.program.logger.time('debug', ['parser.parse', chalk_1.default.green(this.srcPath)], () => {
264
270
  this._parser = Parser_1.Parser.parse(tokens, {
265
271
  mode: this.parseMode,
266
272
  logger: this.program.logger
@@ -282,6 +288,11 @@ class BrsFile {
282
288
  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)))));
283
289
  }
284
290
  }
291
+ /**
292
+ * @deprecated logic has moved into BrsFileValidator, this is now an empty function
293
+ */
294
+ validate() {
295
+ }
285
296
  /**
286
297
  * Find a class. This scans all scopes for this file, and returns the first matching class that is found.
287
298
  * Returns undefined if not found.
@@ -338,7 +349,7 @@ class BrsFile {
338
349
  * Create a scope for every function in this file
339
350
  */
340
351
  createFunctionScopes() {
341
- var _a;
352
+ var _a, _b, _c;
342
353
  //find every function
343
354
  let functions = this.parser.references.functionExpressions;
344
355
  //create a functionScope for every function
@@ -347,7 +358,7 @@ class BrsFile {
347
358
  let scope = new FunctionScope_1.FunctionScope(func);
348
359
  //find parent function, and add this scope to it if found
349
360
  {
350
- let parentScope = this.scopesByFunc.get(func.findAncestor(reflection_1.isFunctionExpression));
361
+ let parentScope = this.scopesByFunc.get(func.parentFunction);
351
362
  //add this child scope to its parent
352
363
  if (parentScope) {
353
364
  parentScope.childrenScopes.push(scope);
@@ -359,28 +370,28 @@ class BrsFile {
359
370
  for (let param of func.parameters) {
360
371
  scope.variableDeclarations.push({
361
372
  nameRange: param.name.range,
362
- lineIndex: param.name.range.start.line,
373
+ lineIndex: (_a = param.name.range) === null || _a === void 0 ? void 0 : _a.start.line,
363
374
  name: param.name.text,
364
- getType: () => {
365
- return param.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
366
- }
375
+ type: param.type
367
376
  });
368
377
  }
369
378
  //add all of ForEachStatement loop varibales
370
- (_a = func.body) === null || _a === void 0 ? void 0 : _a.walk((0, visitors_1.createVisitor)({
379
+ (_b = func.body) === null || _b === void 0 ? void 0 : _b.walk((0, visitors_1.createVisitor)({
371
380
  ForEachStatement: (stmt) => {
381
+ var _a;
372
382
  scope.variableDeclarations.push({
373
383
  nameRange: stmt.item.range,
374
- lineIndex: stmt.item.range.start.line,
384
+ lineIndex: (_a = stmt.item.range) === null || _a === void 0 ? void 0 : _a.start.line,
375
385
  name: stmt.item.text,
376
- getType: () => DynamicType_1.DynamicType.instance //TODO: Infer types from array
386
+ type: new DynamicType_1.DynamicType()
377
387
  });
378
388
  },
379
389
  LabelStatement: (stmt) => {
390
+ var _a;
380
391
  const { identifier } = stmt.tokens;
381
392
  scope.labelStatements.push({
382
393
  nameRange: identifier.range,
383
- lineIndex: identifier.range.start.line,
394
+ lineIndex: (_a = identifier.range) === null || _a === void 0 ? void 0 : _a.start.line,
384
395
  name: identifier.text
385
396
  });
386
397
  }
@@ -395,36 +406,95 @@ class BrsFile {
395
406
  let assignmentStatements = this.parser.references.assignmentStatements;
396
407
  for (let statement of assignmentStatements) {
397
408
  //find this statement's function scope
398
- let scope = this.scopesByFunc.get(statement.findAncestor(reflection_1.isFunctionExpression));
409
+ let scope = this.scopesByFunc.get(statement.containingFunction);
399
410
  //skip variable declarations that are outside of any scope
400
411
  if (scope) {
401
412
  scope.variableDeclarations.push({
402
413
  nameRange: statement.name.range,
403
- lineIndex: statement.name.range.start.line,
414
+ lineIndex: (_c = statement.name.range) === null || _c === void 0 ? void 0 : _c.start.line,
404
415
  name: statement.name.text,
405
- getType: () => {
406
- return statement.getType({ flags: SymbolTable_1.SymbolTypeFlag.runtime });
407
- }
416
+ type: this.getBscTypeFromAssignment(statement, scope)
408
417
  });
409
418
  }
410
419
  }
411
420
  }
421
+ getBscTypeFromAssignment(assignment, scope) {
422
+ var _a, _b, _c, _d;
423
+ try {
424
+ //function
425
+ if ((0, reflection_1.isFunctionExpression)(assignment.value)) {
426
+ let functionType = new FunctionType_1.FunctionType(assignment.value.returnType);
427
+ functionType.isSub = assignment.value.functionType.text === 'sub';
428
+ if (functionType.isSub) {
429
+ functionType.returnType = new VoidType_1.VoidType();
430
+ }
431
+ functionType.setName(assignment.name.text);
432
+ for (let param of assignment.value.parameters) {
433
+ let isOptional = !!param.defaultValue;
434
+ //TODO compute optional parameters
435
+ functionType.addParameter(param.name.text, param.type, isOptional);
436
+ }
437
+ return functionType;
438
+ //literal
439
+ }
440
+ else if ((0, reflection_1.isLiteralExpression)(assignment.value)) {
441
+ return assignment.value.type;
442
+ //function call
443
+ }
444
+ else if ((0, reflection_1.isCallExpression)(assignment.value)) {
445
+ let calleeName = (_b = (_a = assignment.value.callee) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.text;
446
+ if (calleeName) {
447
+ let func = this.getCallableByName(calleeName);
448
+ if (func) {
449
+ return func.type.returnType;
450
+ }
451
+ }
452
+ }
453
+ else if ((0, reflection_1.isVariableExpression)(assignment.value)) {
454
+ let variableName = (_d = (_c = assignment.value) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.text;
455
+ let variable = scope.getVariableByName(variableName);
456
+ return variable.type;
457
+ }
458
+ }
459
+ catch (e) {
460
+ //do nothing. Just return dynamic
461
+ }
462
+ //fallback to dynamic
463
+ return new DynamicType_1.DynamicType();
464
+ }
465
+ getCallableByName(name) {
466
+ name = name ? name.toLowerCase() : undefined;
467
+ if (!name) {
468
+ return;
469
+ }
470
+ for (let func of this.callables) {
471
+ if (func.name.toLowerCase() === name) {
472
+ return func;
473
+ }
474
+ }
475
+ }
412
476
  findCallables() {
413
477
  var _a;
414
478
  for (let statement of (_a = this.parser.references.functionStatements) !== null && _a !== void 0 ? _a : []) {
479
+ let functionType = new FunctionType_1.FunctionType(statement.func.returnType);
480
+ functionType.setName(statement.name.text);
481
+ functionType.isSub = statement.func.functionType.text.toLowerCase() === 'sub';
482
+ if (functionType.isSub) {
483
+ functionType.returnType = new VoidType_1.VoidType();
484
+ }
415
485
  //extract the parameters
416
486
  let params = [];
417
487
  for (let param of statement.func.parameters) {
418
- const paramType = param.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
419
488
  let callableParam = {
420
489
  name: param.name.text,
421
- type: paramType,
490
+ type: param.type,
422
491
  isOptional: !!param.defaultValue,
423
492
  isRestArgument: false
424
493
  };
425
494
  params.push(callableParam);
495
+ let isOptional = !!param.defaultValue;
496
+ functionType.addParameter(callableParam.name, callableParam.type, isOptional);
426
497
  }
427
- const funcType = statement.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
428
498
  this.callables.push({
429
499
  isSub: statement.func.functionType.text.toLowerCase() === 'sub',
430
500
  name: statement.name.text,
@@ -432,7 +502,7 @@ class BrsFile {
432
502
  file: this,
433
503
  params: params,
434
504
  range: statement.func.range,
435
- type: funcType,
505
+ type: functionType,
436
506
  getName: statement.getName.bind(statement),
437
507
  hasNamespace: !!statement.findAncestor(reflection_1.isNamespaceStatement),
438
508
  functionStatement: statement
@@ -466,7 +536,7 @@ class BrsFile {
466
536
  if ((0, reflection_1.isLiteralExpression)(arg)) {
467
537
  args.push({
468
538
  range: arg.range,
469
- type: arg.getType(),
539
+ type: arg.type,
470
540
  text: arg.token.text,
471
541
  expression: arg,
472
542
  typeToken: undefined
@@ -521,8 +591,7 @@ class BrsFile {
521
591
  name: functionName,
522
592
  nameRange: util_1.util.createRange(callee.range.start.line, columnIndexBegin, callee.range.start.line, columnIndexEnd),
523
593
  //TODO keep track of parameters
524
- args: args,
525
- expression: expression
594
+ args: args
526
595
  };
527
596
  this.functionCalls.push(functionCall);
528
597
  }
@@ -568,37 +637,345 @@ class BrsFile {
568
637
  });
569
638
  }
570
639
  }
571
- getNamespaceDefinitions(token, file) {
572
- //BrightScript does not support namespaces, so return an empty list in that case
573
- if (!token) {
574
- return undefined;
640
+ /**
641
+ * Get completions available at the given cursor. This aggregates all values from this file and the current scope.
642
+ */
643
+ getCompletions(position, scope) {
644
+ let result = [];
645
+ //a map of lower-case names of all added options
646
+ let names = {};
647
+ //handle script import completions
648
+ let scriptImport = util_1.util.getScriptImportAtPosition(this.ownScriptImports, position);
649
+ if (scriptImport) {
650
+ return this.program.getScriptImportCompletions(this.pkgPath, scriptImport);
651
+ }
652
+ //if cursor is within a comment, disable completions
653
+ let currentToken = this.getTokenAt(position);
654
+ const tokenKind = currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind;
655
+ if (tokenKind === TokenKind_1.TokenKind.Comment) {
656
+ return [];
657
+ }
658
+ else if (tokenKind === TokenKind_1.TokenKind.StringLiteral || tokenKind === TokenKind_1.TokenKind.TemplateStringQuasi) {
659
+ const match = /^("?)(pkg|libpkg):/.exec(currentToken.text);
660
+ if (match) {
661
+ const [, openingQuote, fileProtocol] = match;
662
+ //include every absolute file path from this scope
663
+ for (const file of scope.getAllFiles()) {
664
+ const pkgPath = `${fileProtocol}:/${file.pkgPath.replace(/\\/g, '/')}`;
665
+ result.push({
666
+ label: pkgPath,
667
+ textEdit: vscode_languageserver_2.TextEdit.replace(util_1.util.createRange(currentToken.range.start.line,
668
+ //+1 to step past the opening quote
669
+ currentToken.range.start.character + (openingQuote ? 1 : 0), currentToken.range.end.line,
670
+ //-1 to exclude the closing quotemark (or the end character if there is no closing quotemark)
671
+ currentToken.range.end.character + (currentToken.text.endsWith('"') ? -1 : 0)), pkgPath),
672
+ kind: vscode_languageserver_2.CompletionItemKind.File
673
+ });
674
+ }
675
+ return result;
676
+ }
677
+ else {
678
+ //do nothing. we don't want to show completions inside of strings...
679
+ return [];
680
+ }
575
681
  }
576
- let location;
577
- const nameParts = this.getPartialVariableName(token, [TokenKind_1.TokenKind.New]).split('.');
578
- const endName = nameParts[nameParts.length - 1].toLowerCase();
579
- const namespaceName = nameParts.slice(0, -1).join('.').toLowerCase();
580
- const statementHandler = (statement) => {
581
- if (!location && statement.getName(Parser_1.ParseMode.BrighterScript).toLowerCase() === namespaceName) {
582
- const namespaceItemStatementHandler = (statement) => {
583
- if (!location && statement.name.text.toLowerCase() === endName) {
584
- const uri = util_1.util.pathToUri(file.srcPath);
585
- location = util_1.util.createLocation(uri, statement.range);
682
+ const namespaceCompletions = this.getNamespaceCompletions(currentToken, this.parseMode, scope);
683
+ if (namespaceCompletions.length > 0) {
684
+ return [...namespaceCompletions];
685
+ }
686
+ const enumMemberCompletions = this.getEnumMemberStatementCompletions(currentToken, this.parseMode, scope);
687
+ if (enumMemberCompletions.length > 0) {
688
+ // no other completion is valid in this case
689
+ return enumMemberCompletions;
690
+ }
691
+ //determine if cursor is inside a function
692
+ let functionScope = this.getFunctionScopeAtPosition(position);
693
+ if (!functionScope) {
694
+ //we aren't in any function scope, so return the keyword completions and namespaces
695
+ if (this.getTokenBefore(currentToken, TokenKind_1.TokenKind.New)) {
696
+ // there's a new keyword, so only class types are viable here
697
+ return [...this.getGlobalClassStatementCompletions(currentToken, this.parseMode)];
698
+ }
699
+ else {
700
+ return [
701
+ ...exports.KeywordCompletions,
702
+ ...this.getGlobalClassStatementCompletions(currentToken, this.parseMode),
703
+ ...namespaceCompletions,
704
+ ...this.getNonNamespacedEnumStatementCompletions(currentToken, this.parseMode, scope)
705
+ ];
706
+ }
707
+ }
708
+ const classNameCompletions = this.getGlobalClassStatementCompletions(currentToken, this.parseMode);
709
+ const newToken = this.getTokenBefore(currentToken, TokenKind_1.TokenKind.New);
710
+ if (newToken) {
711
+ //we are after a new keyword; so we can only be top-level namespaces or classes at this point
712
+ result.push(...classNameCompletions);
713
+ result.push(...namespaceCompletions);
714
+ return result;
715
+ }
716
+ if (this.tokenFollows(currentToken, TokenKind_1.TokenKind.Goto)) {
717
+ return this.getLabelCompletion(functionScope);
718
+ }
719
+ if (this.isPositionNextToTokenKind(position, TokenKind_1.TokenKind.Dot)) {
720
+ const selfClassMemberCompletions = this.getClassMemberCompletions(position, currentToken, functionScope, scope);
721
+ if (selfClassMemberCompletions.size > 0) {
722
+ return [...selfClassMemberCompletions.values()].filter((i) => i.label !== 'new');
723
+ }
724
+ if (!this.getClassFromMReference(position, currentToken, functionScope)) {
725
+ //and anything from any class in scope to a non m class
726
+ let classMemberCompletions = scope.getAllClassMemberCompletions();
727
+ result.push(...classMemberCompletions.values());
728
+ result.push(...scope.getPropertyNameCompletions().filter((i) => !classMemberCompletions.has(i.label)));
729
+ }
730
+ else {
731
+ result.push(...scope.getPropertyNameCompletions());
732
+ }
733
+ }
734
+ else {
735
+ result.push(
736
+ //include namespaces
737
+ ...namespaceCompletions,
738
+ //include class names
739
+ ...classNameCompletions,
740
+ //include enums
741
+ ...this.getNonNamespacedEnumStatementCompletions(currentToken, this.parseMode, scope),
742
+ //include constants
743
+ ...this.getNonNamespacedConstStatementCompletions(currentToken, this.parseMode, scope),
744
+ //include the global callables
745
+ ...scope.getCallablesAsCompletions(this.parseMode));
746
+ //add `m` because that's always valid within a function
747
+ result.push({
748
+ label: 'm',
749
+ kind: vscode_languageserver_2.CompletionItemKind.Variable
750
+ });
751
+ names.m = true;
752
+ result.push(...exports.KeywordCompletions);
753
+ //include local variables
754
+ let variables = functionScope.variableDeclarations;
755
+ for (let variable of variables) {
756
+ //skip duplicate variable names
757
+ if (names[variable.name.toLowerCase()]) {
758
+ continue;
759
+ }
760
+ names[variable.name.toLowerCase()] = true;
761
+ result.push({
762
+ label: variable.name,
763
+ kind: (0, reflection_1.isFunctionType)(variable.type) ? vscode_languageserver_2.CompletionItemKind.Function : vscode_languageserver_2.CompletionItemKind.Variable
764
+ });
765
+ }
766
+ if (this.parseMode === Parser_1.ParseMode.BrighterScript) {
767
+ //include the first part of namespaces
768
+ let namespaces = scope.getAllNamespaceStatements();
769
+ for (let stmt of namespaces) {
770
+ let firstPart = stmt.nameExpression.getNameParts().shift();
771
+ //skip duplicate namespace names
772
+ if (names[firstPart.toLowerCase()]) {
773
+ continue;
586
774
  }
587
- };
588
- file.parser.ast.walk((0, visitors_1.createVisitor)({
589
- ClassStatement: namespaceItemStatementHandler,
590
- FunctionStatement: namespaceItemStatementHandler
591
- }), {
592
- walkMode: visitors_1.WalkMode.visitStatements
775
+ names[firstPart.toLowerCase()] = true;
776
+ result.push({
777
+ label: firstPart,
778
+ kind: vscode_languageserver_2.CompletionItemKind.Module
779
+ });
780
+ }
781
+ }
782
+ }
783
+ return result;
784
+ }
785
+ getLabelCompletion(functionScope) {
786
+ return functionScope.labelStatements.map(label => ({
787
+ label: label.name,
788
+ kind: vscode_languageserver_2.CompletionItemKind.Reference
789
+ }));
790
+ }
791
+ getClassMemberCompletions(position, currentToken, functionScope, scope) {
792
+ var _a, _b, _c, _d;
793
+ let classStatement = this.getClassFromMReference(position, currentToken, functionScope);
794
+ let results = new Map();
795
+ if (classStatement) {
796
+ let classes = scope.getClassHierarchy(classStatement.item.getName(Parser_1.ParseMode.BrighterScript).toLowerCase());
797
+ for (let cs of classes) {
798
+ 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 : []]) {
799
+ if (!results.has(member.name.text.toLowerCase())) {
800
+ results.set(member.name.text.toLowerCase(), {
801
+ label: member.name.text,
802
+ kind: (0, reflection_1.isFieldStatement)(member) ? vscode_languageserver_2.CompletionItemKind.Field : vscode_languageserver_2.CompletionItemKind.Function
803
+ });
804
+ }
805
+ }
806
+ }
807
+ }
808
+ return results;
809
+ }
810
+ getClassFromMReference(position, currentToken, functionScope) {
811
+ let previousToken = this.getPreviousToken(currentToken);
812
+ if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === TokenKind_1.TokenKind.Dot) {
813
+ previousToken = this.getPreviousToken(previousToken);
814
+ }
815
+ if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === TokenKind_1.TokenKind.Identifier && (previousToken === null || previousToken === void 0 ? void 0 : previousToken.text.toLowerCase()) === 'm' && (0, reflection_1.isMethodStatement)(functionScope.func.functionStatement)) {
816
+ return { item: this.parser.references.classStatements.find((cs) => util_1.util.rangeContains(cs.range, position)), file: this };
817
+ }
818
+ return undefined;
819
+ }
820
+ getGlobalClassStatementCompletions(currentToken, parseMode) {
821
+ var _a;
822
+ if (parseMode === Parser_1.ParseMode.BrightScript) {
823
+ return [];
824
+ }
825
+ let results = new Map();
826
+ let completionName = (_a = this.getPartialVariableName(currentToken, [TokenKind_1.TokenKind.New])) === null || _a === void 0 ? void 0 : _a.toLowerCase();
827
+ if (completionName === null || completionName === void 0 ? void 0 : completionName.includes('.')) {
828
+ return [];
829
+ }
830
+ let scopes = this.program.getScopesForFile(this);
831
+ for (let scope of scopes) {
832
+ let classMap = scope.getClassMap();
833
+ for (const key of [...classMap.keys()]) {
834
+ let cs = classMap.get(key).item;
835
+ if (!results.has(cs.name.text)) {
836
+ results.set(cs.name.text, {
837
+ label: cs.name.text,
838
+ kind: vscode_languageserver_2.CompletionItemKind.Class
839
+ });
840
+ }
841
+ }
842
+ }
843
+ return [...results.values()];
844
+ }
845
+ getNonNamespacedEnumStatementCompletions(currentToken, parseMode, scope) {
846
+ var _a, _b;
847
+ if (parseMode !== Parser_1.ParseMode.BrighterScript) {
848
+ return [];
849
+ }
850
+ const containingNamespaceName = ((_b = this.getNamespaceStatementForPosition((_a = currentToken === null || currentToken === void 0 ? void 0 : currentToken.range) === null || _a === void 0 ? void 0 : _a.start)) === null || _b === void 0 ? void 0 : _b.name) + '.';
851
+ const results = new Map();
852
+ const enumMap = scope.getEnumMap();
853
+ for (const key of [...enumMap.keys()]) {
854
+ const enumStatement = enumMap.get(key).item;
855
+ const fullName = enumStatement.fullName;
856
+ //if the enum is contained within our own namespace, or if it's a non-namespaced enum
857
+ if (fullName.startsWith(containingNamespaceName) || !fullName.includes('.')) {
858
+ results.set(fullName, {
859
+ label: enumStatement.name,
860
+ kind: vscode_languageserver_2.CompletionItemKind.Enum
593
861
  });
594
862
  }
595
- };
596
- file.parser.ast.walk((0, visitors_1.createVisitor)({
597
- NamespaceStatement: statementHandler
598
- }), {
599
- walkMode: visitors_1.WalkMode.visitStatements
600
- });
601
- return location;
863
+ }
864
+ return [...results.values()];
865
+ }
866
+ getNonNamespacedConstStatementCompletions(currentToken, parseMode, scope) {
867
+ var _a, _b;
868
+ if (parseMode !== Parser_1.ParseMode.BrighterScript) {
869
+ return [];
870
+ }
871
+ const containingNamespaceName = ((_b = this.getNamespaceStatementForPosition((_a = currentToken === null || currentToken === void 0 ? void 0 : currentToken.range) === null || _a === void 0 ? void 0 : _a.start)) === null || _b === void 0 ? void 0 : _b.name) + '.';
872
+ const results = new Map();
873
+ const map = scope.getConstMap();
874
+ for (const key of [...map.keys()]) {
875
+ const statement = map.get(key).item;
876
+ const fullName = statement.fullName;
877
+ //if the item is contained within our own namespace, or if it's non-namespaced
878
+ if (fullName.startsWith(containingNamespaceName) || !fullName.includes('.')) {
879
+ results.set(fullName, {
880
+ label: statement.name,
881
+ kind: vscode_languageserver_2.CompletionItemKind.Constant
882
+ });
883
+ }
884
+ }
885
+ return [...results.values()];
886
+ }
887
+ getEnumMemberStatementCompletions(currentToken, parseMode, scope) {
888
+ var _a, _b, _c, _d, _e;
889
+ if (parseMode === Parser_1.ParseMode.BrightScript || !currentToken) {
890
+ return [];
891
+ }
892
+ const results = new Map();
893
+ const completionName = (_a = this.getPartialVariableName(currentToken)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
894
+ //if we don't have a completion name, or if there's no period in the name, then this is not to the right of an enum name
895
+ if (!completionName || !completionName.includes('.')) {
896
+ return [];
897
+ }
898
+ const enumNameLower = (_b = completionName === null || completionName === void 0 ? void 0 : completionName.split(/\.(\w+)?$/)[0]) === null || _b === void 0 ? void 0 : _b.toLowerCase();
899
+ const namespaceNameLower = (_c = this.getNamespaceStatementForPosition(currentToken.range.end)) === null || _c === void 0 ? void 0 : _c.name.toLowerCase();
900
+ const enumMap = scope.getEnumMap();
901
+ //get the enum statement with this name (check without namespace prefix first, then with inferred namespace prefix next)
902
+ const enumStatement = (_e = ((_d = enumMap.get(enumNameLower)) !== null && _d !== void 0 ? _d : enumMap.get(namespaceNameLower + '.' + enumNameLower))) === null || _e === void 0 ? void 0 : _e.item;
903
+ //if we found an enum with this name
904
+ if (enumStatement) {
905
+ for (const member of enumStatement.getMembers()) {
906
+ const name = enumStatement.fullName + '.' + member.name;
907
+ const nameLower = name.toLowerCase();
908
+ results.set(nameLower, {
909
+ label: member.name,
910
+ kind: vscode_languageserver_2.CompletionItemKind.EnumMember
911
+ });
912
+ }
913
+ }
914
+ return [...results.values()];
915
+ }
916
+ getNamespaceCompletions(currentToken, parseMode, scope) {
917
+ //BrightScript does not support namespaces, so return an empty list in that case
918
+ if (parseMode === Parser_1.ParseMode.BrightScript) {
919
+ return [];
920
+ }
921
+ const completionName = this.getPartialVariableName(currentToken, [TokenKind_1.TokenKind.New]);
922
+ //if we don't have a completion name, or if there's no period in the name, then this is not a namespaced variable
923
+ if (!completionName || !completionName.includes('.')) {
924
+ return [];
925
+ }
926
+ //remove any trailing identifer and then any trailing dot, to give us the
927
+ //name of its immediate parent namespace
928
+ let closestParentNamespaceName = completionName.replace(/\.([a-z0-9_]*)?$/gi, '').toLowerCase();
929
+ let newToken = this.getTokenBefore(currentToken, TokenKind_1.TokenKind.New);
930
+ let result = new Map();
931
+ for (let [, namespace] of scope.namespaceLookup) {
932
+ //completionName = "NameA."
933
+ //completionName = "NameA.Na
934
+ //NameA
935
+ //NameA.NameB
936
+ //NameA.NameB.NameC
937
+ if (namespace.fullName.toLowerCase() === closestParentNamespaceName) {
938
+ //add all of this namespace's immediate child namespaces, bearing in mind if we are after a new keyword
939
+ for (let [, ns] of namespace.namespaces) {
940
+ if (!newToken || ns.statements.find((s) => (0, reflection_1.isClassStatement)(s))) {
941
+ if (!result.has(ns.lastPartName)) {
942
+ result.set(ns.lastPartName, {
943
+ label: ns.lastPartName,
944
+ kind: vscode_languageserver_2.CompletionItemKind.Module
945
+ });
946
+ }
947
+ }
948
+ }
949
+ //add function and class statement completions
950
+ for (let stmt of namespace.statements) {
951
+ if ((0, reflection_1.isClassStatement)(stmt)) {
952
+ result.set(stmt.name.text, {
953
+ label: stmt.name.text,
954
+ kind: vscode_languageserver_2.CompletionItemKind.Class
955
+ });
956
+ }
957
+ else if ((0, reflection_1.isFunctionStatement)(stmt) && !newToken) {
958
+ result.set(stmt.name.text, {
959
+ label: stmt.name.text,
960
+ kind: vscode_languageserver_2.CompletionItemKind.Function
961
+ });
962
+ }
963
+ else if ((0, reflection_1.isEnumStatement)(stmt) && !newToken) {
964
+ result.set(stmt.name, {
965
+ label: stmt.name,
966
+ kind: vscode_languageserver_2.CompletionItemKind.Enum
967
+ });
968
+ }
969
+ else if ((0, reflection_1.isConstStatement)(stmt) && !newToken) {
970
+ result.set(stmt.name, {
971
+ label: stmt.name,
972
+ kind: vscode_languageserver_2.CompletionItemKind.Constant
973
+ });
974
+ }
975
+ }
976
+ }
977
+ }
978
+ return [...result.values()];
602
979
  }
603
980
  /**
604
981
  * Given a current token, walk
@@ -627,9 +1004,6 @@ class BrsFile {
627
1004
  }
628
1005
  isPositionNextToTokenKind(position, tokenKind) {
629
1006
  const closestToken = this.getClosestToken(position);
630
- return this.isTokenNextToTokenKind(closestToken, tokenKind);
631
- }
632
- isTokenNextToTokenKind(closestToken, tokenKind) {
633
1007
  const previousToken = this.getPreviousToken(closestToken);
634
1008
  const previousTokenKind = previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind;
635
1009
  //next to matched token
@@ -652,9 +1026,6 @@ class BrsFile {
652
1026
  }
653
1027
  getTokenBefore(currentToken, tokenKind) {
654
1028
  const index = this.parser.tokens.indexOf(currentToken);
655
- if (!tokenKind) {
656
- return this.parser.tokens[index - 1];
657
- }
658
1029
  for (let i = index - 1; i >= 0; i--) {
659
1030
  currentToken = this.parser.tokens[i];
660
1031
  if (currentToken.kind === TokenKind_1.TokenKind.Newline) {
@@ -722,7 +1093,7 @@ class BrsFile {
722
1093
  let scopes = this.program.getScopesForFile(this);
723
1094
  for (let scope of scopes) {
724
1095
  let namespace = scope.namespaceLookup.get(namespaceName.toLowerCase());
725
- if (namespace.functionStatements.has(lowerCalleeName)) {
1096
+ if (namespace === null || namespace === void 0 ? void 0 : namespace.functionStatements[lowerCalleeName]) {
726
1097
  return true;
727
1098
  }
728
1099
  }
@@ -752,248 +1123,36 @@ class BrsFile {
752
1123
  }
753
1124
  /**
754
1125
  * Builds a list of document symbols for this file. Used by LanguageServer's onDocumentSymbol functionality
1126
+ * @deprecated use `DocumentSymbolProvider.process()` instead
755
1127
  */
756
1128
  getDocumentSymbols() {
757
- if (this.documentSymbols) {
758
- return this.documentSymbols;
759
- }
760
- let symbols = [];
761
- for (const statement of this.ast.statements) {
762
- const symbol = this.getDocumentSymbol(statement);
763
- if (symbol) {
764
- symbols.push(symbol);
765
- }
766
- }
767
- this.documentSymbols = symbols;
768
- return symbols;
1129
+ return new DocumentSymbolProcessor_1.DocumentSymbolProcessor({
1130
+ documentSymbols: [],
1131
+ file: this,
1132
+ program: this.program
1133
+ }).process();
769
1134
  }
770
1135
  /**
771
1136
  * Builds a list of workspace symbols for this file. Used by LanguageServer's onWorkspaceSymbol functionality
772
1137
  */
773
1138
  getWorkspaceSymbols() {
774
- if (this.workspaceSymbols) {
775
- return this.workspaceSymbols;
776
- }
777
- let symbols = [];
778
- for (const statement of this.ast.statements) {
779
- for (const symbol of this.generateWorkspaceSymbols(statement)) {
780
- symbols.push(symbol);
781
- }
782
- }
783
- this.workspaceSymbols = symbols;
784
- return symbols;
785
- }
786
- /**
787
- * Builds a single DocumentSymbol object for use by LanguageServer's onDocumentSymbol functionality
788
- */
789
- getDocumentSymbol(statement) {
790
- let symbolKind;
791
- const children = [];
792
- if ((0, reflection_1.isFunctionStatement)(statement)) {
793
- symbolKind = vscode_languageserver_2.SymbolKind.Function;
794
- }
795
- else if ((0, reflection_1.isMethodStatement)(statement)) {
796
- symbolKind = vscode_languageserver_2.SymbolKind.Method;
797
- }
798
- else if ((0, reflection_1.isFieldStatement)(statement)) {
799
- symbolKind = vscode_languageserver_2.SymbolKind.Field;
800
- }
801
- else if ((0, reflection_1.isNamespaceStatement)(statement)) {
802
- symbolKind = vscode_languageserver_2.SymbolKind.Namespace;
803
- for (const childStatement of statement.body.statements) {
804
- const symbol = this.getDocumentSymbol(childStatement);
805
- if (symbol) {
806
- children.push(symbol);
807
- }
808
- }
809
- }
810
- else if ((0, reflection_1.isClassStatement)(statement)) {
811
- symbolKind = vscode_languageserver_2.SymbolKind.Class;
812
- for (const childStatement of statement.body) {
813
- const symbol = this.getDocumentSymbol(childStatement);
814
- if (symbol) {
815
- children.push(symbol);
816
- }
817
- }
818
- }
819
- else {
820
- return;
821
- }
822
- const name = (0, reflection_1.isFieldStatement)(statement) ? statement.name.text : statement.getName(Parser_1.ParseMode.BrighterScript);
823
- return vscode_languageserver_2.DocumentSymbol.create(name, '', symbolKind, statement.range, statement.range, children);
824
- }
825
- /**
826
- * Builds a single SymbolInformation object for use by LanguageServer's onWorkspaceSymbol functionality
827
- */
828
- generateWorkspaceSymbols(statement, containerStatement) {
829
- let symbolKind;
830
- const symbols = [];
831
- if ((0, reflection_1.isFunctionStatement)(statement)) {
832
- symbolKind = vscode_languageserver_2.SymbolKind.Function;
833
- }
834
- else if ((0, reflection_1.isMethodStatement)(statement)) {
835
- symbolKind = vscode_languageserver_2.SymbolKind.Method;
836
- }
837
- else if ((0, reflection_1.isNamespaceStatement)(statement)) {
838
- symbolKind = vscode_languageserver_2.SymbolKind.Namespace;
839
- for (const childStatement of statement.body.statements) {
840
- for (const symbol of this.generateWorkspaceSymbols(childStatement, statement)) {
841
- symbols.push(symbol);
842
- }
843
- }
844
- }
845
- else if ((0, reflection_1.isClassStatement)(statement)) {
846
- symbolKind = vscode_languageserver_2.SymbolKind.Class;
847
- for (const childStatement of statement.body) {
848
- for (const symbol of this.generateWorkspaceSymbols(childStatement, statement)) {
849
- symbols.push(symbol);
850
- }
851
- }
852
- }
853
- else {
854
- return symbols;
855
- }
856
- const name = statement.getName(Parser_1.ParseMode.BrighterScript);
857
- const uri = util_1.util.pathToUri(this.srcPath);
858
- const symbol = vscode_languageserver_2.SymbolInformation.create(name, symbolKind, statement.range, uri, containerStatement === null || containerStatement === void 0 ? void 0 : containerStatement.getName(Parser_1.ParseMode.BrighterScript));
859
- symbols.push(symbol);
860
- return symbols;
1139
+ return new WorkspaceSymbolProcessor_1.WorkspaceSymbolProcessor({
1140
+ program: this.program,
1141
+ workspaceSymbols: []
1142
+ }).process();
861
1143
  }
862
1144
  /**
863
1145
  * Given a position in a file, if the position is sitting on some type of identifier,
864
1146
  * go to the definition of that identifier (where this thing was first defined)
1147
+ * @deprecated use `DefinitionProvider.process()` instead
865
1148
  */
866
1149
  getDefinition(position) {
867
- var _a, _b;
868
- let results = [];
869
- //get the token at the position
870
- const token = this.getTokenAt(position);
871
- // 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
872
- let definitionTokenTypes = [
873
- TokenKind_1.TokenKind.Identifier,
874
- TokenKind_1.TokenKind.StringLiteral
875
- ];
876
- //throw out invalid tokens and the wrong kind of tokens
877
- if (!token || !definitionTokenTypes.includes(token.kind)) {
878
- return results;
879
- }
880
- const scopesForFile = this.program.getScopesForFile(this);
881
- const [scope] = scopesForFile;
882
- const expression = this.getClosestExpression(position);
883
- if (scope && expression) {
884
- scope.linkSymbolTable();
885
- let containingNamespace = (_a = expression.findAncestor(reflection_1.isNamespaceStatement)) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript);
886
- const fullName = (_b = util_1.util.getAllDottedGetParts(expression)) === null || _b === void 0 ? void 0 : _b.map(x => x.text).join('.');
887
- //find a constant with this name
888
- const constant = scope === null || scope === void 0 ? void 0 : scope.getConstFileLink(fullName, containingNamespace);
889
- if (constant) {
890
- results.push(util_1.util.createLocation(vscode_uri_1.URI.file(constant.file.srcPath).toString(), constant.item.tokens.name.range));
891
- return results;
892
- }
893
- if ((0, reflection_1.isDottedGetExpression)(expression) || (0, reflection_1.isVariableExpression)(expression)) {
894
- const enumLink = scope.getEnumFileLink(fullName, containingNamespace);
895
- if (enumLink) {
896
- results.push(util_1.util.createLocation(vscode_uri_1.URI.file(enumLink.file.srcPath).toString(), enumLink.item.tokens.name.range));
897
- return results;
898
- }
899
- const enumMemberLink = scope.getEnumMemberFileLink(fullName, containingNamespace);
900
- if (enumMemberLink) {
901
- results.push(util_1.util.createLocation(vscode_uri_1.URI.file(enumMemberLink.file.srcPath).toString(), enumMemberLink.item.tokens.name.range));
902
- return results;
903
- }
904
- const interfaceFileLink = scope.getInterfaceFileLink(fullName, containingNamespace);
905
- if (interfaceFileLink) {
906
- results.push(util_1.util.createLocation(vscode_uri_1.URI.file(interfaceFileLink.file.srcPath).toString(), interfaceFileLink.item.tokens.name.range));
907
- return results;
908
- }
909
- const classFileLink = scope.getClassFileLink(fullName, containingNamespace);
910
- if (classFileLink) {
911
- results.push(util_1.util.createLocation(vscode_uri_1.URI.file(classFileLink.file.srcPath).toString(), classFileLink.item.name.range));
912
- return results;
913
- }
914
- }
915
- }
916
- let textToSearchFor = token.text.toLowerCase();
917
- const previousToken = this.getTokenAt({ line: token.range.start.line, character: token.range.start.character });
918
- if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === TokenKind_1.TokenKind.Callfunc) {
919
- for (const scope of scopesForFile) {
920
- //to only get functions defined in interface methods
921
- const callable = scope.getAllCallables().find((c) => c.callable.name.toLowerCase() === textToSearchFor); // eslint-disable-line @typescript-eslint/no-loop-func
922
- if (callable) {
923
- results.push(util_1.util.createLocation(util_1.util.pathToUri(callable.callable.file.srcPath), callable.callable.functionStatement.range));
924
- }
925
- }
926
- return results;
927
- }
928
- let classToken = this.getTokenBefore(token, TokenKind_1.TokenKind.Class);
929
- if (classToken) {
930
- let cs = this.parser.references.classStatements.find((cs) => cs.classKeyword.range === classToken.range);
931
- if (cs === null || cs === void 0 ? void 0 : cs.parentClassName) {
932
- const nameParts = cs.parentClassName.getNameParts();
933
- let extendedClass = this.getClassFileLink(nameParts[nameParts.length - 1], nameParts.slice(0, -1).join('.'));
934
- if (extendedClass) {
935
- results.push(util_1.util.createLocation(util_1.util.pathToUri(extendedClass.file.srcPath), extendedClass.item.range));
936
- }
937
- }
938
- return results;
939
- }
940
- if (token.kind === TokenKind_1.TokenKind.StringLiteral) {
941
- // We need to strip off the quotes but only if present
942
- const startIndex = textToSearchFor.startsWith('"') ? 1 : 0;
943
- let endIndex = textToSearchFor.length;
944
- if (textToSearchFor.endsWith('"')) {
945
- endIndex--;
946
- }
947
- textToSearchFor = textToSearchFor.substring(startIndex, endIndex);
948
- }
949
- //look through local variables first, get the function scope for this position (if it exists)
950
- const functionScope = this.getFunctionScopeAtPosition(position);
951
- if (functionScope) {
952
- //find any variable or label with this name
953
- for (const varDeclaration of functionScope.variableDeclarations) {
954
- //we found a variable declaration with this token text!
955
- if (varDeclaration.name.toLowerCase() === textToSearchFor) {
956
- const uri = util_1.util.pathToUri(this.srcPath);
957
- results.push(util_1.util.createLocation(uri, varDeclaration.nameRange));
958
- }
959
- }
960
- if (this.tokenFollows(token, TokenKind_1.TokenKind.Goto)) {
961
- for (const label of functionScope.labelStatements) {
962
- if (label.name.toLocaleLowerCase() === textToSearchFor) {
963
- const uri = util_1.util.pathToUri(this.srcPath);
964
- results.push(util_1.util.createLocation(uri, label.nameRange));
965
- }
966
- }
967
- }
968
- }
969
- const filesSearched = new Set();
970
- //look through all files in scope for matches
971
- for (const scope of scopesForFile) {
972
- for (const file of scope.getAllFiles()) {
973
- if ((0, reflection_1.isBrsFile)(file) && !filesSearched.has(file)) {
974
- filesSearched.add(file);
975
- if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === TokenKind_1.TokenKind.Dot && file.parseMode === Parser_1.ParseMode.BrighterScript) {
976
- results.push(...this.getClassMemberDefinitions(textToSearchFor, file));
977
- const namespaceDefinition = this.getNamespaceDefinitions(token, file);
978
- if (namespaceDefinition) {
979
- results.push(namespaceDefinition);
980
- }
981
- }
982
- const statementHandler = (statement) => {
983
- if (statement.getName(this.parseMode).toLowerCase() === textToSearchFor) {
984
- const uri = util_1.util.pathToUri(file.srcPath);
985
- results.push(util_1.util.createLocation(uri, statement.range));
986
- }
987
- };
988
- file.parser.ast.walk((0, visitors_1.createVisitor)({
989
- FunctionStatement: statementHandler
990
- }), {
991
- walkMode: visitors_1.WalkMode.visitStatements
992
- });
993
- }
994
- }
995
- }
996
- return results;
1150
+ return new DefinitionProvider_1.DefinitionProvider({
1151
+ program: this.program,
1152
+ file: this,
1153
+ position: position,
1154
+ definitions: []
1155
+ }).process();
997
1156
  }
998
1157
  getClassMemberDefinitions(textToSearchFor, file) {
999
1158
  let results = [];
@@ -1009,8 +1168,8 @@ class BrsFile {
1009
1168
  }
1010
1169
  };
1011
1170
  file.parser.ast.walk((0, visitors_1.createVisitor)({
1012
- MethodStatement: statementHandler,
1013
- FieldStatement: fieldStatementHandler
1171
+ ClassMethodStatement: statementHandler,
1172
+ ClassFieldStatement: fieldStatementHandler
1014
1173
  }), {
1015
1174
  walkMode: visitors_1.WalkMode.visitStatements
1016
1175
  });
@@ -1044,58 +1203,27 @@ class BrsFile {
1044
1203
  }
1045
1204
  return statement;
1046
1205
  }
1047
- getReferences(position) {
1048
- const callSiteToken = this.getTokenAt(position);
1049
- let locations = [];
1050
- const searchFor = callSiteToken.text.toLowerCase();
1051
- const scopes = this.program.getScopesForFile(this);
1052
- for (const scope of scopes) {
1053
- const processedFiles = new Set();
1054
- for (const file of scope.getAllFiles()) {
1055
- if ((0, reflection_1.isBrsFile)(file) && !processedFiles.has(file)) {
1056
- processedFiles.add(file);
1057
- file.ast.walk((0, visitors_1.createVisitor)({
1058
- VariableExpression: (e) => {
1059
- if (e.name.text.toLowerCase() === searchFor) {
1060
- locations.push(util_1.util.createLocation(util_1.util.pathToUri(file.srcPath), e.range));
1061
- }
1062
- }
1063
- }), {
1064
- walkMode: visitors_1.WalkMode.visitExpressionsRecursive
1065
- });
1066
- }
1067
- }
1068
- }
1069
- return locations;
1070
- }
1071
1206
  /**
1072
- * Generate the code, map, and typedef for this file
1207
+ * Given a position in a file, if the position is sitting on some type of identifier,
1208
+ * look up all references of that identifier (every place that identifier is used across the whole app)
1209
+ * @deprecated use `ReferencesProvider.process()` instead
1073
1210
  */
1074
- serialize() {
1075
- const result = {};
1076
- const transpiled = this.transpile();
1077
- if (typeof transpiled.code === 'string') {
1078
- result.code = transpiled.code;
1079
- }
1080
- if (transpiled.map) {
1081
- result.map = transpiled.map.toString();
1082
- }
1083
- //generate the typedef (if this is not a typedef itself, and if enabled)
1084
- if (!this.isTypedef && this.program.options.emitDefinitions) {
1085
- result.typedef = this.getTypedef();
1086
- }
1087
- return result;
1211
+ getReferences(position) {
1212
+ return new ReferencesProvider_1.ReferencesProvider({
1213
+ program: this.program,
1214
+ file: this,
1215
+ position: position,
1216
+ references: []
1217
+ }).process();
1088
1218
  }
1089
1219
  /**
1090
1220
  * Convert the brightscript/brighterscript source code into valid brightscript
1091
1221
  */
1092
1222
  transpile() {
1093
- var _a;
1094
1223
  const state = new BrsTranspileState_1.BrsTranspileState(this);
1095
- state.editor = (_a = this.editor) !== null && _a !== void 0 ? _a : new Editor_1.Editor();
1096
1224
  let transpileResult;
1097
1225
  if (this.needsTranspiled) {
1098
- transpileResult = new source_map_1.SourceNode(null, null, state.srcPath, this.ast.transpile(state));
1226
+ transpileResult = util_1.util.sourceNodeFromTranspileResult(null, null, state.srcPath, this.ast.transpile(state));
1099
1227
  }
1100
1228
  else if (this.program.options.sourceMap) {
1101
1229
  //emit code as-is with a simple map to the original file location
@@ -1105,17 +1233,15 @@ class BrsFile {
1105
1233
  //simple SourceNode wrapping the entire file to simplify the logic below
1106
1234
  transpileResult = new source_map_1.SourceNode(null, null, state.srcPath, this.fileContents);
1107
1235
  }
1108
- //if we created an editor for this flow, undo the edits now
1109
- if (!this.editor) {
1110
- //undo any AST edits that the transpile cycle has made
1111
- state.editor.undoAll();
1112
- }
1236
+ //undo any AST edits that the transpile cycle has made
1237
+ state.editor.undoAll();
1113
1238
  if (this.program.options.sourceMap) {
1114
- return new source_map_1.SourceNode(null, null, null, [
1239
+ const stagingFileName = path.basename(state.srcPath).replace(/\.bs$/, '.brs');
1240
+ return new source_map_1.SourceNode(null, null, stagingFileName, [
1115
1241
  transpileResult,
1116
1242
  //add the sourcemap reference comment
1117
- `'//# sourceMappingURL=./${path.basename(state.srcPath)}.map`
1118
- ]).toStringWithSourceMap();
1243
+ state.newline + `'//# sourceMappingURL=./${stagingFileName}.map`
1244
+ ]).toStringWithSourceMap({ file: stagingFileName });
1119
1245
  }
1120
1246
  else {
1121
1247
  return {
@@ -1124,210 +1250,17 @@ class BrsFile {
1124
1250
  };
1125
1251
  }
1126
1252
  }
1127
- processSymbolInformation() {
1128
- this.validationSegmenter.processTree(this.ast);
1129
- this.program.addFileSymbolInfo(this);
1130
- }
1131
- getValidationSegments(changedSymbols) {
1132
- const segments = this.validationSegmenter.getSegments(changedSymbols);
1133
- return segments;
1134
- }
1135
- get requiredSymbols() {
1136
- return this.cache.getOrAdd(`requiredSymbols`, () => {
1137
- var _a;
1138
- const allNeededSymbolSets = this.validationSegmenter.unresolvedSegmentsSymbols.values();
1139
- const requiredSymbols = [];
1140
- const addedSymbols = new Map();
1141
- addedSymbols.set(SymbolTable_1.SymbolTypeFlag.runtime, new Set());
1142
- addedSymbols.set(SymbolTable_1.SymbolTypeFlag.typetime, new Set());
1143
- for (const setOfSymbols of allNeededSymbolSets) {
1144
- for (const symbol of setOfSymbols) {
1145
- const fullSymbolKey = symbol.typeChain.map(tce => tce.name).join('.').toLowerCase();
1146
- if ((_a = this.providedSymbols.symbolMap.get(symbol.flags)) === null || _a === void 0 ? void 0 : _a.has(fullSymbolKey)) {
1147
- // this catches namespaced things
1148
- continue;
1149
- }
1150
- if (!addedSymbols.get(symbol.flags).has(fullSymbolKey)) {
1151
- requiredSymbols.push(symbol);
1152
- addedSymbols.get(symbol.flags).add(fullSymbolKey);
1153
- }
1154
- }
1155
- }
1156
- return requiredSymbols;
1157
- });
1158
- }
1159
- get providedSymbols() {
1160
- var _a;
1161
- return (_a = this.cache) === null || _a === void 0 ? void 0 : _a.getOrAdd(`providedSymbols`, () => {
1162
- return this.getProvidedSymbols();
1163
- });
1164
- }
1165
- getProvidedSymbols() {
1166
- var _a, _b;
1167
- const symbolMap = new Map();
1168
- const runTimeSymbolMap = new Map();
1169
- const typeTimeSymbolMap = new Map();
1170
- const tablesToGetSymbolsFrom = [{
1171
- table: this.parser.symbolTable
1172
- }];
1173
- for (const namespaceStatement of this.parser.references.namespaceStatements) {
1174
- tablesToGetSymbolsFrom.push({
1175
- table: namespaceStatement.body.getSymbolTable(),
1176
- namePrefixLower: namespaceStatement.getName(Parser_1.ParseMode.BrighterScript).toLowerCase()
1177
- });
1178
- }
1179
- for (const symbolTable of tablesToGetSymbolsFrom) {
1180
- const runTimeSymbols = symbolTable.table.getOwnSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
1181
- const typeTimeSymbols = symbolTable.table.getOwnSymbols(SymbolTable_1.SymbolTypeFlag.typetime);
1182
- for (const symbol of runTimeSymbols) {
1183
- if (!(0, reflection_1.isAnyReferenceType)(symbol.type)) {
1184
- const symbolNameLower = symbolTable.namePrefixLower
1185
- ? `${symbolTable.namePrefixLower}.${symbol.name.toLowerCase()}`
1186
- : symbol.name.toLowerCase();
1187
- runTimeSymbolMap.set(symbolNameLower, symbol);
1188
- }
1189
- }
1190
- for (const symbol of typeTimeSymbols) {
1191
- if (!(0, reflection_1.isAnyReferenceType)(symbol.type)) {
1192
- const symbolNameLower = symbolTable.namePrefixLower
1193
- ? `${symbolTable.namePrefixLower}.${symbol.name.toLowerCase()}`
1194
- : symbol.name.toLowerCase();
1195
- typeTimeSymbolMap.set(symbolNameLower, symbol);
1196
- }
1197
- }
1198
- }
1199
- symbolMap.set(SymbolTable_1.SymbolTypeFlag.runtime, runTimeSymbolMap);
1200
- symbolMap.set(SymbolTable_1.SymbolTypeFlag.typetime, typeTimeSymbolMap);
1201
- const changes = new Map();
1202
- changes.set(SymbolTable_1.SymbolTypeFlag.runtime, new Set());
1203
- changes.set(SymbolTable_1.SymbolTypeFlag.typetime, new Set());
1204
- const previouslyProvidedSymbols = (_a = this.program.getFileSymbolInfo(this)) === null || _a === void 0 ? void 0 : _a.provides.symbolMap;
1205
- const previousSymbolsChecked = new Map();
1206
- previousSymbolsChecked.set(SymbolTable_1.SymbolTypeFlag.runtime, new Set());
1207
- previousSymbolsChecked.set(SymbolTable_1.SymbolTypeFlag.typetime, new Set());
1208
- for (const flag of [SymbolTable_1.SymbolTypeFlag.runtime, SymbolTable_1.SymbolTypeFlag.typetime]) {
1209
- const newSymbolMapForFlag = symbolMap.get(flag);
1210
- const oldSymbolMapForFlag = previouslyProvidedSymbols === null || previouslyProvidedSymbols === void 0 ? void 0 : previouslyProvidedSymbols.get(flag);
1211
- const previousSymbolsCheckedForFlag = previousSymbolsChecked.get(flag);
1212
- const changesForFlag = changes.get(flag);
1213
- if (!oldSymbolMapForFlag) {
1214
- for (const key of newSymbolMapForFlag.keys()) {
1215
- changesForFlag.add(key);
1216
- }
1217
- continue;
1218
- }
1219
- for (const [symbolKey, symbol] of newSymbolMapForFlag) {
1220
- const symbolType = symbol.type;
1221
- const previousType = (_b = oldSymbolMapForFlag === null || oldSymbolMapForFlag === void 0 ? void 0 : oldSymbolMapForFlag.get(symbolKey)) === null || _b === void 0 ? void 0 : _b.type;
1222
- previousSymbolsCheckedForFlag.add(symbolKey);
1223
- if (!previousType) {
1224
- changesForFlag.add(symbolKey);
1225
- continue;
1226
- }
1227
- const data = {};
1228
- if (!symbolType.isEqual(previousType, data)) {
1229
- changesForFlag.add(symbolKey);
1230
- }
1231
- }
1232
- for (const [symbolKey] of previouslyProvidedSymbols.get(flag)) {
1233
- if (!previousSymbolsCheckedForFlag.has(symbolKey)) {
1234
- changesForFlag.add(symbolKey);
1235
- }
1236
- }
1237
- }
1238
- return {
1239
- symbolMap: symbolMap,
1240
- changes: changes
1241
- };
1242
- }
1243
- markSegmentAsValidated(node) {
1244
- this.validationSegmenter.markSegmentAsValidated(node);
1245
- }
1246
- getNamespaceLookupObject() {
1247
- if (!this.isValidated) {
1248
- return this.buildNamespaceLookup();
1249
- }
1250
- return this.cache.getOrAdd(`namespaceLookup`, () => {
1251
- const nsLookup = this.buildNamespaceLookup();
1252
- return nsLookup;
1253
- });
1254
- }
1255
- buildNamespaceLookup() {
1256
- const namespaceLookup = new Map();
1257
- for (let namespaceStatement of this.parser.references.namespaceStatements) {
1258
- let nameParts = namespaceStatement.getNameParts();
1259
- let loopName = null;
1260
- let lowerLoopName = null;
1261
- let parentNameLower = null;
1262
- //ensure each namespace section is represented in the results
1263
- //(so if the namespace name is A.B.C, this will make an entry for "A", an entry for "A.B", and an entry for "A.B.C"
1264
- for (let i = 0; i < nameParts.length; i++) {
1265
- let part = nameParts[i];
1266
- let lowerPartName = part.text.toLowerCase();
1267
- if (i === 0) {
1268
- loopName = part.text;
1269
- lowerLoopName = lowerPartName;
1270
- }
1271
- else {
1272
- parentNameLower = lowerLoopName;
1273
- loopName += '.' + part.text;
1274
- lowerLoopName += '.' + lowerPartName;
1275
- }
1276
- if (!namespaceLookup.has(lowerLoopName)) {
1277
- namespaceLookup.set(lowerLoopName, {
1278
- isTopLevel: i === 0,
1279
- file: this,
1280
- fullName: loopName,
1281
- fullNameLower: lowerLoopName,
1282
- parentNameLower: parentNameLower,
1283
- nameParts: nameParts.slice(0, i),
1284
- nameRange: namespaceStatement.nameExpression.range,
1285
- lastPartName: part.text,
1286
- lastPartNameLower: lowerPartName,
1287
- functionStatements: new Map(),
1288
- namespaceStatements: [],
1289
- namespaces: new Map(),
1290
- classStatements: new Map(),
1291
- enumStatements: new Map(),
1292
- constStatements: new Map(),
1293
- statements: [],
1294
- // the aggregate symbol table should have no parent. It should include just the symbols of the namespace.
1295
- symbolTable: new SymbolTable_1.SymbolTable(`Namespace Aggregate: '${loopName}'`)
1296
- });
1297
- }
1298
- }
1299
- let ns = namespaceLookup.get(lowerLoopName);
1300
- ns.namespaceStatements.push(namespaceStatement);
1301
- ns.statements.push(...namespaceStatement.body.statements);
1302
- for (let statement of namespaceStatement.body.statements) {
1303
- if ((0, reflection_1.isClassStatement)(statement) && statement.name) {
1304
- ns.classStatements.set(statement.name.text.toLowerCase(), statement);
1305
- }
1306
- else if ((0, reflection_1.isFunctionStatement)(statement) && statement.name) {
1307
- ns.functionStatements.set(statement.name.text.toLowerCase(), statement);
1308
- }
1309
- else if ((0, reflection_1.isEnumStatement)(statement) && statement.fullName) {
1310
- ns.enumStatements.set(statement.fullName.toLowerCase(), statement);
1311
- }
1312
- else if ((0, reflection_1.isConstStatement)(statement) && statement.fullName) {
1313
- ns.constStatements.set(statement.fullName.toLowerCase(), statement);
1314
- }
1315
- }
1316
- // Merges all the symbol tables of the namespace statements into the new symbol table created above.
1317
- // Set those symbol tables to have this new merged table as a parent
1318
- ns.symbolTable.mergeSymbolTable(namespaceStatement.body.getSymbolTable());
1319
- }
1320
- return namespaceLookup;
1321
- }
1322
1253
  getTypedef() {
1323
1254
  const state = new BrsTranspileState_1.BrsTranspileState(this);
1324
1255
  const typedef = this.ast.getTypedef(state);
1325
- const programNode = new source_map_1.SourceNode(null, null, this.srcPath, typedef);
1256
+ const programNode = util_1.util.sourceNodeFromTranspileResult(null, null, this.srcPath, typedef);
1326
1257
  return programNode.toString();
1327
1258
  }
1328
1259
  dispose() {
1329
- var _a;
1260
+ var _a, _b;
1330
1261
  (_a = this._parser) === null || _a === void 0 ? void 0 : _a.dispose();
1262
+ //unsubscribe from any DependencyGraph subscriptions
1263
+ (_b = this.unsubscribeFromDependencyGraph) === null || _b === void 0 ? void 0 : _b.call(this);
1331
1264
  //deleting these properties result in lower memory usage (garbage collection is magic!)
1332
1265
  delete this.fileContents;
1333
1266
  delete this._parser;
@@ -1338,4 +1271,18 @@ class BrsFile {
1338
1271
  }
1339
1272
  }
1340
1273
  exports.BrsFile = BrsFile;
1274
+ /**
1275
+ * List of completions for all valid keywords/reserved words.
1276
+ * Build this list once because it won't change for the lifetime of this process
1277
+ */
1278
+ exports.KeywordCompletions = Object.keys(TokenKind_1.Keywords)
1279
+ //remove any keywords with whitespace
1280
+ .filter(x => !x.includes(' '))
1281
+ //create completions
1282
+ .map(x => {
1283
+ return {
1284
+ label: x,
1285
+ kind: vscode_languageserver_2.CompletionItemKind.Keyword
1286
+ };
1287
+ });
1341
1288
  //# sourceMappingURL=BrsFile.js.map