brighterscript 0.72.0 → 0.72.2

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 (335) hide show
  1. package/bsconfig.schema.json +62 -0
  2. package/dist/BsConfig.d.ts +56 -1
  3. package/dist/CommentFlagProcessor.d.ts +16 -12
  4. package/dist/CommentFlagProcessor.js +141 -59
  5. package/dist/CommentFlagProcessor.js.map +1 -1
  6. package/dist/DiagnosticMessages.d.ts +27 -1
  7. package/dist/DiagnosticMessages.js +32 -2
  8. package/dist/DiagnosticMessages.js.map +1 -1
  9. package/dist/Program.d.ts +4 -0
  10. package/dist/Program.js +2 -0
  11. package/dist/Program.js.map +1 -1
  12. package/dist/ProgramBuilder.d.ts +1 -8
  13. package/dist/ProgramBuilder.js +31 -11
  14. package/dist/ProgramBuilder.js.map +1 -1
  15. package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +38 -0
  16. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +257 -14
  17. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  18. package/dist/bscPlugin/validation/BrsFileValidator.js +13 -0
  19. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  20. package/dist/cli.js +13 -0
  21. package/dist/cli.js.map +1 -1
  22. package/dist/diagnosticUtils.d.ts +51 -1
  23. package/dist/diagnosticUtils.js +222 -1
  24. package/dist/diagnosticUtils.js.map +1 -1
  25. package/dist/files/BrsFile.js +4 -2
  26. package/dist/files/BrsFile.js.map +1 -1
  27. package/dist/files/XmlFile.js +2 -1
  28. package/dist/files/XmlFile.js.map +1 -1
  29. package/dist/interfaces.d.ts +15 -1
  30. package/dist/lexer/TokenKind.d.ts +8 -0
  31. package/dist/lexer/TokenKind.js +21 -1
  32. package/dist/lexer/TokenKind.js.map +1 -1
  33. package/dist/lsp/LspProject.d.ts +19 -0
  34. package/dist/lsp/Project.d.ts +14 -0
  35. package/dist/lsp/Project.js +9 -1
  36. package/dist/lsp/Project.js.map +1 -1
  37. package/dist/lsp/ProjectManager.js +15 -1
  38. package/dist/lsp/ProjectManager.js.map +1 -1
  39. package/dist/lsp/worker/WorkerThreadProject.d.ts +14 -0
  40. package/dist/lsp/worker/WorkerThreadProject.js +7 -0
  41. package/dist/lsp/worker/WorkerThreadProject.js.map +1 -1
  42. package/dist/parser/Parser.d.ts +13 -1
  43. package/dist/parser/Parser.js +40 -14
  44. package/dist/parser/Parser.js.map +1 -1
  45. package/dist/util.js +20 -9
  46. package/dist/util.js.map +1 -1
  47. package/package.json +17 -14
  48. package/dist/astUtils/AstEditor.spec.d.ts +0 -1
  49. package/dist/astUtils/AstEditor.spec.js +0 -254
  50. package/dist/astUtils/AstEditor.spec.js.map +0 -1
  51. package/dist/astUtils/creators.spec.d.ts +0 -1
  52. package/dist/astUtils/creators.spec.js +0 -21
  53. package/dist/astUtils/creators.spec.js.map +0 -1
  54. package/dist/astUtils/reflection.spec.d.ts +0 -1
  55. package/dist/astUtils/reflection.spec.js +0 -308
  56. package/dist/astUtils/reflection.spec.js.map +0 -1
  57. package/dist/astUtils/stackedVisitor.spec.d.ts +0 -1
  58. package/dist/astUtils/stackedVisitor.spec.js +0 -79
  59. package/dist/astUtils/stackedVisitor.spec.js.map +0 -1
  60. package/dist/astUtils/visitors.spec.d.ts +0 -1
  61. package/dist/astUtils/visitors.spec.js +0 -1197
  62. package/dist/astUtils/visitors.spec.js.map +0 -1
  63. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.d.ts +0 -1
  64. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +0 -887
  65. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +0 -1
  66. package/dist/bscPlugin/definition/DefinitionProvider.spec.d.ts +0 -1
  67. package/dist/bscPlugin/definition/DefinitionProvider.spec.js +0 -171
  68. package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +0 -1
  69. package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +0 -1
  70. package/dist/bscPlugin/hover/HoverProcessor.spec.js +0 -201
  71. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +0 -1
  72. package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +0 -1
  73. package/dist/bscPlugin/references/ReferencesProvider.spec.js +0 -51
  74. package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +0 -1
  75. package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.spec.d.ts +0 -1
  76. package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.spec.js +0 -298
  77. package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.spec.js.map +0 -1
  78. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +0 -1
  79. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +0 -399
  80. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +0 -1
  81. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.d.ts +0 -1
  82. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +0 -290
  83. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +0 -1
  84. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.d.ts +0 -1
  85. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +0 -245
  86. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +0 -1
  87. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts +0 -1
  88. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -46
  89. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
  90. package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +0 -1
  91. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +0 -487
  92. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +0 -1
  93. package/dist/common/Sequencer.spec.d.ts +0 -1
  94. package/dist/common/Sequencer.spec.js +0 -75
  95. package/dist/common/Sequencer.spec.js.map +0 -1
  96. package/dist/files/BrsFile.Class.spec.d.ts +0 -1
  97. package/dist/files/BrsFile.Class.spec.js +0 -1805
  98. package/dist/files/BrsFile.Class.spec.js.map +0 -1
  99. package/dist/files/BrsFile.spec.d.ts +0 -1
  100. package/dist/files/BrsFile.spec.js +0 -4420
  101. package/dist/files/BrsFile.spec.js.map +0 -1
  102. package/dist/files/XmlFile.spec.d.ts +0 -1
  103. package/dist/files/XmlFile.spec.js +0 -1169
  104. package/dist/files/XmlFile.spec.js.map +0 -1
  105. package/dist/files/tests/imports.spec.d.ts +0 -1
  106. package/dist/files/tests/imports.spec.js +0 -241
  107. package/dist/files/tests/imports.spec.js.map +0 -1
  108. package/dist/files/tests/optionalChaning.spec.d.ts +0 -1
  109. package/dist/files/tests/optionalChaning.spec.js +0 -152
  110. package/dist/files/tests/optionalChaning.spec.js.map +0 -1
  111. package/dist/lexer/Character.spec.d.ts +0 -1
  112. package/dist/lexer/Character.spec.js +0 -27
  113. package/dist/lexer/Character.spec.js.map +0 -1
  114. package/dist/lexer/Lexer.spec.d.ts +0 -1
  115. package/dist/lexer/Lexer.spec.js +0 -1300
  116. package/dist/lexer/Lexer.spec.js.map +0 -1
  117. package/dist/lsp/ActionQueue.spec.d.ts +0 -1
  118. package/dist/lsp/ActionQueue.spec.js +0 -80
  119. package/dist/lsp/ActionQueue.spec.js.map +0 -1
  120. package/dist/lsp/DocumentManager.spec.d.ts +0 -1
  121. package/dist/lsp/DocumentManager.spec.js +0 -103
  122. package/dist/lsp/DocumentManager.spec.js.map +0 -1
  123. package/dist/lsp/PathFilterer.spec.d.ts +0 -1
  124. package/dist/lsp/PathFilterer.spec.js +0 -182
  125. package/dist/lsp/PathFilterer.spec.js.map +0 -1
  126. package/dist/lsp/Project.spec.d.ts +0 -1
  127. package/dist/lsp/Project.spec.js +0 -400
  128. package/dist/lsp/Project.spec.js.map +0 -1
  129. package/dist/lsp/ProjectManager.spec.d.ts +0 -1
  130. package/dist/lsp/ProjectManager.spec.js +0 -1147
  131. package/dist/lsp/ProjectManager.spec.js.map +0 -1
  132. package/dist/lsp/worker/MessageHandler.spec.d.ts +0 -1
  133. package/dist/lsp/worker/MessageHandler.spec.js +0 -64
  134. package/dist/lsp/worker/MessageHandler.spec.js.map +0 -1
  135. package/dist/lsp/worker/WorkerPool.spec.d.ts +0 -1
  136. package/dist/lsp/worker/WorkerPool.spec.js +0 -59
  137. package/dist/lsp/worker/WorkerPool.spec.js.map +0 -1
  138. package/dist/lsp/worker/WorkerThreadProject.spec.d.ts +0 -2
  139. package/dist/lsp/worker/WorkerThreadProject.spec.js +0 -72
  140. package/dist/lsp/worker/WorkerThreadProject.spec.js.map +0 -1
  141. package/dist/parser/AstNode.spec.d.ts +0 -1
  142. package/dist/parser/AstNode.spec.js +0 -1452
  143. package/dist/parser/AstNode.spec.js.map +0 -1
  144. package/dist/parser/Expression.spec.d.ts +0 -1
  145. package/dist/parser/Expression.spec.js +0 -40
  146. package/dist/parser/Expression.spec.js.map +0 -1
  147. package/dist/parser/Parser.Class.spec.d.ts +0 -1
  148. package/dist/parser/Parser.Class.spec.js +0 -495
  149. package/dist/parser/Parser.Class.spec.js.map +0 -1
  150. package/dist/parser/Parser.spec.d.ts +0 -4
  151. package/dist/parser/Parser.spec.js +0 -1857
  152. package/dist/parser/Parser.spec.js.map +0 -1
  153. package/dist/parser/SGParser.spec.d.ts +0 -1
  154. package/dist/parser/SGParser.spec.js +0 -131
  155. package/dist/parser/SGParser.spec.js.map +0 -1
  156. package/dist/parser/Statement.spec.d.ts +0 -1
  157. package/dist/parser/Statement.spec.js +0 -118
  158. package/dist/parser/Statement.spec.js.map +0 -1
  159. package/dist/parser/tests/Parser.spec.d.ts +0 -19
  160. package/dist/parser/tests/Parser.spec.js +0 -38
  161. package/dist/parser/tests/Parser.spec.js.map +0 -1
  162. package/dist/parser/tests/controlFlow/For.spec.d.ts +0 -1
  163. package/dist/parser/tests/controlFlow/For.spec.js +0 -161
  164. package/dist/parser/tests/controlFlow/For.spec.js.map +0 -1
  165. package/dist/parser/tests/controlFlow/ForEach.spec.d.ts +0 -1
  166. package/dist/parser/tests/controlFlow/ForEach.spec.js +0 -106
  167. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +0 -1
  168. package/dist/parser/tests/controlFlow/If.spec.d.ts +0 -1
  169. package/dist/parser/tests/controlFlow/If.spec.js +0 -570
  170. package/dist/parser/tests/controlFlow/If.spec.js.map +0 -1
  171. package/dist/parser/tests/controlFlow/While.spec.d.ts +0 -1
  172. package/dist/parser/tests/controlFlow/While.spec.js +0 -107
  173. package/dist/parser/tests/controlFlow/While.spec.js.map +0 -1
  174. package/dist/parser/tests/expression/Additive.spec.d.ts +0 -1
  175. package/dist/parser/tests/expression/Additive.spec.js +0 -99
  176. package/dist/parser/tests/expression/Additive.spec.js.map +0 -1
  177. package/dist/parser/tests/expression/ArrayLiterals.spec.d.ts +0 -1
  178. package/dist/parser/tests/expression/ArrayLiterals.spec.js +0 -291
  179. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +0 -1
  180. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.d.ts +0 -1
  181. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +0 -401
  182. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +0 -1
  183. package/dist/parser/tests/expression/Boolean.spec.d.ts +0 -1
  184. package/dist/parser/tests/expression/Boolean.spec.js +0 -83
  185. package/dist/parser/tests/expression/Boolean.spec.js.map +0 -1
  186. package/dist/parser/tests/expression/Call.spec.d.ts +0 -1
  187. package/dist/parser/tests/expression/Call.spec.js +0 -242
  188. package/dist/parser/tests/expression/Call.spec.js.map +0 -1
  189. package/dist/parser/tests/expression/Exponential.spec.d.ts +0 -1
  190. package/dist/parser/tests/expression/Exponential.spec.js +0 -37
  191. package/dist/parser/tests/expression/Exponential.spec.js.map +0 -1
  192. package/dist/parser/tests/expression/Function.spec.d.ts +0 -1
  193. package/dist/parser/tests/expression/Function.spec.js +0 -403
  194. package/dist/parser/tests/expression/Function.spec.js.map +0 -1
  195. package/dist/parser/tests/expression/Indexing.spec.d.ts +0 -1
  196. package/dist/parser/tests/expression/Indexing.spec.js +0 -289
  197. package/dist/parser/tests/expression/Indexing.spec.js.map +0 -1
  198. package/dist/parser/tests/expression/Multiplicative.spec.d.ts +0 -1
  199. package/dist/parser/tests/expression/Multiplicative.spec.js +0 -67
  200. package/dist/parser/tests/expression/Multiplicative.spec.js.map +0 -1
  201. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.d.ts +0 -1
  202. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +0 -346
  203. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +0 -1
  204. package/dist/parser/tests/expression/PrefixUnary.spec.d.ts +0 -1
  205. package/dist/parser/tests/expression/PrefixUnary.spec.js +0 -105
  206. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +0 -1
  207. package/dist/parser/tests/expression/Primary.spec.d.ts +0 -1
  208. package/dist/parser/tests/expression/Primary.spec.js +0 -149
  209. package/dist/parser/tests/expression/Primary.spec.js.map +0 -1
  210. package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +0 -1
  211. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +0 -171
  212. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +0 -1
  213. package/dist/parser/tests/expression/Relational.spec.d.ts +0 -1
  214. package/dist/parser/tests/expression/Relational.spec.js +0 -83
  215. package/dist/parser/tests/expression/Relational.spec.js.map +0 -1
  216. package/dist/parser/tests/expression/SourceLiteralExpression.spec.d.ts +0 -1
  217. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +0 -201
  218. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +0 -1
  219. package/dist/parser/tests/expression/TemplateStringExpression.spec.d.ts +0 -1
  220. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +0 -389
  221. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +0 -1
  222. package/dist/parser/tests/expression/TernaryExpression.spec.d.ts +0 -1
  223. package/dist/parser/tests/expression/TernaryExpression.spec.js +0 -876
  224. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +0 -1
  225. package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +0 -1
  226. package/dist/parser/tests/expression/UnaryExpression.spec.js +0 -52
  227. package/dist/parser/tests/expression/UnaryExpression.spec.js.map +0 -1
  228. package/dist/parser/tests/statement/AssignmentOperators.spec.d.ts +0 -1
  229. package/dist/parser/tests/statement/AssignmentOperators.spec.js +0 -79
  230. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +0 -1
  231. package/dist/parser/tests/statement/ConstStatement.spec.d.ts +0 -1
  232. package/dist/parser/tests/statement/ConstStatement.spec.js +0 -708
  233. package/dist/parser/tests/statement/ConstStatement.spec.js.map +0 -1
  234. package/dist/parser/tests/statement/Continue.spec.d.ts +0 -1
  235. package/dist/parser/tests/statement/Continue.spec.js +0 -119
  236. package/dist/parser/tests/statement/Continue.spec.js.map +0 -1
  237. package/dist/parser/tests/statement/Declaration.spec.d.ts +0 -1
  238. package/dist/parser/tests/statement/Declaration.spec.js +0 -108
  239. package/dist/parser/tests/statement/Declaration.spec.js.map +0 -1
  240. package/dist/parser/tests/statement/Dim.spec.d.ts +0 -1
  241. package/dist/parser/tests/statement/Dim.spec.js +0 -73
  242. package/dist/parser/tests/statement/Dim.spec.js.map +0 -1
  243. package/dist/parser/tests/statement/Enum.spec.d.ts +0 -1
  244. package/dist/parser/tests/statement/Enum.spec.js +0 -1307
  245. package/dist/parser/tests/statement/Enum.spec.js.map +0 -1
  246. package/dist/parser/tests/statement/For.spec.d.ts +0 -1
  247. package/dist/parser/tests/statement/For.spec.js +0 -45
  248. package/dist/parser/tests/statement/For.spec.js.map +0 -1
  249. package/dist/parser/tests/statement/ForEach.spec.d.ts +0 -1
  250. package/dist/parser/tests/statement/ForEach.spec.js +0 -36
  251. package/dist/parser/tests/statement/ForEach.spec.js.map +0 -1
  252. package/dist/parser/tests/statement/Function.spec.d.ts +0 -1
  253. package/dist/parser/tests/statement/Function.spec.js +0 -342
  254. package/dist/parser/tests/statement/Function.spec.js.map +0 -1
  255. package/dist/parser/tests/statement/Goto.spec.d.ts +0 -1
  256. package/dist/parser/tests/statement/Goto.spec.js +0 -51
  257. package/dist/parser/tests/statement/Goto.spec.js.map +0 -1
  258. package/dist/parser/tests/statement/Increment.spec.d.ts +0 -1
  259. package/dist/parser/tests/statement/Increment.spec.js +0 -117
  260. package/dist/parser/tests/statement/Increment.spec.js.map +0 -1
  261. package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +0 -1
  262. package/dist/parser/tests/statement/InterfaceStatement.spec.js +0 -102
  263. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +0 -1
  264. package/dist/parser/tests/statement/LibraryStatement.spec.d.ts +0 -1
  265. package/dist/parser/tests/statement/LibraryStatement.spec.js +0 -74
  266. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +0 -1
  267. package/dist/parser/tests/statement/Misc.spec.d.ts +0 -1
  268. package/dist/parser/tests/statement/Misc.spec.js +0 -335
  269. package/dist/parser/tests/statement/Misc.spec.js.map +0 -1
  270. package/dist/parser/tests/statement/PrintStatement.spec.d.ts +0 -1
  271. package/dist/parser/tests/statement/PrintStatement.spec.js +0 -195
  272. package/dist/parser/tests/statement/PrintStatement.spec.js.map +0 -1
  273. package/dist/parser/tests/statement/ReturnStatement.spec.d.ts +0 -1
  274. package/dist/parser/tests/statement/ReturnStatement.spec.js +0 -94
  275. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +0 -1
  276. package/dist/parser/tests/statement/Set.spec.d.ts +0 -1
  277. package/dist/parser/tests/statement/Set.spec.js +0 -218
  278. package/dist/parser/tests/statement/Set.spec.js.map +0 -1
  279. package/dist/parser/tests/statement/Stop.spec.d.ts +0 -1
  280. package/dist/parser/tests/statement/Stop.spec.js +0 -38
  281. package/dist/parser/tests/statement/Stop.spec.js.map +0 -1
  282. package/dist/parser/tests/statement/Throw.spec.d.ts +0 -1
  283. package/dist/parser/tests/statement/Throw.spec.js +0 -35
  284. package/dist/parser/tests/statement/Throw.spec.js.map +0 -1
  285. package/dist/parser/tests/statement/TryCatch.spec.d.ts +0 -1
  286. package/dist/parser/tests/statement/TryCatch.spec.js +0 -142
  287. package/dist/parser/tests/statement/TryCatch.spec.js.map +0 -1
  288. package/dist/preprocessor/Manifest.spec.d.ts +0 -1
  289. package/dist/preprocessor/Manifest.spec.js +0 -80
  290. package/dist/preprocessor/Manifest.spec.js.map +0 -1
  291. package/dist/preprocessor/Preprocessor.spec.d.ts +0 -1
  292. package/dist/preprocessor/Preprocessor.spec.js +0 -152
  293. package/dist/preprocessor/Preprocessor.spec.js.map +0 -1
  294. package/dist/preprocessor/PreprocessorParser.spec.d.ts +0 -1
  295. package/dist/preprocessor/PreprocessorParser.spec.js +0 -116
  296. package/dist/preprocessor/PreprocessorParser.spec.js.map +0 -1
  297. package/dist/types/ArrayType.spec.d.ts +0 -1
  298. package/dist/types/ArrayType.spec.js +0 -30
  299. package/dist/types/ArrayType.spec.js.map +0 -1
  300. package/dist/types/BooleanType.spec.d.ts +0 -1
  301. package/dist/types/BooleanType.spec.js +0 -12
  302. package/dist/types/BooleanType.spec.js.map +0 -1
  303. package/dist/types/DoubleType.spec.d.ts +0 -1
  304. package/dist/types/DoubleType.spec.js +0 -12
  305. package/dist/types/DoubleType.spec.js.map +0 -1
  306. package/dist/types/DynamicType.spec.d.ts +0 -1
  307. package/dist/types/DynamicType.spec.js +0 -12
  308. package/dist/types/DynamicType.spec.js.map +0 -1
  309. package/dist/types/FloatType.spec.d.ts +0 -1
  310. package/dist/types/FloatType.spec.js +0 -12
  311. package/dist/types/FloatType.spec.js.map +0 -1
  312. package/dist/types/FunctionType.spec.d.ts +0 -1
  313. package/dist/types/FunctionType.spec.js +0 -23
  314. package/dist/types/FunctionType.spec.js.map +0 -1
  315. package/dist/types/IntegerType.spec.d.ts +0 -1
  316. package/dist/types/IntegerType.spec.js +0 -12
  317. package/dist/types/IntegerType.spec.js.map +0 -1
  318. package/dist/types/InterfaceType.spec.d.ts +0 -1
  319. package/dist/types/InterfaceType.spec.js +0 -175
  320. package/dist/types/InterfaceType.spec.js.map +0 -1
  321. package/dist/types/InvalidType.spec.d.ts +0 -1
  322. package/dist/types/InvalidType.spec.js +0 -12
  323. package/dist/types/InvalidType.spec.js.map +0 -1
  324. package/dist/types/LongIntegerType.spec.d.ts +0 -1
  325. package/dist/types/LongIntegerType.spec.js +0 -12
  326. package/dist/types/LongIntegerType.spec.js.map +0 -1
  327. package/dist/types/ObjectType.spec.d.ts +0 -1
  328. package/dist/types/ObjectType.spec.js +0 -12
  329. package/dist/types/ObjectType.spec.js.map +0 -1
  330. package/dist/types/StringType.spec.d.ts +0 -1
  331. package/dist/types/StringType.spec.js +0 -12
  332. package/dist/types/StringType.spec.js.map +0 -1
  333. package/dist/types/VoidType.spec.d.ts +0 -1
  334. package/dist/types/VoidType.spec.js +0 -12
  335. package/dist/types/VoidType.spec.js.map +0 -1
