brighterscript 0.66.0-alpha.9 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/CHANGELOG.md +116 -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 +29 -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 +82 -87
  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 +552 -607
  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,44 +54,58 @@ 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
111
  if (!diagnostic.file) {
@@ -119,7 +140,7 @@ class BrsFile {
119
140
  if ((0, reflection_1.isImportStatement)(statement) && statement.filePathToken) {
120
141
  result.push({
121
142
  filePathRange: statement.filePathToken.range,
122
- destPath: util_1.util.getPkgPathFromTarget(this.destPath, statement.filePath),
143
+ pkgPath: util_1.util.getPkgPathFromTarget(this.pkgPath, statement.filePath),
123
144
  sourceFile: this,
124
145
  text: (_d = statement.filePathToken) === null || _d === void 0 ? void 0 : _d.text
125
146
  });
@@ -129,26 +150,11 @@ class BrsFile {
129
150
  })) !== null && _b !== void 0 ? _b : [];
130
151
  return result;
131
152
  }
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
153
  /**
147
154
  * The AST for this file
148
155
  */
149
156
  get ast() {
150
- var _a;
151
- return (_a = this.parser) === null || _a === void 0 ? void 0 : _a.ast;
157
+ return this.parser.ast;
152
158
  }
153
159
  /**
154
160
  * Get the token at the specified position
@@ -202,25 +208,23 @@ class BrsFile {
202
208
  this.typedefFile = this.program.getFile(this.typedefKey);
203
209
  this.hasTypedef = !!this.typedefFile;
204
210
  }
205
- onDependenciesChanged() {
206
- this.resolveTypedef();
207
- }
208
211
  /**
209
212
  * Attach the file to the dependency graph so it can monitor changes.
210
213
  * 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
214
  */