@@ -1,1147 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const chai_1 = require("chai");
4
- const ProjectManager_1 = require("./ProjectManager");
5
- const testHelpers_spec_1 = require("../testHelpers.spec");
6
- const fsExtra = require("fs-extra");
7
- const util_1 = require("../util");
8
- const sinon_1 = require("sinon");
9
- const Project_1 = require("./Project");
10
- const WorkerThreadProject_1 = require("./worker/WorkerThreadProject");
11
- const WorkerThreadProject_spec_1 = require("./worker/WorkerThreadProject.spec");
12
- const DiagnosticMessages_1 = require("../DiagnosticMessages");
13
- const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
14
- const PathFilterer_1 = require("./PathFilterer");
15
- const deferred_1 = require("../deferred");
16
- const net = require("net");
17
- const getPort = require("get-port");
18
- const sinon = (0, sinon_1.createSandbox)();
19
- describe('ProjectManager', () => {
20
- let manager;
21
- let pathFilterer;
22
- beforeEach(() => {
23
- pathFilterer = new PathFilterer_1.PathFilterer();
24
- manager = new ProjectManager_1.ProjectManager({
25
- pathFilterer: pathFilterer
26
- });
27
- fsExtra.emptyDirSync(testHelpers_spec_1.tempDir);
28
- sinon.restore();
29
- diagnosticsListeners = [];
30
- diagnosticsResponses = [];
31
- manager.on('diagnostics', (event) => {
32
- var _a;
33
- if (diagnosticsListeners.length > 0) {
34
- (_a = diagnosticsListeners.shift()) === null || _a === void 0 ? void 0 : _a(event.diagnostics);
35
- }
36
- else {
37
- diagnosticsResponses.push(event.diagnostics);
38
- }
39
- });
40
- });
41
- afterEach(() => {
42
- fsExtra.emptyDirSync(testHelpers_spec_1.tempDir);
43
- sinon.restore();
44
- manager.dispose();
45
- });
46
- let diagnosticsListeners = [];
47
- let diagnosticsResponses = [];
48
- /**
49
- * Get a promise that resolves when the next diagnostics event is emitted (or pop the earliest unhandled diagnostics list if some are already here)
50
- */
51
- function onNextDiagnostics() {
52
- if (diagnosticsResponses.length > 0) {
53
- return Promise.resolve(diagnosticsResponses.shift());
54
- }
55
- else {
56
- return new Promise((resolve) => {
57
- diagnosticsListeners.push(resolve);
58
- });
59
- }
60
- }
61
- async function setFile(srcPath, contents) {
62
- //set the namespace first
63
- await manager.handleFileChanges([{
64
- srcPath: srcPath,
65
- type: vscode_languageserver_protocol_1.FileChangeType.Changed,
66
- fileContents: contents,
67
- allowStandaloneProject: false
68
- }]);
69
- }
70
- describe('on', () => {
71
- it('emits events', async () => {
72
- const stub = sinon.stub();
73
- const off = manager.on('diagnostics', stub);
74
- await manager['emit']('diagnostics', { project: undefined, diagnostics: [] });
75
- (0, chai_1.expect)(stub.callCount).to.eql(1);
76
- await manager['emit']('diagnostics', { project: undefined, diagnostics: [] });
77
- (0, chai_1.expect)(stub.callCount).to.eql(2);
78
- off();
79
- await manager['emit']('diagnostics', { project: undefined, diagnostics: [] });
80
- (0, chai_1.expect)(stub.callCount).to.eql(2);
81
- });
82
- });
83
- describe('validation tracking', () => {
84
- it('tracks validation state', async () => {
85
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
86
- const project = manager.projects[0];
87
- //force validation to take a while
88
- sinon.stub(project['builder'].program, 'validate').callsFake(async () => {
89
- await util_1.default.sleep(100);
90
- });
91
- (0, chai_1.expect)(manager.busyStatusTracker.status).to.eql('idle');
92
- //run several validations (which cancel the previous)
93
- void project.validate();
94
- await util_1.default.sleep(10);
95
- void project.validate();
96
- await util_1.default.sleep(10);
97
- void project.validate();
98
- await util_1.default.sleep(10);
99
- //busy status should be active
100
- (0, chai_1.expect)(manager.busyStatusTracker.status).to.eql('busy');
101
- });
102
- });
103
- describe('syncProjects', () => {
104
- it('does not crash on zero projects', async () => {
105
- await manager.syncProjects([]);
106
- });
107
- it('finds bsconfig in a folder', async () => {
108
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, '');
109
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
110
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
111
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`
112
- ]);
113
- });
114
- it('finds bsconfig at root and also in subfolder', async () => {
115
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, '');
116
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/bsconfig.json`, '');
117
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
118
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
119
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`,
120
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir/bsconfig.json`
121
- ]);
122
- });
123
- it('skips excluded bsconfig bsconfig in a folder', async () => {
124
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, '');
125
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/bsconfig.json`, '');
126
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { excludePatterns: ['**/subdir/**/*'] })]);
127
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
128
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`
129
- ]);
130
- });
131
- it('uses rootDir when manifest found but no brightscript file', async () => {
132
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/manifest`, '');
133
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
134
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
135
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
136
- ]);
137
- });
138
- it('returns root folder when automatic discovery is disabled', async () => {
139
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, '');
140
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project2/bsconfig.json`, '');
141
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { enableProjectDiscovery: false }) })]);
142
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
143
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
144
- ]);
145
- });
146
- it('gets diagnostics from plugins added in afterProgramValidate', async () => {
147
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/plugin.js`, `
148
- module.exports = function () {
149
- return {
150
- afterProgramValidate: function(program) {
151
- var file = program.getFile('source/main.brs');
152
- //add a diagnostic from a plugin
153
- file.addDiagnostic({
154
- message: 'Test diagnostic',
155
- code: 'test-123',
156
- severity: 1
157
- });
158
- }
159
- }
160
- }
161
- `);
162
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
163
- plugins: [
164
- './plugin.js'
165
- ]
166
- });
167
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `
168
- sub test()
169
- print nameNotDefined
170
- end sub
171
- `);
172
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/manifest`, '');
173
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
174
- (0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
175
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('nameNotDefined').message,
176
- 'Test diagnostic'
177
- ]);
178
- });
179
- it('uses subdir when manifest and brightscript file found', async () => {
180
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/manifest`, '');
181
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/source/main.brs`, '');
182
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
183
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
184
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir`
185
- ]);
186
- });
187
- it('removes stale projects', async () => {
188
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`, '');
189
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`, '');
190
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
191
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
192
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`,
193
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`
194
- ]);
195
- fsExtra.removeSync(`${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`);
196
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
197
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
198
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`
199
- ]);
200
- });
201
- it('keeps existing projects on subsequent sync calls', async () => {
202
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`, '');
203
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`, '');
204
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
205
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
206
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`,
207
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`
208
- ]);
209
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
210
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
211
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`,
212
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`
213
- ]);
214
- });
215
- it('uses nonstandard json naming when specified in projects array', async () => {
216
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json`, '');
217
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, '');
218
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { projects: [
219
- { path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json` }
220
- ] })]);
221
- //we should NOT have found the `project1/bsconfig.json` file because it's not in the projects array
222
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
223
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json`
224
- ]);
225
- });
226
- it('supports pointing to a folder AND a bsconfig.json in projects array', async () => {
227
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json`, '');
228
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { projects: [
229
- { path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json` },
230
- { path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1` }
231
- ] })]);
232
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
233
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1`,
234
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json`
235
- ]);
236
- });
237
- it('supports project with AND without bsconfig.json in same location in projects array', async () => {
238
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, '');
239
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { projects: [
240
- { path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1` },
241
- { path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/bsconfig.json` }
242
- ] })]);
243
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
244
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1`,
245
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/bsconfig.json`
246
- ]);
247
- });
248
- it('ignores empty projects array configuration', async () => {
249
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, '');
250
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { projects: [] })]);
251
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
252
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/bsconfig.json`
253
- ]);
254
- });
255
- describe('concurrency limiting', () => {
256
- it('limits the number of projects activating concurrently', async () => {
257
- //create multiple bsconfig.json files
258
- for (let i = 0; i < 6; i++) {
259
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
260
- }
261
- //track concurrent activation count by stubbing the private activateProject method
262
- let maxConcurrent = 0;
263
- let currentConcurrent = 0;
264
- const activateStub = sinon.stub(manager, 'activateProject').callsFake(async () => {
265
- currentConcurrent++;
266
- maxConcurrent = Math.max(maxConcurrent, currentConcurrent);
267
- //simulate async activation work
268
- await util_1.default.sleep(10);
269
- currentConcurrent--;
270
- });
271
- //set a low concurrency limit for testing
272
- manager.projectActivationConcurrencyLimit = 2;
273
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
274
- //should have activated all 6 projects
275
- (0, chai_1.expect)(activateStub.callCount).to.eql(6);
276
- //but never more than 2 at a time
277
- (0, chai_1.expect)(maxConcurrent).to.be.at.most(2);
278
- });
279
- it('activates all projects even with concurrency limit', async () => {
280
- //create 5 bsconfig.json files
281
- for (let i = 0; i < 5; i++) {
282
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
283
- }
284
- manager.projectActivationConcurrencyLimit = 2;
285
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
286
- //all projects should be created
287
- (0, chai_1.expect)(manager.projects.length).to.eql(5);
288
- });
289
- it('limits the number of projects validating concurrently', async () => {
290
- for (let i = 0; i < 6; i++) {
291
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
292
- }
293
- let maxConcurrent = 0;
294
- let currentConcurrent = 0;
295
- let validateCallCount = 0;
296
- //stub activateProject to be a no-op so projects activate quickly
297
- sinon.stub(manager, 'activateProject').callsFake(async () => { });
298
- //stub Project.prototype.validate BEFORE syncProjects so the fire-and-forget phase uses it
299
- sinon.stub(Project_1.Project.prototype, 'validate').callsFake(async () => {
300
- currentConcurrent++;
301
- validateCallCount++;
302
- maxConcurrent = Math.max(maxConcurrent, currentConcurrent);
303
- await util_1.default.sleep(10);
304
- currentConcurrent--;
305
- });
306
- manager.projectActivationConcurrencyLimit = 2;
307
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
308
- //wait for the fire-and-forget validation phase to complete
309
- await util_1.default.sleep(200);
310
- (0, chai_1.expect)(validateCallCount).to.eql(6);
311
- (0, chai_1.expect)(maxConcurrent).to.be.at.most(2);
312
- });
313
- it('validates all projects after activation completes', async () => {
314
- for (let i = 0; i < 3; i++) {
315
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
316
- }
317
- let allActivated = false;
318
- let validationStartedBeforeActivation = false;
319
- let validateCallCount = 0;
320
- sinon.stub(manager, 'activateProject').callsFake(async () => { });
321
- sinon.stub(Project_1.Project.prototype, 'validate').callsFake(() => {
322
- if (!allActivated) {
323
- validationStartedBeforeActivation = true;
324
- }
325
- validateCallCount++;
326
- return Promise.resolve();
327
- });
328
- manager.projectActivationConcurrencyLimit = 1;
329
- //hook into the end of the activation phase by spying on firstSync
330
- const origTryResolve = manager['firstSync'].tryResolve.bind(manager['firstSync']);
331
- sinon.stub(manager['firstSync'], 'tryResolve').callsFake(() => {
332
- allActivated = true;
333
- return origTryResolve();
334
- });
335
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
336
- //wait for fire-and-forget validation phase
337
- await util_1.default.sleep(100);
338
- (0, chai_1.expect)(validateCallCount).to.eql(3);
339
- (0, chai_1.expect)(validationStartedBeforeActivation).to.be.false;
340
- });
341
- it('stops activating projects when a new sync starts', async () => {
342
- for (let i = 0; i < 4; i++) {
343
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
344
- }
345
- let activateCount = 0;
346
- const activateDeferred = new deferred_1.Deferred();
347
- sinon.stub(manager, 'activateProject').callsFake(async () => {
348
- activateCount++;
349
- //block the first activation so we can trigger a re-sync
350
- if (activateCount === 1) {
351
- await activateDeferred.promise;
352
- }
353
- });
354
- manager.projectActivationConcurrencyLimit = 1;
355
- //start first sync (will block on first activation)
356
- const firstSync = manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
357
- //wait for the first activation to start
358
- await util_1.default.sleep(50);
359
- //start a second sync which bumps the generation counter
360
- const secondSync = manager.syncProjects([testHelpers_spec_1.workspaceSettings], true);
361
- //unblock the first activation
362
- activateDeferred.resolve();
363
- await firstSync;
364
- await secondSync;
365
- //the first sync should have stopped activating after generation changed.
366
- //the exact count depends on timing, but we should NOT see all 4 from the first sync
367
- //plus all 4 from the second sync (8 total). The first sync's remaining items should be skipped.
368
- (0, chai_1.expect)(activateCount).to.be.lessThan(8);
369
- });
370
- it('skips validation when a new sync starts before validation phase', async () => {
371
- for (let i = 0; i < 3; i++) {
372
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
373
- }
374
- let validateCallCount = 0;
375
- const activateDeferred = new deferred_1.Deferred();
376
- sinon.stub(manager, 'activateProject').callsFake(async () => {
377
- //block on the deferred only when it's pending (we'll make it pending for the second sync)
378
- if (!activateDeferred.isCompleted) {
379
- await activateDeferred.promise;
380
- }
381
- });
382
- sinon.stub(Project_1.Project.prototype, 'validate').callsFake(() => {
383
- validateCallCount++;
384
- return Promise.resolve();
385
- });
386
- manager.projectActivationConcurrencyLimit = 1;
387
- //first sync — activates and validates normally (deferred starts resolved)
388
- activateDeferred.resolve();
389
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
390
- await util_1.default.sleep(50);
391
- const firstSyncValidateCount = validateCallCount;
392
- //reset for the next syncs: create a new deferred that blocks
393
- const blockDeferred = new deferred_1.Deferred();
394
- manager.activateProject.callsFake(async () => {
395
- await blockDeferred.promise;
396
- });
397
- //start second sync (blocks on activation)
398
- const secondSync = manager.syncProjects([testHelpers_spec_1.workspaceSettings], true);
399
- await util_1.default.sleep(10);
400
- //immediately start a third sync which bumps the generation
401
- const thirdSync = manager.syncProjects([testHelpers_spec_1.workspaceSettings], true);
402
- //unblock activation
403
- blockDeferred.resolve();
404
- await secondSync;
405
- await thirdSync;
406
- //wait for any fire-and-forget validation
407
- await util_1.default.sleep(100);
408
- //the second sync's validation should have been skipped because the third sync bumped the generation.
409
- //we should see at most the first sync's validations + the third sync's validations
410
- (0, chai_1.expect)(validateCallCount - firstSyncValidateCount).to.be.at.most(3);
411
- });
412
- });
413
- });
414
- describe('maxDepth configuration', () => {
415
- function writeTestFiles(files) {
416
- for (const [filePath, content] of Object.entries(files)) {
417
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/${filePath}`, content);
418
- }
419
- }
420
- it('respects maxDepth of 1 when discovering projects', async () => {
421
- // Create bsconfig.json files at different depths
422
- writeTestFiles({
423
- 'bsconfig.json': '',
424
- 'level1/bsconfig.json': '',
425
- 'level1/level2/bsconfig.json': '',
426
- 'level1/level2/level3/bsconfig.json': ''
427
- });
428
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 1 }) })]);
429
- // maxDepth: 1 should find files at depth 0 only
430
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
431
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`
432
- ]);
433
- });
434
- it('respects maxDepth of 5 when discovering projects', async () => {
435
- // Create bsconfig.json files at different depths
436
- writeTestFiles({
437
- 'bsconfig.json': '',
438
- 'level1/bsconfig.json': '',
439
- 'level1/level2/bsconfig.json': '',
440
- 'level1/level2/level3/bsconfig.json': '',
441
- 'level1/level2/level3/level4/bsconfig.json': '',
442
- 'level1/level2/level3/level4/level5/bsconfig.json': '',
443
- 'level1/level2/level3/level4/level5/level6/bsconfig.json': ''
444
- });
445
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 5 }) })]);
446
- // maxDepth: 5 should find files at depths 0, 1, 2, 3, 4
447
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
448
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`,
449
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/bsconfig.json`,
450
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/bsconfig.json`,
451
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/bsconfig.json`,
452
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/bsconfig.json`
453
- ]);
454
- });
455
- it('respects maxDepth of 20 when discovering projects', async () => {
456
- // Create bsconfig.json files at different depths, skipping some levels in between
457
- // and proving it stops at level 20 by creating files at level 20 and 21
458
- // Note: depth 20 means the file is in the 20th directory level from root
459
- writeTestFiles({
460
- 'bsconfig.json': '',
461
- 'level1/bsconfig.json': '',
462
- 'level1/level2/level3/level4/level5/bsconfig.json': '',
463
- 'level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/level15/level16/level17/level18/level19/bsconfig.json': '',
464
- 'level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/level15/level16/level17/level18/level19/level20/bsconfig.json': ''
465
- });
466
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 20 }) })]);
467
- // maxDepth: 20 should find file at level 19 (depth 20) but not at level 20 (depth 21)
468
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
469
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`,
470
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/bsconfig.json`,
471
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/level5/bsconfig.json`,
472
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/level15/level16/level17/level18/level19/bsconfig.json`
473
- ]);
474
- });
475
- it('uses default maxDepth of 15 when no maxDepth is specified', async () => {
476
- // Create bsconfig.json files at different depths, skipping some levels in between
477
- // and proving it stops at level 15 by creating files at level 15 and 16
478
- // Note: depth 15 means the file is in the 15th directory level from root
479
- writeTestFiles({
480
- 'bsconfig.json': '',
481
- 'level1/bsconfig.json': '',
482
- 'level1/level2/level3/level4/level5/bsconfig.json': '',
483
- 'level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/bsconfig.json': '',
484
- 'level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/level15/bsconfig.json': ''
485
- });
486
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
487
- // Default maxDepth: 15 should find file at level 14 (depth 15) but not at level 15 (depth 16)
488
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
489
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`,
490
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/bsconfig.json`,
491
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/level5/bsconfig.json`,
492
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/bsconfig.json`
493
- ]);
494
- });
495
- it('respects maxDepth of 1 when discovering roku projects with manifest files', async () => {
496
- // Create manifest files at different depths
497
- writeTestFiles({
498
- 'manifest': '',
499
- 'source/main.brs': '',
500
- 'level1/manifest': '',
501
- 'level1/source/main.brs': '',
502
- 'level1/level2/manifest': '',
503
- 'level1/level2/source/main.brs': '',
504
- 'level1/level2/level3/manifest': '',
505
- 'level1/level2/level3/source/main.brs': ''
506
- });
507
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 1 }) })]);
508
- // maxDepth: 1 should find projects at depth 0 only
509
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
510
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
511
- ]);
512
- });
513
- it('respects maxDepth of 5 when discovering roku projects with manifest files', async () => {
514
- // Create manifest files at different depths
515
- writeTestFiles({
516
- 'manifest': '',
517
- 'source/main.brs': '',
518
- 'level1/manifest': '',
519
- 'level1/source/main.brs': '',
520
- 'level1/level2/manifest': '',
521
- 'level1/level2/source/main.brs': '',
522
- 'level1/level2/level3/manifest': '',
523
- 'level1/level2/level3/source/main.brs': '',
524
- 'level1/level2/level3/level4/manifest': '',
525
- 'level1/level2/level3/level4/source/main.brs': '',
526
- 'level1/level2/level3/level4/level5/manifest': '',
527
- 'level1/level2/level3/level4/level5/source/main.brs': '',
528
- 'level1/level2/level3/level4/level5/level6/manifest': '',
529
- 'level1/level2/level3/level4/level5/level6/source/main.brs': ''
530
- });
531
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 5 }) })]);
532
- // maxDepth: 5 should find projects at depths 0, 1, 2, 3, 4
533
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
534
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`,
535
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1`,
536
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2`,
537
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3`,
538
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4`
539
- ]);
540
- });
541
- });
542
- describe('getCompletions', () => {
543
- it('works for quick file changes', async () => {
544
- //set up the project
545
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
546
- //add the namespace first
547
- await setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/alpha.bs`, `
548
- namespace alpha
549
- enum Direction
550
- up
551
- end enum
552
- end namespace
553
- `);
554
- //add the baseline file
555
- await setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`, `
556
- sub test()
557
- thing = alpha.Directio
558
- end sub
559
- `);
560
- await manager.onIdle();
561
- //now for the test. type a char, request completions, type a char, request completions (just like how vscode does it)
562
- void setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`, `
563
- sub test()
564
- thing = alpha.Direction
565
- end sub
566
- `);
567
- // const completionsPromise1 = manager.getCompletions({
568
- // srcPath: s`${rootDir}/source/main.bs`,
569
- // position: util.createPosition(2, 43)
570
- // });
571
- //request completions
572
- void setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`, `
573
- sub test()
574
- thing = alpha.Direction.
575
- end sub
576
- `);
577
- const completionsPromise2 = manager.getCompletions({
578
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`,
579
- position: util_1.default.createPosition(2, 44)
580
- });
581
- // //the first set of completions should only have the `alpha.Direction` enum
582
- // expectCompletionsIncludes(await completionsPromise1, [{
583
- // label: 'Direction'
584
- // }]);
585
- //the next set of completions should only have the alpha.Direction.up enum member
586
- (0, testHelpers_spec_1.expectCompletionsIncludes)(await completionsPromise2, [{
587
- label: 'up'
588
- }]);
589
- });
590
- });
591
- describe('getFileRenameEdits', () => {
592
- const mainUri = util_1.default.pathToUri((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`);
593
- function fakeProject(getFileRenameEdits) {
594
- return {
595
- projectNumber: 0,
596
- whenActivated: () => Promise.resolve(),
597
- getFileRenameEdits: getFileRenameEdits
598
- };
599
- }
600
- function fileRenameEdit(uri, newText, range = util_1.default.createRange(0, 8, 0, 14)) {
601
- return { uri: uri, range: range, newText: newText };
602
- }
603
- beforeEach(() => {
604
- //these tests exercise the cross-project consensus logic; bypass the project-sync wait so we don't need a real project setup
605
- sinon.stub(manager, 'onIdle').callsFake(() => Promise.resolve());
606
- });
607
- it('passes through edits from a single project', async () => {
608
- manager.projects = [
609
- fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')])
610
- ];
611
- const result = await manager.getFileRenameEdits({
612
- oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
613
- newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
614
- });
615
- (0, chai_1.expect)(result).to.have.lengthOf(1);
616
- (0, chai_1.expect)(result[0].uri).to.eql(mainUri);
617
- (0, chai_1.expect)(result[0].newText).to.eql('lib2.bs');
618
- });
619
- it('keeps edits when every project that produced an edit at the same range agrees', async () => {
620
- manager.projects = [
621
- fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')]),
622
- fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')])
623
- ];
624
- const result = await manager.getFileRenameEdits({
625
- oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
626
- newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
627
- });
628
- (0, chai_1.expect)(result).to.have.lengthOf(1);
629
- (0, chai_1.expect)(result[0].newText).to.eql('lib2.bs');
630
- });
631
- it('drops edits when projects disagree on the replacement text for the same range', async () => {
632
- manager.projects = [
633
- fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')]),
634
- fakeProject(() => [fileRenameEdit(mainUri, 'pkg:/source/lib2.bs')])
635
- ];
636
- const result = await manager.getFileRenameEdits({
637
- oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
638
- newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
639
- });
640
- (0, chai_1.expect)(result).to.be.empty;
641
- });
642
- it('keeps edits unique to one project when others have nothing to say at that range', async () => {
643
- manager.projects = [
644
- fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')]),
645
- fakeProject(() => [])
646
- ];
647
- const result = await manager.getFileRenameEdits({
648
- oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
649
- newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
650
- });
651
- (0, chai_1.expect)(result).to.have.lengthOf(1);
652
- });
653
- it('still emits edits from healthy projects when one project throws', async () => {
654
- manager.projects = [
655
- fakeProject(() => {
656
- throw new Error('boom');
657
- }),
658
- fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')])
659
- ];
660
- const result = await manager.getFileRenameEdits({
661
- oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
662
- newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
663
- });
664
- (0, chai_1.expect)(result).to.have.lengthOf(1);
665
- (0, chai_1.expect)(result[0].newText).to.eql('lib2.bs');
666
- });
667
- });
668
- describe('flushDocumentChanges', () => {
669
- it('reuses cached PathCollection across multiple flushes', async () => {
670
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, ``);
671
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {});
672
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
673
- //spy on PathCollection constructor to count how many are created
674
- const project = manager.projects[0];
675
- //first flush to warm the cache
676
- await manager['flushDocumentChanges']({
677
- actions: [{
678
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
679
- type: 'set',
680
- fileContents: 'sub main():end sub',
681
- allowStandaloneProject: true
682
- }]
683
- });
684
- //grab the cached filterer
685
- const cachedFilterer = manager['projectFiltererCache'].get(project);
686
- (0, chai_1.expect)(cachedFilterer).to.exist;
687
- //second flush should reuse the same filterer instance
688
- await manager['flushDocumentChanges']({
689
- actions: [{
690
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
691
- type: 'set',
692
- fileContents: 'sub main2():end sub',
693
- allowStandaloneProject: true
694
- }]
695
- });
696
- const cachedFilterer2 = manager['projectFiltererCache'].get(project);
697
- (0, chai_1.expect)(cachedFilterer2).to.equal(cachedFilterer);
698
- });
699
- it('does not crash when getting undefined back from projects', async () => {
700
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, ``);
701
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, {
702
- rootDir: testHelpers_spec_1.rootDir
703
- });
704
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
705
- sinon.stub(manager.projects[0], 'applyFileChanges').returns(Promise.resolve([
706
- //return an undefined item, which used to cause a specific crash
707
- undefined
708
- ]));
709
- await manager['flushDocumentChanges']({
710
- actions: [{
711
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
712
- type: 'set',
713
- fileContents: 'sub main():end sub',
714
- allowStandaloneProject: true
715
- }]
716
- });
717
- });
718
- });
719
- describe('handleFileChanges', () => {
720
- it('only sends files to the project that match the include patterns for that project', async () => {
721
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib1/a.brs`, ``);
722
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib2/a.brs`, ``);
723
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib1/b.brs`, ``);
724
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib2/b.brs`, ``);
725
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, {
726
- rootDir: testHelpers_spec_1.rootDir,
727
- files: [
728
- 'source/**/a.brs'
729
- ]
730
- });
731
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/project2/bsconfig.json`, {
732
- rootDir: testHelpers_spec_1.rootDir,
733
- files: [
734
- 'source/**/b.brs'
735
- ]
736
- });
737
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
738
- let deferred1 = new deferred_1.Deferred();
739
- let deferred2 = new deferred_1.Deferred();
740
- const project1 = manager.projects.find(x => x.bsconfigPath.includes('project1'));
741
- const project2 = manager.projects.find(x => x.bsconfigPath.includes('project2'));
742
- const project1Stub = sinon.stub(project1, 'applyFileChanges').callsFake(async (...args) => {
743
- const result = await project1Stub.wrappedMethod.apply(project1, args);
744
- deferred1.resolve();
745
- return result;
746
- });
747
- const project2Stub = sinon.stub(project2, 'applyFileChanges').callsFake(async (...args) => {
748
- const result = await project2Stub.wrappedMethod.apply(project1, args);
749
- deferred2.resolve();
750
- return result;
751
- });
752
- await manager.handleFileChanges([
753
- { srcPath: `${testHelpers_spec_1.rootDir}/source/lib1/a.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
754
- { srcPath: `${testHelpers_spec_1.rootDir}/source/lib2/a.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
755
- { srcPath: `${testHelpers_spec_1.rootDir}/source/lib1/b.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
756
- { srcPath: `${testHelpers_spec_1.rootDir}/source/lib2/b.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
757
- ]);
758
- //wait for the functions to finish being called
759
- await Promise.all([
760
- deferred1.promise,
761
- deferred2.promise
762
- ]);
763
- //project1 should only receive a.brs files
764
- (0, chai_1.expect)(project1Stub.getCall(0).args[0].map(x => x.srcPath)).to.eql([
765
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib1/a.brs`,
766
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2/a.brs`
767
- ]);
768
- //project2 should only receive b.brs files
769
- (0, chai_1.expect)(project2Stub.getCall(0).args[0].map(x => x.srcPath)).to.eql([
770
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib1/b.brs`,
771
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2/b.brs`
772
- ]);
773
- });
774
- it('excludes files based on global exclude patterns', async () => {
775
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file1.md`, ``);
776
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file2.brs`, ``);
777
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
778
- files: [
779
- 'source/**/*.brs'
780
- ]
781
- });
782
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
783
- const stub = sinon.stub(manager, 'handleFileChange').callThrough();
784
- //register an exclusion filter
785
- pathFilterer.registerExcludeList(testHelpers_spec_1.rootDir, [
786
- '**/*.md'
787
- ]);
788
- //make sure the .md file is ignored
789
- await manager.handleFileChanges([
790
- { srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
791
- { srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
792
- ]);
793
- await manager.onIdle();
794
- (0, chai_1.expect)(stub.getCalls().map(x => x.args[0]).map(x => x.srcPath)).to.eql([
795
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`
796
- ]);
797
- stub.reset();
798
- //remove all filters, make sure the markdown file is included
799
- pathFilterer.clear();
800
- await manager.handleFileChanges([
801
- { srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
802
- { srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
803
- ]);
804
- await manager.onIdle();
805
- (0, chai_1.expect)(stub.getCalls().flatMap(x => x.args[0]).map(x => x.srcPath)).to.eql([
806
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`,
807
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`
808
- ]);
809
- });
810
- it('keeps files from bsconfig.json even if the path matches an exclude list', async () => {
811
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file1.md`, ``);
812
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file2.brs`, ``);
813
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
814
- files: ['source/**/*']
815
- });
816
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
817
- const stub = sinon.stub(manager['projects'][0], 'applyFileChanges').callThrough();
818
- //register an exclusion filter
819
- pathFilterer.registerExcludeList(testHelpers_spec_1.rootDir, [
820
- '**/*.md'
821
- ]);
822
- //make sure the .md file is included because of its project's files array
823
- await manager.handleFileChanges([
824
- { srcPath: `${testHelpers_spec_1.rootDir}/source/file1.md`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
825
- { srcPath: `${testHelpers_spec_1.rootDir}/source/file2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
826
- ]);
827
- await manager.onIdle();
828
- (0, chai_1.expect)(stub.getCalls().flatMap(x => x.args[0]).map(x => x.srcPath)).to.eql([
829
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`,
830
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`
831
- ]);
832
- });
833
- it('does not create a standalone project for files that exist in a known project', async () => {
834
- fsExtra.outputFileSync((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`, `sub main() : end sub`);
835
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
836
- await onNextDiagnostics();
837
- await manager.handleFileChanges([
838
- { srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed, fileContents: `'test`, allowStandaloneProject: true }
839
- ]);
840
- await onNextDiagnostics();
841
- //there should NOT be a standalone project
842
- (0, chai_1.expect)(manager['standaloneProjects'].size).to.eql(0);
843
- });
844
- it('converts a missing file to a delete', async () => {
845
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
846
- await onNextDiagnostics();
847
- let applyFileChangesDeferred = new deferred_1.Deferred();
848
- const project1 = manager.projects[0];
849
- const project1Stub = sinon.stub(project1, 'applyFileChanges').callsFake(async (...args) => {
850
- const result = await project1Stub.wrappedMethod.apply(project1, args);
851
- applyFileChangesDeferred.resolve(result);
852
- return result;
853
- });
854
- //emit created and changed events for files that don't exist. These turn into delete events
855
- await manager.handleFileChanges([
856
- { srcPath: `${testHelpers_spec_1.rootDir}/source/missing1.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
857
- { srcPath: `${testHelpers_spec_1.rootDir}/source/missing2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
858
- ]);
859
- //wait for the next set of diagnostics to arrive (signifying the files have been applied)
860
- const result = await applyFileChangesDeferred.promise;
861
- //make sure the project has these files
862
- (0, chai_1.expect)(result.map(x => {
863
- return { type: x.type, srcPath: x.srcPath };
864
- })).to.eql([{
865
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing1.brs`,
866
- type: 'set'
867
- }, {
868
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing2.brs`,
869
- type: 'set'
870
- }, {
871
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing1.brs`,
872
- type: 'delete'
873
- }, {
874
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing2.brs`,
875
- type: 'delete'
876
- }]);
877
- });
878
- it('properly syncs changes', async () => {
879
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib1.brs`, `sub test1():print "alpha":end sub`);
880
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib2.brs`, `sub test2():print "beta":end sub`);
881
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
882
- (0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
883
- await manager.handleFileChanges([
884
- { srcPath: `${testHelpers_spec_1.rootDir}/source/lib1.brs`, fileContents: `sub test1():print alpha:end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
885
- { srcPath: `${testHelpers_spec_1.rootDir}/source/lib2.brs`, fileContents: `sub test2()::print beta:end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
886
- ]);
887
- (0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
888
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('alpha').message,
889
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('beta').message
890
- ]);
891
- await manager.handleFileChanges([
892
- { srcPath: `${testHelpers_spec_1.rootDir}/source/lib1.brs`, fileContents: `sub test1():print "alpha":end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
893
- { srcPath: `${testHelpers_spec_1.rootDir}/source/lib2.brs`, fileContents: `sub test2()::print "beta":end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
894
- ]);
895
- (0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
896
- });
897
- it('adds all new files in a folder', async () => {
898
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `sub main():print "main":end sub`);
899
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
900
- (0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
901
- //add a few files to a folder, then register that folder as an "add"
902
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/beta.brs`, `sub beta(): print one: end sub`);
903
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/charlie/delta.brs`, `sub delta():print two:end sub`);
904
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/echo/foxtrot.brs`, `sub foxtrot():print three:end sub`);
905
- await manager.handleFileChanges([
906
- //register the entire folder as an "add"
907
- { srcPath: `${testHelpers_spec_1.rootDir}/source/libs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
908
- ]);
909
- (0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
910
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('one').message,
911
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('two').message,
912
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('three').message
913
- ]);
914
- });
915
- it('removes all files in a folder', async () => {
916
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `sub main():print "main":end sub`);
917
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/beta.brs`, `sub beta(): print one: end sub`);
918
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/charlie/delta.brs`, `sub delta():print two:end sub`);
919
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/echo/foxtrot.brs`, `sub foxtrot():print three:end sub`);
920
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
921
- (0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
922
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('one').message,
923
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('two').message,
924
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('three').message
925
- ]);
926
- await manager.handleFileChanges([
927
- //register the entire folder as an "add"
928
- { srcPath: `${testHelpers_spec_1.rootDir}/source/libs`, type: vscode_languageserver_protocol_1.FileChangeType.Deleted }
929
- ]);
930
- (0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
931
- });
932
- });
933
- describe('threading', () => {
934
- before(async function workerThreadWarmup() {
935
- this.timeout(60000);
936
- await (0, WorkerThreadProject_spec_1.getWakeWorkerThreadPromise)();
937
- });
938
- it('spawns a worker thread when threading is enabled', async () => {
939
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { enableThreading: true }) })]);
940
- (0, chai_1.expect)(manager.projects[0]).instanceof(WorkerThreadProject_1.WorkerThreadProject);
941
- });
942
- });
943
- describe('getProject', () => {
944
- it('uses .projectKey if param is not a string', async () => {
945
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
946
- (0, chai_1.expect)(manager['getProject']({
947
- projectKey: testHelpers_spec_1.rootDir
948
- }).projectKey).to.eql(testHelpers_spec_1.rootDir);
949
- });
950
- });
951
- describe('createAndActivateProject', () => {
952
- it('skips creating project if we already have it', async () => {
953
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
954
- await manager['createAndActivateProject']({
955
- projectKey: testHelpers_spec_1.rootDir,
956
- projectDir: testHelpers_spec_1.rootDir,
957
- workspaceFolder: testHelpers_spec_1.rootDir,
958
- bsconfigPath: undefined
959
- });
960
- (0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
961
- (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
962
- ]);
963
- });
964
- it('uses given projectNumber', async () => {
965
- await manager['createAndActivateProject']({
966
- projectKey: testHelpers_spec_1.rootDir,
967
- projectDir: testHelpers_spec_1.rootDir,
968
- workspaceFolder: testHelpers_spec_1.rootDir,
969
- bsconfigPath: undefined,
970
- projectNumber: 3
971
- });
972
- (0, chai_1.expect)(manager.projects[0].projectNumber).to.eql(3);
973
- });
974
- it('properly tracks a failed run', async () => {
975
- //force a total crash
976
- sinon.stub(Project_1.Project.prototype, 'activate').returns(Promise.reject(new Error('Critical failure')));
977
- let error;
978
- try {
979
- await manager['createAndActivateProject']({
980
- projectKey: testHelpers_spec_1.rootDir,
981
- projectDir: testHelpers_spec_1.rootDir,
982
- workspaceFolder: testHelpers_spec_1.rootDir,
983
- bsconfigPath: 'subdir1/brsconfig.json'
984
- });
985
- }
986
- catch (e) {
987
- error = e;
988
- }
989
- (0, chai_1.expect)(error).to.include({ message: 'Critical failure' });
990
- });
991
- });
992
- describe('removeProject', () => {
993
- it('handles undefined', async () => {
994
- manager['removeProject'](undefined);
995
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
996
- manager['removeProject'](undefined);
997
- });
998
- it('does not crash when removing project that is not there', () => {
999
- manager['removeProject']({
1000
- projectPath: testHelpers_spec_1.rootDir,
1001
- dispose: () => { }
1002
- });
1003
- });
1004
- });
1005
- describe('getSemanticTokens', () => {
1006
- it('waits until the project is ready', () => {
1007
- });
1008
- });
1009
- describe('standalone projects', () => {
1010
- it('creates a standalone project for files not found in a project', async () => {
1011
- var _a;
1012
- await manager.syncProjects([]);
1013
- await manager.handleFileChanges([{
1014
- srcPath: `${testHelpers_spec_1.rootDir}/source/main.brs`,
1015
- type: vscode_languageserver_protocol_1.FileChangeType.Created,
1016
- fileContents: `sub main():print "main":end sub`,
1017
- allowStandaloneProject: true
1018
- }]);
1019
- await onNextDiagnostics();
1020
- (0, chai_1.expect)((_a = [...manager['standaloneProjects'].values()][0]) === null || _a === void 0 ? void 0 : _a.srcPath).to.eql((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`);
1021
- //it deletes the standalone project when the file is closed
1022
- await manager.handleFileClose({
1023
- srcPath: `${testHelpers_spec_1.rootDir}/source/main.brs`
1024
- });
1025
- (0, chai_1.expect)(manager['standaloneProjects'].size).to.eql(0);
1026
- });
1027
- });
1028
- it('completes promise when project is disposed in the middle of a flow', async function () {
1029
- this.timeout(20000);
1030
- //small plugin to communicate over a socket inside the worker thread.
1031
- //This transpiles from tsc use `require()` for all imports and don't reference external vars
1032
- class Plugin {
1033
- constructor(port, host) {
1034
- this.deferred = this.defer();
1035
- // eslint-disable-next-line
1036
- const net = require('net');
1037
- console.log('Starting server');
1038
- this.server = net.createServer((socket) => {
1039
- console.log('Client connected');
1040
- socket.on('data', (data) => {
1041
- let text = data.toString();
1042
- console.log('message received', JSON.stringify(text));
1043
- //when we get the event to resolve, do it
1044
- if (text === 'resolve') {
1045
- console.log('Resolving promise');
1046
- this.deferred.resolve();
1047
- this.server.close();
1048
- }
1049
- });
1050
- });
1051
- this.server.listen(port, host);
1052
- }
1053
- afterProgramCreate(program) {
1054
- // hijack the function to get workspace symbols, return a promise that resolves in the future
1055
- program.getWorkspaceSymbols = () => {
1056
- return this.deferred.promise;
1057
- };
1058
- }
1059
- defer() {
1060
- let resolve;
1061
- let reject;
1062
- let promise = new Promise((res, rej) => {
1063
- resolve = res;
1064
- reject = rej;
1065
- });
1066
- return {
1067
- resolve: resolve,
1068
- reject: reject,
1069
- promise: promise
1070
- };
1071
- }
1072
- }
1073
- const port = await getPort();
1074
- const host = '127.0.0.1';
1075
- //write a small brighterscript plugin to allow this test to communicate with the thread
1076
- fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/pluginsocket.js`, `
1077
- ${Plugin.toString()};
1078
- exports.default = function() {
1079
- return new Plugin(${port}, "${host}");
1080
- };
1081
- `);
1082
- //write a bsconfig that will load this plugin
1083
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
1084
- plugins: [
1085
- `${testHelpers_spec_1.rootDir}/pluginsocket.js`
1086
- ]
1087
- });
1088
- //wait for the projects to finish syncing/loading
1089
- await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { enableThreading: true }) })]);
1090
- //establish the connection with the plugin
1091
- const connection = net.createConnection({
1092
- host: host,
1093
- port: port
1094
- });
1095
- //do the request to fetch symbols (this will be stalled on purpose by our test plugin)
1096
- let managerGetWorkspaceSymbolPromise = manager.getWorkspaceSymbol();
1097
- //small sleep to let things settle
1098
- await util_1.default.sleep(20);
1099
- //now dispose the project (which should destroy all of the listeners)
1100
- manager['removeProject'](manager.projects[0]);
1101
- //settle again
1102
- await util_1.default.sleep(20);
1103
- console.log('Asking the client to resolve');
1104
- //resolve the request
1105
- connection.write('resolve');
1106
- //now wait to see if we ever get the response back
1107
- let result = await managerGetWorkspaceSymbolPromise;
1108
- //the result should be an empty array, since the only project was rejected in the middle of the request
1109
- (0, chai_1.expect)(result).to.eql([]);
1110
- //test passes if the promise resolves
1111
- });
1112
- it('properly handles reloading when bsconfig.json contents change', async () => {
1113
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
1114
- files: [
1115
- 'one'
1116
- ]
1117
- });
1118
- //wait for the projects to finish syncing/loading
1119
- await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
1120
- const stub = sinon.stub(manager, 'reloadProject').callThrough();
1121
- //change the file to new contents
1122
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
1123
- files: [
1124
- 'two'
1125
- ]
1126
- });
1127
- await manager.handleFileChanges([{
1128
- srcPath: `${testHelpers_spec_1.rootDir}/bsconfig.json`,
1129
- type: vscode_languageserver_protocol_1.FileChangeType.Changed
1130
- }]);
1131
- //the project was reloaded
1132
- (0, chai_1.expect)(stub.callCount).to.eql(1);
1133
- //change the file to the same contents
1134
- fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
1135
- files: [
1136
- 'two'
1137
- ]
1138
- });
1139
- await manager.handleFileChanges([{
1140
- srcPath: `${testHelpers_spec_1.rootDir}/bsconfig.json`,
1141
- type: vscode_languageserver_protocol_1.FileChangeType.Changed
1142
- }]);
1143
- //the project was not reloaded this time
1144
- (0, chai_1.expect)(stub.callCount).to.eql(1);
1145
- });
1146
- });
1147
- //# sourceMappingURL=ProjectManager.spec.js.map