217
- get dependencies() {
218
- const result = this.ownScriptImports.filter(x => !!x.destPath).map(x => x.destPath.toLowerCase());
215
+ attachDependencyGraph(dependencyGraph) {
216
+ var _a;
217
+ (_a = this.unsubscribeFromDependencyGraph) === null || _a === void 0 ? void 0 : _a.call(this);
218
+ //event that fires anytime a dependency changes
219
+ this.unsubscribeFromDependencyGraph = dependencyGraph.onchange(this.dependencyGraphKey, () => {
220
+ this.resolveTypedef();
221
+ });
222
+ const dependencies = this.ownScriptImports.filter(x => !!x.pkgPath).map(x => x.pkgPath.toLowerCase());
219
223
  //if this is a .brs file, watch for typedef changes
220
224
  if (this.extension === '.brs') {
221
- result.push(util_1.util.getTypedefPath(this.destPath));
225
+ dependencies.push(util_1.util.getTypedefPath(this.pkgPath));
222
226
  }
223
- return result;
227
+ dependencyGraph.addOrReplace(this.dependencyGraphKey, dependencies);
224
228
  }
225
229
  /**
226
230
  * Calculate the AST for this file
@@ -237,7 +241,7 @@ class BrsFile {
237
241
  return;
238
242
  }
239
243
  //tokenize the input file
240
- let lexer = this.program.logger.time(Logger_1.LogLevel.debug, ['lexer.lex', chalk_1.default.green(this.srcPath)], () => {
244
+ let lexer = this.program.logger.time('debug', ['lexer.lex', chalk_1.default.green(this.srcPath)], () => {
241
245
  return Lexer_1.Lexer.scan(fileContents, {
242
246
  includeWhitespace: false
243
247
  });
@@ -248,7 +252,7 @@ class BrsFile {
248
252
  //TODO preprocessor should go away in favor of the AST handling this internally (because it affects transpile)
249
253
  //currently the preprocessor throws exceptions on syntax errors...so we need to catch it
250
254
  try {
251
- this.program.logger.time(Logger_1.LogLevel.debug, ['preprocessor.process', chalk_1.default.green(this.srcPath)], () => {
255
+ this.program.logger.time('debug', ['preprocessor.process', chalk_1.default.green(this.srcPath)], () => {
252
256
  preprocessor.process(lexer.tokens, this.program.getManifest());
253
257
  });
254
258
  }
@@ -260,7 +264,7 @@ class BrsFile {
260
264
  }
261
265
  //if the preprocessor generated tokens, use them.
262
266
  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)], () => {
267
+ this.program.logger.time('debug', ['parser.parse', chalk_1.default.green(this.srcPath)], () => {
264
268
  this._parser = Parser_1.Parser.parse(tokens, {
265
269
  mode: this.parseMode,
266
270
  logger: this.program.logger
@@ -282,6 +286,11 @@ class BrsFile {
282
286
  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
287
  }
284
288
  }
289
+ /**
290
+ * @deprecated logic has moved into BrsFileValidator, this is now an empty function
291
+ */
292
+ validate() {
293
+ }
285
294
  /**
286
295
  * Find a class. This scans all scopes for this file, and returns the first matching class that is found.
287
296
  * Returns undefined if not found.
@@ -338,7 +347,7 @@ class BrsFile {
338
347
  * Create a scope for every function in this file
339
348
  */
340
349
  createFunctionScopes() {
341
- var _a;
350
+ var _a, _b, _c;
342
351
  //find every function
343
352
  let functions = this.parser.references.functionExpressions;
344
353
  //create a functionScope for every function
@@ -347,7 +356,7 @@ class BrsFile {
347
356
  let scope = new FunctionScope_1.FunctionScope(func);
348
357
  //find parent function, and add this scope to it if found
349
358
  {
350
- let parentScope = this.scopesByFunc.get(func.findAncestor(reflection_1.isFunctionExpression));
359
+ let parentScope = this.scopesByFunc.get(func.parentFunction);
351
360
  //add this child scope to its parent
352
361
  if (parentScope) {
353
362
  parentScope.childrenScopes.push(scope);
@@ -359,28 +368,28 @@ class BrsFile {
359
368
  for (let param of func.parameters) {
360
369
  scope.variableDeclarations.push({
361
370
  nameRange: param.name.range,
362
- lineIndex: param.name.range.start.line,
371
+ lineIndex: (_a = param.name.range) === null || _a === void 0 ? void 0 : _a.start.line,
363
372
  name: param.name.text,
364
- getType: () => {
365
- return param.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
366
- }
373
+ type: param.type
367
374
  });
368
375
  }
369
376
  //add all of ForEachStatement loop varibales
370
- (_a = func.body) === null || _a === void 0 ? void 0 : _a.walk((0, visitors_1.createVisitor)({
377
+ (_b = func.body) === null || _b === void 0 ? void 0 : _b.walk((0, visitors_1.createVisitor)({
371
378
  ForEachStatement: (stmt) => {
379
+ var _a;
372
380
  scope.variableDeclarations.push({
373
381
  nameRange: stmt.item.range,
374
- lineIndex: stmt.item.range.start.line,
382
+ lineIndex: (_a = stmt.item.range) === null || _a === void 0 ? void 0 : _a.start.line,
375
383
  name: stmt.item.text,
376
- getType: () => DynamicType_1.DynamicType.instance //TODO: Infer types from array
384
+ type: new DynamicType_1.DynamicType()
377
385
  });
378
386
  },
379
387
  LabelStatement: (stmt) => {
388
+ var _a;
380
389
  const { identifier } = stmt.tokens;
381
390
  scope.labelStatements.push({
382
391
  nameRange: identifier.range,
383
- lineIndex: identifier.range.start.line,
392
+ lineIndex: (_a = identifier.range) === null || _a === void 0 ? void 0 : _a.start.line,
384
393
  name: identifier.text
385
394
  });
386
395
  }
@@ -395,36 +404,95 @@ class BrsFile {
395
404
  let assignmentStatements = this.parser.references.assignmentStatements;
396
405
  for (let statement of assignmentStatements) {
397
406
  //find this statement's function scope
398
- let scope = this.scopesByFunc.get(statement.findAncestor(reflection_1.isFunctionExpression));
407
+ let scope = this.scopesByFunc.get(statement.containingFunction);
399
408
  //skip variable declarations that are outside of any scope
400
409
  if (scope) {
401
410
  scope.variableDeclarations.push({
402
411
  nameRange: statement.name.range,
403
- lineIndex: statement.name.range.start.line,
412
+ lineIndex: (_c = statement.name.range) === null || _c === void 0 ? void 0 : _c.start.line,
404
413
  name: statement.name.text,
405
- getType: () => {
406
- return statement.getType({ flags: SymbolTable_1.SymbolTypeFlag.runtime });
407
- }
414
+ type: this.getBscTypeFromAssignment(statement, scope)
408
415
  });
409
416
  }
410
417
  }
411
418
  }
419
+ getBscTypeFromAssignment(assignment, scope) {
420
+ var _a, _b, _c, _d;
421
+ try {
422
+ //function
423
+ if ((0, reflection_1.isFunctionExpression)(assignment.value)) {
424
+ let functionType = new FunctionType_1.FunctionType(assignment.value.returnType);
425
+ functionType.isSub = assignment.value.functionType.text === 'sub';
426
+ if (functionType.isSub) {
427
+ functionType.returnType = new VoidType_1.VoidType();
428
+ }
429
+ functionType.setName(assignment.name.text);
430
+ for (let param of assignment.value.parameters) {
431
+ let isOptional = !!param.defaultValue;
432
+ //TODO compute optional parameters
433
+ functionType.addParameter(param.name.text, param.type, isOptional);
434
+ }
435
+ return functionType;
436
+ //literal
437
+ }
438
+ else if ((0, reflection_1.isLiteralExpression)(assignment.value)) {
439
+ return assignment.value.type;
440
+ //function call
441
+ }
442
+ else if ((0, reflection_1.isCallExpression)(assignment.value)) {
443
+ let calleeName = (_b = (_a = assignment.value.callee) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.text;
444
+ if (calleeName) {
445
+ let func = this.getCallableByName(calleeName);
446
+ if (func) {
447
+ return func.type.returnType;
448
+ }
449
+ }
450
+ }
451
+ else if ((0, reflection_1.isVariableExpression)(assignment.value)) {
452
+ let variableName = (_d = (_c = assignment.value) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.text;
453
+ let variable = scope.getVariableByName(variableName);
454
+ return variable.type;
455
+ }
456
+ }
457
+ catch (e) {
458
+ //do nothing. Just return dynamic
459
+ }
460
+ //fallback to dynamic
461
+ return new DynamicType_1.DynamicType();
462
+ }
463
+ getCallableByName(name) {
464
+ name = name ? name.toLowerCase() : undefined;
465
+ if (!name) {
466
+ return;
467
+ }
468
+ for (let func of this.callables) {
469
+ if (func.name.toLowerCase() === name) {
470
+ return func;
471
+ }
472
+ }
473
+ }
412
474
  findCallables() {
413
475
  var _a;
414
476
  for (let statement of (_a = this.parser.references.functionStatements) !== null && _a !== void 0 ? _a : []) {
477
+ let functionType = new FunctionType_1.FunctionType(statement.func.returnType);
478
+ functionType.setName(statement.name.text);
479
+ functionType.isSub = statement.func.functionType.text.toLowerCase() === 'sub';
480
+ if (functionType.isSub) {
481
+ functionType.returnType = new VoidType_1.VoidType();
482
+ }
415
483
  //extract the parameters
416
484
  let params = [];
417
485
  for (let param of statement.func.parameters) {
418
- const paramType = param.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
419
486
  let callableParam = {
420
487
  name: param.name.text,
421
- type: paramType,
488
+ type: param.type,
422
489
  isOptional: !!param.defaultValue,
423
490
  isRestArgument: false
424
491
  };
425
492
  params.push(callableParam);
493
+ let isOptional = !!param.defaultValue;
494
+ functionType.addParameter(callableParam.name, callableParam.type, isOptional);
426
495
  }
427
- const funcType = statement.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
428
496
  this.callables.push({
429
497
  isSub: statement.func.functionType.text.toLowerCase() === 'sub',
430
498
  name: statement.name.text,
@@ -432,7 +500,7 @@ class BrsFile {
432
500
  file: this,
433
501
  params: params,
434
502
  range: statement.func.range,
435
- type: funcType,
503
+ type: functionType,
436
504
  getName: statement.getName.bind(statement),
437
505
  hasNamespace: !!statement.findAncestor(reflection_1.isNamespaceStatement),
438
506
  functionStatement: statement
@@ -466,7 +534,7 @@ class BrsFile {
466
534
  if ((0, reflection_1.isLiteralExpression)(arg)) {
467
535
  args.push({
468
536
  range: arg.range,
469
- type: arg.getType(),
537
+ type: arg.type,
470
538
  text: arg.token.text,
471
539
  expression: arg,
472
540
  typeToken: undefined
@@ -521,8 +589,7 @@ class BrsFile {
521
589
  name: functionName,
522
590
  nameRange: util_1.util.createRange(callee.range.start.line, columnIndexBegin, callee.range.start.line, columnIndexEnd),
523
591
  //TODO keep track of parameters
524
- args: args,
525
- expression: expression
592
+ args: args
526
593
  };
527
594
  this.functionCalls.push(functionCall);
528
595
  }
@@ -568,37 +635,345 @@ class BrsFile {
568
635
  });
569
636
  }
570
637
  }
571
- getNamespaceDefinitions(token, file) {
572
- //BrightScript does not support namespaces, so return an empty list in that case
573
- if (!token) {
574
- return undefined;
638
+ /**
639
+ * Get completions available at the given cursor. This aggregates all values from this file and the current scope.
640
+ */
641
+ getCompletions(position, scope) {
642
+ let result = [];
643
+ //a map of lower-case names of all added options
644
+ let names = {};
645
+ //handle script import completions
646
+ let scriptImport = util_1.util.getScriptImportAtPosition(this.ownScriptImports, position);
647
+ if (scriptImport) {
648
+ return this.program.getScriptImportCompletions(this.pkgPath, scriptImport);
649
+ }
650
+ //if cursor is within a comment, disable completions
651
+ let currentToken = this.getTokenAt(position);
652
+ const tokenKind = currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind;
653
+ if (tokenKind === TokenKind_1.TokenKind.Comment) {
654
+ return [];
655
+ }
656
+ else if (tokenKind === TokenKind_1.TokenKind.StringLiteral || tokenKind === TokenKind_1.TokenKind.TemplateStringQuasi) {
657
+ const match = /^("?)(pkg|libpkg):/.exec(currentToken.text);
658
+ if (match) {
659
+ const [, openingQuote, fileProtocol] = match;
660
+ //include every absolute file path from this scope
661
+ for (const file of scope.getAllFiles()) {
662
+ const pkgPath = `${fileProtocol}:/${file.pkgPath.replace(/\\/g, '/')}`;
663
+ result.push({
664
+ label: pkgPath,
665
+ textEdit: vscode_languageserver_2.TextEdit.replace(util_1.util.createRange(currentToken.range.start.line,
666
+ //+1 to step past the opening quote
667
+ currentToken.range.start.character + (openingQuote ? 1 : 0), currentToken.range.end.line,
668
+ //-1 to exclude the closing quotemark (or the end character if there is no closing quotemark)
669
+ currentToken.range.end.character + (currentToken.text.endsWith('"') ? -1 : 0)), pkgPath),
670
+ kind: vscode_languageserver_2.CompletionItemKind.File
671
+ });
672
+ }
673
+ return result;
674
+ }
675
+ else {
676
+ //do nothing. we don't want to show completions inside of strings...
677
+ return [];
678
+ }
575
679
  }
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);
680
+ const namespaceCompletions = this.getNamespaceCompletions(currentToken, this.parseMode, scope);
681
+ if (namespaceCompletions.length > 0) {
682
+ return [...namespaceCompletions];
683
+ }
684
+ const enumMemberCompletions = this.getEnumMemberStatementCompletions(currentToken, this.parseMode, scope);
685
+ if (enumMemberCompletions.length > 0) {
686
+ // no other completion is valid in this case
687
+ return enumMemberCompletions;
688
+ }
689
+ //determine if cursor is inside a function
690
+ let functionScope = this.getFunctionScopeAtPosition(position);
691
+ if (!functionScope) {
692
+ //we aren't in any function scope, so return the keyword completions and namespaces
693
+ if (this.getTokenBefore(currentToken, TokenKind_1.TokenKind.New)) {
694
+ // there's a new keyword, so only class types are viable here
695
+ return [...this.getGlobalClassStatementCompletions(currentToken, this.parseMode)];
696
+ }
697
+ else {
698
+ return [
699
+ ...exports.KeywordCompletions,
700
+ ...this.getGlobalClassStatementCompletions(currentToken, this.parseMode),
701
+ ...namespaceCompletions,
702
+ ...this.getNonNamespacedEnumStatementCompletions(currentToken, this.parseMode, scope)
703
+ ];
704
+ }
705
+ }
706
+ const classNameCompletions = this.getGlobalClassStatementCompletions(currentToken, this.parseMode);
707
+ const newToken = this.getTokenBefore(currentToken, TokenKind_1.TokenKind.New);
708
+ if (newToken) {
709
+ //we are after a new keyword; so we can only be top-level namespaces or classes at this point
710
+ result.push(...classNameCompletions);
711
+ result.push(...namespaceCompletions);
712
+ return result;
713
+ }
714
+ if (this.tokenFollows(currentToken, TokenKind_1.TokenKind.Goto)) {
715
+ return this.getLabelCompletion(functionScope);
716
+ }
717
+ if (this.isPositionNextToTokenKind(position, TokenKind_1.TokenKind.Dot)) {
718
+ const selfClassMemberCompletions = this.getClassMemberCompletions(position, currentToken, functionScope, scope);
719
+ if (selfClassMemberCompletions.size > 0) {
720
+ return [...selfClassMemberCompletions.values()].filter((i) => i.label !== 'new');
721
+ }
722
+ if (!this.getClassFromMReference(position, currentToken, functionScope)) {
723
+ //and anything from any class in scope to a non m class
724
+ let classMemberCompletions = scope.getAllClassMemberCompletions();
725
+ result.push(...classMemberCompletions.values());
726
+ result.push(...scope.getPropertyNameCompletions().filter((i) => !classMemberCompletions.has(i.label)));
727
+ }
728
+ else {
729
+ result.push(...scope.getPropertyNameCompletions());
730
+ }
731
+ }
732
+ else {
733
+ result.push(
734
+ //include namespaces
735
+ ...namespaceCompletions,
736
+ //include class names
737
+ ...classNameCompletions,
738
+ //include enums
739
+ ...this.getNonNamespacedEnumStatementCompletions(currentToken, this.parseMode, scope),
740
+ //include constants
741
+ ...this.getNonNamespacedConstStatementCompletions(currentToken, this.parseMode, scope),
742
+ //include the global callables
743
+ ...scope.getCallablesAsCompletions(this.parseMode));
744
+ //add `m` because that's always valid within a function
745
+ result.push({
746
+ label: 'm',
747
+ kind: vscode_languageserver_2.CompletionItemKind.Variable
748
+ });
749
+ names.m = true;
750
+ result.push(...exports.KeywordCompletions);
751
+ //include local variables
752
+ let variables = functionScope.variableDeclarations;
753
+ for (let variable of variables) {
754
+ //skip duplicate variable names
755
+ if (names[variable.name.toLowerCase()]) {
756
+ continue;
757
+ }
758
+ names[variable.name.toLowerCase()] = true;
759
+ result.push({
760
+ label: variable.name,
761
+ kind: (0, reflection_1.isFunctionType)(variable.type) ? vscode_languageserver_2.CompletionItemKind.Function : vscode_languageserver_2.CompletionItemKind.Variable
762
+ });
763
+ }
764
+ if (this.parseMode === Parser_1.ParseMode.BrighterScript) {
765
+ //include the first part of namespaces
766
+ let namespaces = scope.getAllNamespaceStatements();
767
+ for (let stmt of namespaces) {
768
+ let firstPart = stmt.nameExpression.getNameParts().shift();
769
+ //skip duplicate namespace names
770
+ if (names[firstPart.toLowerCase()]) {
771
+ continue;
586
772
  }
587
- };
588
- file.parser.ast.walk((0, visitors_1.createVisitor)({
589
- ClassStatement: namespaceItemStatementHandler,
590
- FunctionStatement: namespaceItemStatementHandler
591
- }), {
592
- walkMode: visitors_1.WalkMode.visitStatements
773
+ names[firstPart.toLowerCase()] = true;
774
+ result.push({
775
+ label: firstPart,
776
+ kind: vscode_languageserver_2.CompletionItemKind.Module
777
+ });
778
+ }
779
+ }
780
+ }
781
+ return result;
782
+ }
783
+ getLabelCompletion(functionScope) {
784
+ return functionScope.labelStatements.map(label => ({
785
+ label: label.name,
786
+ kind: vscode_languageserver_2.CompletionItemKind.Reference
787
+ }));
788
+ }
789
+ getClassMemberCompletions(position, currentToken, functionScope, scope) {
790
+ var _a, _b, _c, _d;
791
+ let classStatement = this.getClassFromMReference(position, currentToken, functionScope);
792
+ let results = new Map();
793
+ if (classStatement) {
794
+ let classes = scope.getClassHierarchy(classStatement.item.getName(Parser_1.ParseMode.BrighterScript).toLowerCase());
795
+ for (let cs of classes) {
796
+ 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 : []]) {
797
+ if (!results.has(member.name.text.toLowerCase())) {
798
+ results.set(member.name.text.toLowerCase(), {
799
+ label: member.name.text,
800
+ kind: (0, reflection_1.isFieldStatement)(member) ? vscode_languageserver_2.CompletionItemKind.Field : vscode_languageserver_2.CompletionItemKind.Function
801
+ });
802
+ }
803
+ }
804
+ }
805
+ }
806
+ return results;
807
+ }
808
+ getClassFromMReference(position, currentToken, functionScope) {
809
+ let previousToken = this.getPreviousToken(currentToken);
810
+ if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === TokenKind_1.TokenKind.Dot) {
811
+ previousToken = this.getPreviousToken(previousToken);
812
+ }
813
+ 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)) {
814
+ return { item: this.parser.references.classStatements.find((cs) => util_1.util.rangeContains(cs.range, position)), file: this };
815
+ }
816
+ return undefined;
817
+ }
818
+ getGlobalClassStatementCompletions(currentToken, parseMode) {
819
+ var _a;
820
+ if (parseMode === Parser_1.ParseMode.BrightScript) {
821
+ return [];
822
+ }
823
+ let results = new Map();
824
+ let completionName = (_a = this.getPartialVariableName(currentToken, [TokenKind_1.TokenKind.New])) === null || _a === void 0 ? void 0 : _a.toLowerCase();
825
+ if (completionName === null || completionName === void 0 ? void 0 : completionName.includes('.')) {
826
+ return [];
827
+ }
828
+ let scopes = this.program.getScopesForFile(this);
829
+ for (let scope of scopes) {
830
+ let classMap = scope.getClassMap();
831
+ for (const key of [...classMap.keys()]) {
832
+ let cs = classMap.get(key).item;
833
+ if (!results.has(cs.name.text)) {
834
+ results.set(cs.name.text, {
835
+ label: cs.name.text,
836
+ kind: vscode_languageserver_2.CompletionItemKind.Class
837
+ });
838
+ }
839
+ }
840
+ }
841
+ return [...results.values()];
842
+ }
843
+ getNonNamespacedEnumStatementCompletions(currentToken, parseMode, scope) {
844
+ var _a, _b;
845
+ if (parseMode !== Parser_1.ParseMode.BrighterScript) {
846
+ return [];
847
+ }
848
+ 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) + '.';
849
+ const results = new Map();
850
+ const enumMap = scope.getEnumMap();
851
+ for (const key of [...enumMap.keys()]) {
852
+ const enumStatement = enumMap.get(key).item;
853
+ const fullName = enumStatement.fullName;
854
+ //if the enum is contained within our own namespace, or if it's a non-namespaced enum
855
+ if (fullName.startsWith(containingNamespaceName) || !fullName.includes('.')) {
856
+ results.set(fullName, {
857
+ label: enumStatement.name,
858
+ kind: vscode_languageserver_2.CompletionItemKind.Enum
593
859
  });
594
860
  }
595
- };
596
- file.parser.ast.walk((0, visitors_1.createVisitor)({
597
- NamespaceStatement: statementHandler
598
- }), {
599
- walkMode: visitors_1.WalkMode.visitStatements
600
- });
601
- return location;
861
+ }
862
+ return [...results.values()];
863
+ }
864
+ getNonNamespacedConstStatementCompletions(currentToken, parseMode, scope) {
865
+ var _a, _b;
866
+ if (parseMode !== Parser_1.ParseMode.BrighterScript) {
867
+ return [];
868
+ }
869
+ 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) + '.';
870
+ const results = new Map();
871
+ const map = scope.getConstMap();
872
+ for (const key of [...map.keys()]) {
873
+ const statement = map.get(key).item;
874
+ const fullName = statement.fullName;
875
+ //if the item is contained within our own namespace, or if it's non-namespaced
876
+ if (fullName.startsWith(containingNamespaceName) || !fullName.includes('.')) {
877
+ results.set(fullName, {
878
+ label: statement.name,
879
+ kind: vscode_languageserver_2.CompletionItemKind.Constant
880
+ });
881
+ }
882
+ }
883
+ return [...results.values()];
884
+ }
885
+ getEnumMemberStatementCompletions(currentToken, parseMode, scope) {
886
+ var _a, _b, _c, _d, _e;
887
+ if (parseMode === Parser_1.ParseMode.BrightScript || !currentToken) {
888
+ return [];
889
+ }
890
+ const results = new Map();
891
+ const completionName = (_a = this.getPartialVariableName(currentToken)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
892
+ //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
893
+ if (!completionName || !completionName.includes('.')) {
894
+ return [];
895
+ }
896
+ const enumNameLower = (_b = completionName === null || completionName === void 0 ? void 0 : completionName.split(/\.(\w+)?$/)[0]) === null || _b === void 0 ? void 0 : _b.toLowerCase();
897
+ const namespaceNameLower = (_c = this.getNamespaceStatementForPosition(currentToken.range.end)) === null || _c === void 0 ? void 0 : _c.name.toLowerCase();
898
+ const enumMap = scope.getEnumMap();
899
+ //get the enum statement with this name (check without namespace prefix first, then with inferred namespace prefix next)
900
+ const enumStatement = (_e = ((_d = enumMap.get(enumNameLower)) !== null && _d !== void 0 ? _d : enumMap.get(namespaceNameLower + '.' + enumNameLower))) === null || _e === void 0 ? void 0 : _e.item;
901
+ //if we found an enum with this name
902
+ if (enumStatement) {
903
+ for (const member of enumStatement.getMembers()) {
904
+ const name = enumStatement.fullName + '.' + member.name;
905
+ const nameLower = name.toLowerCase();
906
+ results.set(nameLower, {
907
+ label: member.name,
908
+ kind: vscode_languageserver_2.CompletionItemKind.EnumMember
909
+ });
910
+ }
911
+ }
912
+ return [...results.values()];
913
+ }
914
+ getNamespaceCompletions(currentToken, parseMode, scope) {
915
+ //BrightScript does not support namespaces, so return an empty list in that case
916
+ if (parseMode === Parser_1.ParseMode.BrightScript) {
917
+ return [];
918
+ }
919
+ const completionName = this.getPartialVariableName(currentToken, [TokenKind_1.TokenKind.New]);
920
+ //if we don't have a completion name, or if there's no period in the name, then this is not a namespaced variable
921
+ if (!completionName || !completionName.includes('.')) {
922
+ return [];
923
+ }
924
+ //remove any trailing identifer and then any trailing dot, to give us the
925
+ //name of its immediate parent namespace
926
+ let closestParentNamespaceName = completionName.replace(/\.([a-z0-9_]*)?$/gi, '').toLowerCase();
927
+ let newToken = this.getTokenBefore(currentToken, TokenKind_1.TokenKind.New);
928
+ let result = new Map();
929
+ for (let [, namespace] of scope.namespaceLookup) {
930
+ //completionName = "NameA."
931
+ //completionName = "NameA.Na
932
+ //NameA
933
+ //NameA.NameB
934
+ //NameA.NameB.NameC
935
+ if (namespace.fullName.toLowerCase() === closestParentNamespaceName) {
936
+ //add all of this namespace's immediate child namespaces, bearing in mind if we are after a new keyword
937
+ for (let [, ns] of namespace.namespaces) {
938
+ if (!newToken || ns.statements.find((s) => (0, reflection_1.isClassStatement)(s))) {
939
+ if (!result.has(ns.lastPartName)) {
940
+ result.set(ns.lastPartName, {
941
+ label: ns.lastPartName,
942
+ kind: vscode_languageserver_2.CompletionItemKind.Module
943
+ });
944
+ }
945
+ }
946
+ }
947
+ //add function and class statement completions
948
+ for (let stmt of namespace.statements) {
949
+ if ((0, reflection_1.isClassStatement)(stmt)) {
950
+ result.set(stmt.name.text, {
951
+ label: stmt.name.text,
952
+ kind: vscode_languageserver_2.CompletionItemKind.Class
953
+ });
954
+ }
955
+ else if ((0, reflection_1.isFunctionStatement)(stmt) && !newToken) {
956
+ result.set(stmt.name.text, {
957
+ label: stmt.name.text,
958
+ kind: vscode_languageserver_2.CompletionItemKind.Function
959
+ });
960
+ }
961
+ else if ((0, reflection_1.isEnumStatement)(stmt) && !newToken) {
962
+ result.set(stmt.name, {
963
+ label: stmt.name,
964
+ kind: vscode_languageserver_2.CompletionItemKind.Enum
965
+ });
966
+ }
967
+ else if ((0, reflection_1.isConstStatement)(stmt) && !newToken) {
968
+ result.set(stmt.name, {
969
+ label: stmt.name,
970
+ kind: vscode_languageserver_2.CompletionItemKind.Constant
971
+ });
972
+ }
973
+ }
974
+ }
975
+ }
976
+ return [...result.values()];
602
977
  }
603
978
  /**
604
979
  * Given a current token, walk
@@ -627,9 +1002,6 @@ class BrsFile {
627
1002
  }
628
1003
  isPositionNextToTokenKind(position, tokenKind) {
629
1004
  const closestToken = this.getClosestToken(position);
630
- return this.isTokenNextToTokenKind(closestToken, tokenKind);
631
- }
632
- isTokenNextToTokenKind(closestToken, tokenKind) {
633
1005
  const previousToken = this.getPreviousToken(closestToken);
634
1006
  const previousTokenKind = previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind;
635
1007
  //next to matched token
@@ -652,9 +1024,6 @@ class BrsFile {
652
1024
  }
653
1025
  getTokenBefore(currentToken, tokenKind) {
654
1026
  const index = this.parser.tokens.indexOf(currentToken);
655
- if (!tokenKind) {
656
- return this.parser.tokens[index - 1];
657
- }
658
1027
  for (let i = index - 1; i >= 0; i--) {
659
1028
  currentToken = this.parser.tokens[i];
660
1029
  if (currentToken.kind === TokenKind_1.TokenKind.Newline) {
@@ -722,7 +1091,7 @@ class BrsFile {
722
1091
  let scopes = this.program.getScopesForFile(this);
723
1092
  for (let scope of scopes) {
724
1093
  let namespace = scope.namespaceLookup.get(namespaceName.toLowerCase());
725
- if (namespace.functionStatements.has(lowerCalleeName)) {
1094
+ if (namespace === null || namespace === void 0 ? void 0 : namespace.functionStatements[lowerCalleeName]) {
726
1095
  return true;
727
1096
  }
728
1097
  }
@@ -752,248 +1121,36 @@ class BrsFile {
752
1121
  }
753
1122
  /**
754
1123
  * Builds a list of document symbols for this file. Used by LanguageServer's onDocumentSymbol functionality
1124
+ * @deprecated use `DocumentSymbolProvider.process()` instead
755
1125
  */
756
1126
  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;
1127
+ return new DocumentSymbolProcessor_1.DocumentSymbolProcessor({
1128
+ documentSymbols: [],
1129
+ file: this,
1130
+ program: this.program
1131
+ }).process();
769
1132
  }
770
1133
  /**
771
1134
  * Builds a list of workspace symbols for this file. Used by LanguageServer's onWorkspaceSymbol functionality
772
1135
  */
773
1136
  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;
1137
+ return new WorkspaceSymbolProcessor_1.WorkspaceSymbolProcessor({
1138
+ program: this.program,
1139
+ workspaceSymbols: []
1140
+ }).process();
861
1141
  }
862
1142
  /**
863
1143
  * Given a position in a file, if the position is sitting on some type of identifier,
864
1144
  * go to the definition of that identifier (where this thing was first defined)
1145
+ * @deprecated use `DefinitionProvider.process()` instead
865
1146
  */
866
1147
  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;
1148
+ return new DefinitionProvider_1.DefinitionProvider({
1149
+ program: this.program,
1150
+ file: this,
1151
+ position: position,
1152
+ definitions: []
1153
+ }).process();
997
1154
  }
998
1155
  getClassMemberDefinitions(textToSearchFor, file) {
999
1156
  let results = [];
@@ -1009,8 +1166,8 @@ class BrsFile {
1009
1166
  }
1010
1167
  };
1011
1168
  file.parser.ast.walk((0, visitors_1.createVisitor)({
1012
- MethodStatement: statementHandler,
1013
- FieldStatement: fieldStatementHandler
1169
+ ClassMethodStatement: statementHandler,
1170
+ ClassFieldStatement: fieldStatementHandler
1014
1171
  }), {
1015
1172
  walkMode: visitors_1.WalkMode.visitStatements
1016
1173
  });
@@ -1044,58 +1201,27 @@ class BrsFile {
1044
1201
  }
1045
1202
  return statement;
1046
1203
  }
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
1204
  /**
1072
- * Generate the code, map, and typedef for this file
1205
+ * Given a position in a file, if the position is sitting on some type of identifier,
1206
+ * look up all references of that identifier (every place that identifier is used across the whole app)
1207
+ * @deprecated use `ReferencesProvider.process()` instead
1073
1208
  */
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;
1209
+ getReferences(position) {
1210
+ return new ReferencesProvider_1.ReferencesProvider({
1211
+ program: this.program,
1212
+ file: this,
1213
+ position: position,
1214
+ references: []
1215
+ }).process();
1088
1216
  }
1089
1217
  /**
1090
1218
  * Convert the brightscript/brighterscript source code into valid brightscript
1091
1219
  */
1092
1220
  transpile() {
1093
- var _a;
1094
1221
  const state = new BrsTranspileState_1.BrsTranspileState(this);
1095
- state.editor = (_a = this.editor) !== null && _a !== void 0 ? _a : new Editor_1.Editor();
1096
1222
  let transpileResult;
1097
1223
  if (this.needsTranspiled) {
1098
- transpileResult = new source_map_1.SourceNode(null, null, state.srcPath, this.ast.transpile(state));
1224
+ transpileResult = util_1.util.sourceNodeFromTranspileResult(null, null, state.srcPath, this.ast.transpile(state));
1099
1225
  }
1100
1226
  else if (this.program.options.sourceMap) {
1101
1227
  //emit code as-is with a simple map to the original file location
@@ -1105,17 +1231,15 @@ class BrsFile {
1105
1231
  //simple SourceNode wrapping the entire file to simplify the logic below
1106
1232
  transpileResult = new source_map_1.SourceNode(null, null, state.srcPath, this.fileContents);
1107
1233
  }
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
- }
1234
+ //undo any AST edits that the transpile cycle has made
1235
+ state.editor.undoAll();
1113
1236
  if (this.program.options.sourceMap) {
1114
- return new source_map_1.SourceNode(null, null, null, [
1237
+ const stagingFileName = path.basename(state.srcPath).replace(/\.bs$/, '.brs');
1238
+ return new source_map_1.SourceNode(null, null, stagingFileName, [
1115
1239
  transpileResult,
1116
1240
  //add the sourcemap reference comment
1117
- `'//# sourceMappingURL=./${path.basename(state.srcPath)}.map`
1118
- ]).toStringWithSourceMap();
1241
+ state.newline + `'//# sourceMappingURL=./${stagingFileName}.map`
1242
+ ]).toStringWithSourceMap({ file: stagingFileName });
1119
1243
  }
1120
1244
  else {
1121
1245
  return {
@@ -1124,210 +1248,17 @@ class BrsFile {
1124
1248
  };
1125
1249
  }
1126
1250
  }
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
1251
  getTypedef() {
1323
1252
  const state = new BrsTranspileState_1.BrsTranspileState(this);
1324
1253
  const typedef = this.ast.getTypedef(state);
1325
- const programNode = new source_map_1.SourceNode(null, null, this.srcPath, typedef);
1254
+ const programNode = util_1.util.sourceNodeFromTranspileResult(null, null, this.srcPath, typedef);
1326
1255
  return programNode.toString();
1327
1256
  }
1328
1257
  dispose() {
1329
- var _a;
1258
+ var _a, _b;
1330
1259
  (_a = this._parser) === null || _a === void 0 ? void 0 : _a.dispose();
1260
+ //unsubscribe from any DependencyGraph subscriptions
1261
+ (_b = this.unsubscribeFromDependencyGraph) === null || _b === void 0 ? void 0 : _b.call(this);
1331
1262
  //deleting these properties result in lower memory usage (garbage collection is magic!)
1332
1263
  delete this.fileContents;
1333
1264
  delete this._parser;
@@ -1338,4 +1269,18 @@ class BrsFile {
1338
1269
  }
1339
1270
  }
1340
1271
  exports.BrsFile = BrsFile;
1272
+ /**
1273
+ * List of completions for all valid keywords/reserved words.
1274
+ * Build this list once because it won't change for the lifetime of this process
1275
+ */
1276
+ exports.KeywordCompletions = Object.keys(TokenKind_1.Keywords)
1277
+ //remove any keywords with whitespace
1278
+ .filter(x => !x.includes(' '))
1279
+ //create completions
1280
+ .map(x => {
1281
+ return {
1282
+ label: x,
1283
+ kind: vscode_languageserver_2.CompletionItemKind.Keyword
1284
+ };
1285
+ });
1341
1286
  //# sourceMappingURL=BrsFile.js.map