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
@@ -5,20 +5,14 @@ const vscode_uri_1 = require("vscode-uri");
5
5
  const reflection_1 = require("../../astUtils/reflection");
6
6
  const Cache_1 = require("../../Cache");
7
7
  const DiagnosticMessages_1 = require("../../DiagnosticMessages");
8
- const interfaces_1 = require("../../interfaces");
9
- const SymbolTable_1 = require("../../SymbolTable");
10
8
  const util_1 = require("../../util");
11
9
  const roku_types_1 = require("../../roku-types");
12
- const Expression_1 = require("../../parser/Expression");
13
- const visitors_1 = require("../../astUtils/visitors");
14
- const AstValidationSegmenter_1 = require("../../AstValidationSegmenter");
15
- const TokenKind_1 = require("../../lexer/TokenKind");
10
+ const Parser_1 = require("../../parser/Parser");
16
11
  /**
17
12
  * The lower-case names of all platform-included scenegraph nodes
18
13
  */
19
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
20
- const platformNodeNames = roku_types_1.nodes ? new Set(Object.values(roku_types_1.nodes).map(x => x === null || x === void 0 ? void 0 : x.name.toLowerCase())) : new Set();
21
- const platformComponentNames = roku_types_1.components ? new Set(Object.values(roku_types_1.components).map(x => x === null || x === void 0 ? void 0 : x.name.toLowerCase())) : new Set();
14
+ const platformNodeNames = new Set(Object.values(roku_types_1.nodes).map(x => x.name.toLowerCase()));
15
+ const platformComponentNames = new Set(Object.values(roku_types_1.components).map(x => x.name.toLowerCase()));
22
16
  /**
23
17
  * A validator that handles all scope validations for a program validation cycle.
24
18
  * You should create ONE of these to handle all scope events between beforeProgramValidate and afterProgramValidate,
@@ -26,14 +20,12 @@ const platformComponentNames = roku_types_1.components ? new Set(Object.values(r
26
20
  */
27
21
  class ScopeValidator {
28
22
  constructor() {
23
+ this.expressionsByFile = new Cache_1.Cache();
29
24
  this.onceCache = new Cache_1.Cache();
30
25
  this.multiScopeCache = new Cache_1.Cache();
31
26
  }
32
27
  processEvent(event) {
33
28
  this.event = event;
34
- if (this.event.program.globalScope === this.event.scope) {
35
- return;
36
- }
37
29
  this.walkFiles();
38
30
  this.detectDuplicateEnums();
39
31
  }
@@ -45,82 +37,123 @@ class ScopeValidator {
45
37
  walkFiles() {
46
38
  this.event.scope.enumerateOwnFiles((file) => {
47
39
  if ((0, reflection_1.isBrsFile)(file)) {
48
- const hasChangeInfo = this.event.changedFiles && this.event.changedSymbols;
49
- let thisFileRequiresChangedSymbol = false;
50
- for (let requiredSymbol of file.requiredSymbols) {
51
- const changeSymbolSetForFlag = this.event.changedSymbols.get(requiredSymbol.flags);
52
- if (util_1.default.setContainsUnresolvedSymbol(changeSymbolSetForFlag, requiredSymbol)) {
53
- thisFileRequiresChangedSymbol = true;
54
- }
40
+ this.iterateFileExpressions(file);
41
+ this.validateCreateObjectCalls(file);
42
+ }
43
+ });
44
+ }
45
+ iterateFileExpressions(file) {
46
+ var _a, _b, _c, _d, _e;
47
+ const { scope } = this.event;
48
+ //build an expression collection ONCE per file
49
+ const expressionInfos = this.expressionsByFile.getOrAdd(file, () => {
50
+ var _a, _b;
51
+ const result = [];
52
+ const expressions = [
53
+ ...file.parser.references.expressions,
54
+ //all class "extends <whatever>" expressions
55
+ ...file.parser.references.classStatements.map(x => { var _a; return (_a = x.parentClassName) === null || _a === void 0 ? void 0 : _a.expression; }),
56
+ //all interface "extends <whatever>" expressions
57
+ ...file.parser.references.interfaceStatements.map(x => { var _a; return (_a = x.parentInterfaceName) === null || _a === void 0 ? void 0 : _a.expression; })
58
+ ];
59
+ for (let expression of expressions) {
60
+ if (!expression) {
61
+ continue;
55
62
  }
56
- const thisFileHasChanges = this.event.changedFiles.includes(file);
57
- if (hasChangeInfo && !thisFileRequiresChangedSymbol && !thisFileHasChanges) {
58
- // this file does not require a symbol that has changed, and this file has not changed
59
- return;
63
+ //walk left-to-right on every expression, only keep the ones that start with VariableExpression, and then keep subsequent DottedGet parts
64
+ const parts = util_1.default.getDottedGetPath(expression);
65
+ if (parts.length > 0) {
66
+ result.push({
67
+ parts: parts,
68
+ expression: expression,
69
+ enclosingNamespaceNameLower: (_b = (_a = expression.findAncestor(reflection_1.isNamespaceStatement)) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript)) === null || _b === void 0 ? void 0 : _b.toLowerCase()
70
+ });
60
71
  }
61
- if (thisFileHasChanges) {
62
- this.event.scope.clearAstSegmentDiagnosticsByFile(file);
72
+ }
73
+ return result;
74
+ });
75
+ outer: for (const info of expressionInfos) {
76
+ const symbolTable = info.expression.getSymbolTable();
77
+ const firstPart = info.parts[0];
78
+ const firstNamespacePart = info.parts[0].name.text;
79
+ const firstNamespacePartLower = firstNamespacePart === null || firstNamespacePart === void 0 ? void 0 : firstNamespacePart.toLowerCase();
80
+ //get the namespace container (accounting for namespace-relative as well)
81
+ const namespaceContainer = scope.getNamespace(firstNamespacePartLower, info.enclosingNamespaceNameLower);
82
+ //flag all unknown left-most variables
83
+ if (!(symbolTable === null || symbolTable === void 0 ? void 0 : symbolTable.hasSymbol((_a = firstPart.name) === null || _a === void 0 ? void 0 : _a.text)) &&
84
+ !namespaceContainer) {
85
+ //flag functions differently than all other variables
86
+ if ((0, reflection_1.isCallExpression)(firstPart.parent) && firstPart.parent.callee === firstPart) {
87
+ this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindFunction((_b = firstPart.name) === null || _b === void 0 ? void 0 : _b.text)), { range: firstPart.name.range }));
88
+ }
89
+ else {
90
+ this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName((_c = firstPart.name) === null || _c === void 0 ? void 0 : _c.text)), { range: firstPart.name.range }));
91
+ }
92
+ //skip to the next expression
93
+ continue;
94
+ }
95
+ const enumStatement = scope.getEnum(firstNamespacePartLower, info.enclosingNamespaceNameLower);
96
+ //if this isn't a namespace, skip it
97
+ if (!namespaceContainer && !enumStatement) {
98
+ continue;
99
+ }
100
+ //catch unknown namespace items
101
+ let entityName = firstNamespacePart;
102
+ let entityNameLower = firstNamespacePart.toLowerCase();
103
+ for (let i = 1; i < info.parts.length; i++) {
104
+ const part = info.parts[i];
105
+ entityName += '.' + part.name.text;
106
+ entityNameLower += '.' + part.name.text.toLowerCase();
107
+ //if this is an enum member, stop validating here to prevent errors further down the chain
108
+ if (scope.getEnumMemberFileLink(entityName, info.enclosingNamespaceNameLower)) {
109
+ break;
63
110
  }
64
- const validationVisitor = (0, visitors_1.createVisitor)({
65
- VariableExpression: (varExpr) => {
66
- this.validateVariableAndDottedGetExpressions(file, varExpr);
67
- },
68
- DottedGetExpression: (dottedGet) => {
69
- this.validateVariableAndDottedGetExpressions(file, dottedGet);
70
- },
71
- CallExpression: (functionCall) => {
72
- this.validateFunctionCall(file, functionCall);
73
- this.validateCreateObjectCall(file, functionCall);
74
- },
75
- ReturnStatement: (returnStatement) => {
76
- this.validateReturnStatement(file, returnStatement);
77
- },
78
- DottedSetStatement: (dottedSetStmt) => {
79
- this.validateDottedSetStatement(file, dottedSetStmt);
80
- },
81
- BinaryExpression: (binaryExpr) => {
82
- this.validateBinaryExpression(file, binaryExpr);
83
- },
84
- UnaryExpression: (unaryExpr) => {
85
- this.validateUnaryExpression(file, unaryExpr);
111
+ if (!scope.getEnumMap().has(entityNameLower) &&
112
+ !scope.getClassMap().has(entityNameLower) &&
113
+ !scope.getConstMap().has(entityNameLower) &&
114
+ !scope.getCallableByName(entityNameLower) &&
115
+ !scope.getNamespace(entityNameLower, info.enclosingNamespaceNameLower)) {
116
+ //if this looks like an enum, provide a nicer error message
117
+ const theEnum = (_d = this.getEnum(scope, entityNameLower)) === null || _d === void 0 ? void 0 : _d.item;
118
+ if (theEnum) {
119
+ this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownEnumValue((_e = part.name.text) === null || _e === void 0 ? void 0 : _e.split('.').pop(), theEnum.fullName)), { range: part.name.range, relatedInformation: [{
120
+ message: 'Enum declared here',
121
+ location: util_1.default.createLocation(vscode_uri_1.URI.file(file.srcPath).toString(), theEnum.tokens.name.range)
122
+ }] }));
86
123
  }
87
- });
88
- const segmentsToWalkForValidation = (thisFileHasChanges || !hasChangeInfo)
89
- ? file.validationSegmenter.segmentsForValidation // validate everything in the file
90
- : file.getValidationSegments(this.event.changedSymbols); // validate only what's needed in the file
91
- for (const segment of segmentsToWalkForValidation) {
92
- this.currentSegmentBeingValidated = segment;
93
- this.event.scope.clearAstSegmentDiagnostics(segment);
94
- segment.walk(validationVisitor, {
95
- walkMode: AstValidationSegmenter_1.InsideSegmentWalkMode
96
- });
97
- file.markSegmentAsValidated(segment);
124
+ else {
125
+ //flag functions differently than all other variables
126
+ if ((0, reflection_1.isCallExpression)(firstPart.parent) && firstPart.parent.callee === firstPart) {
127
+ this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotFindFunction(part.name.text, entityName)), { range: part.name.range, file: file }));
128
+ }
129
+ else {
130
+ this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(part.name.text, entityName)), { range: part.name.range, file: file }));
131
+ }
132
+ }
133
+ //no need to add another diagnostic for future unknown items
134
+ continue outer;
98
135
  }
99
136
  }
100
- });
101
- }
102
- isTypeKnown(exprType) {
103
- let isKnownType = exprType === null || exprType === void 0 ? void 0 : exprType.isResolvable();
104
- return isKnownType;
137
+ //if the full expression is a namespace path, this is an illegal statement because namespaces don't exist at runtme
138
+ if (scope.getNamespace(entityNameLower, info.enclosingNamespaceNameLower)) {
139
+ this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('namespace')), { range: info.expression.range, file: file }), 'When used in scope');
140
+ }
141
+ }
105
142
  }
106
143
  /**
107
- * If this is the lhs of an assignment, we don't need to flag it as unresolved
144
+ * Given a string optionally separated by dots, find an enum related to it.
145
+ * For example, all of these would return the enum: `SomeNamespace.SomeEnum.SomeMember`, SomeEnum.SomeMember, `SomeEnum`
108
146
  */
109
- ignoreUnresolvedAssignmentLHS(expression, exprType, definingNode) {
110
- var _a, _b;
111
- if (!(0, reflection_1.isVariableExpression)(expression)) {
112
- return false;
113
- }
114
- let assignmentAncestor;
115
- if ((0, reflection_1.isAssignmentStatement)(definingNode) && definingNode.equals.kind === TokenKind_1.TokenKind.Equal) {
116
- // this symbol was defined in a "normal" assignment (eg. not a compound assignment)
117
- assignmentAncestor = definingNode;
118
- return ((_a = assignmentAncestor === null || assignmentAncestor === void 0 ? void 0 : assignmentAncestor.name) === null || _a === void 0 ? void 0 : _a.text.toLowerCase()) === ((_b = expression === null || expression === void 0 ? void 0 : expression.name) === null || _b === void 0 ? void 0 : _b.text.toLowerCase());
119
- }
120
- else {
121
- assignmentAncestor = expression === null || expression === void 0 ? void 0 : expression.findAncestor(reflection_1.isAssignmentStatement);
122
- }
123
- return (assignmentAncestor === null || assignmentAncestor === void 0 ? void 0 : assignmentAncestor.name) === (expression === null || expression === void 0 ? void 0 : expression.name) && (0, reflection_1.isUnionType)(exprType);
147
+ getEnum(scope, name) {
148
+ //look for the enum directly
149
+ let result = scope.getEnumMap().get(name);
150
+ //assume we've been given the enum.member syntax, so pop the member and try again
151
+ if (!result) {
152
+ const parts = name.split('.');
153
+ parts.pop();
154
+ result = scope.getEnumMap().get(parts.join('.'));
155
+ }
156
+ return result;
124
157
  }
125
158
  /**
126
159
  * Flag duplicate enums
@@ -161,7 +194,7 @@ class ScopeValidator {
161
194
  diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateEnumDeclaration(this.event.scope.name, fullName)), { file: duplicateEnumInfo.file, range: duplicateEnumInfo.statement.tokens.name.range, relatedInformation: [{
162
195
  message: 'Enum declared here',
163
196
  location: util_1.default.createLocation(vscode_uri_1.URI.file(primaryEnum.file.srcPath).toString(), primaryEnum.statement.tokens.name.range)
164
- }], origin: interfaces_1.DiagnosticOrigin.Scope }));
197
+ }] }));
165
198
  }
166
199
  }
167
200
  this.event.scope.addDiagnostics(diagnostics);
@@ -172,288 +205,57 @@ class ScopeValidator {
172
205
  * what these calls are supposed to look like, and this is a very common thing for brs devs to do, so just
173
206
  * do this manually for now.
174
207
  */
175
- validateCreateObjectCall(file, call) {
176
- var _a, _b, _c, _d, _e, _f;
177
- //skip non CreateObject function calls
178
- const callName = (_a = util_1.default.getAllDottedGetPartsAsString(call.callee)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
179
- if (callName !== 'createobject' || !(0, reflection_1.isLiteralExpression)(call === null || call === void 0 ? void 0 : call.args[0])) {
180
- return;
181
- }
182
- const firstParamToken = (_b = call === null || call === void 0 ? void 0 : call.args[0]) === null || _b === void 0 ? void 0 : _b.token;
183
- const firstParamStringValue = (_c = firstParamToken === null || firstParamToken === void 0 ? void 0 : firstParamToken.text) === null || _c === void 0 ? void 0 : _c.replace(/"/g, '');
184
- //if this is a `createObject('roSGNode'` call, only support known sg node types
185
- if ((firstParamStringValue === null || firstParamStringValue === void 0 ? void 0 : firstParamStringValue.toLowerCase()) === 'rosgnode' && (0, reflection_1.isLiteralExpression)(call === null || call === void 0 ? void 0 : call.args[1])) {
186
- const componentName = (_d = call === null || call === void 0 ? void 0 : call.args[1]) === null || _d === void 0 ? void 0 : _d.token;
187
- //don't validate any components with a colon in their name (probably component libraries, but regular components can have them too).
188
- if ((_e = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _e === void 0 ? void 0 : _e.includes(':')) {
189
- return;
190
- }
191
- //add diagnostic for unknown components
192
- const unquotedComponentName = (_f = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _f === void 0 ? void 0 : _f.replace(/"/g, '');
193
- if (unquotedComponentName && !platformNodeNames.has(unquotedComponentName.toLowerCase()) && !this.event.program.getComponent(unquotedComponentName)) {
194
- this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownRoSGNode(unquotedComponentName)), { range: componentName.range }));
195
- }
196
- else if ((call === null || call === void 0 ? void 0 : call.args.length) !== 2) {
197
- // roSgNode should only ever have 2 args in `createObject`
198
- this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.mismatchCreateObjectArgumentCount(firstParamStringValue, [2], call === null || call === void 0 ? void 0 : call.args.length)), { range: call.range }));
199
- }
200
- }
201
- else if (!platformComponentNames.has(firstParamStringValue.toLowerCase())) {
202
- this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownBrightScriptComponent(firstParamStringValue)), { range: firstParamToken.range }));
203
- }
204
- else {
205
- // This is valid brightscript component
206
- // Test for invalid arg counts
207
- const brightScriptComponent = roku_types_1.components[firstParamStringValue.toLowerCase()];
208
- // Valid arg counts for createObject are 1+ number of args for constructor
209
- let validArgCounts = brightScriptComponent.constructors.map(cnstr => cnstr.params.length + 1);
210
- if (validArgCounts.length === 0) {
211
- // no constructors for this component, so createObject only takes 1 arg
212
- validArgCounts = [1];
213
- }
214
- if (!validArgCounts.includes(call === null || call === void 0 ? void 0 : call.args.length)) {
215
- // Incorrect number of arguments included in `createObject()`
216
- this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.mismatchCreateObjectArgumentCount(firstParamStringValue, validArgCounts, call === null || call === void 0 ? void 0 : call.args.length)), { range: call.range }));
217
- }
218
- // Test for deprecation
219
- if (brightScriptComponent.isDeprecated) {
220
- this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.deprecatedBrightScriptComponent(firstParamStringValue, brightScriptComponent.deprecatedDescription)), { range: call.range }));
208
+ validateCreateObjectCalls(file) {
209
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
210
+ const diagnostics = [];
211
+ for (const call of file.functionCalls) {
212
+ //skip non CreateObject function calls
213
+ if (((_a = call.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== 'createobject' || !(0, reflection_1.isLiteralExpression)((_b = call === null || call === void 0 ? void 0 : call.args[0]) === null || _b === void 0 ? void 0 : _b.expression)) {
214
+ continue;
221
215
  }
222
- }
223
- }
224
- /**
225
- * Detect calls to functions with the incorrect number of parameters, or wrong types of arguments
226
- */
227
- validateFunctionCall(file, expression) {
228
- var _a, _b;
229
- const getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
230
- let funcType = (_a = expression === null || expression === void 0 ? void 0 : expression.callee) === null || _a === void 0 ? void 0 : _a.getType(getTypeOptions);
231
- if ((funcType === null || funcType === void 0 ? void 0 : funcType.isResolvable()) && (0, reflection_1.isClassType)(funcType)) {
232
- // We're calling a class - get the constructor
233
- funcType = funcType.getMemberType('new', getTypeOptions);
234
- }
235
- if ((funcType === null || funcType === void 0 ? void 0 : funcType.isResolvable()) && (0, reflection_1.isTypedFunctionType)(funcType)) {
236
- //funcType.setName(expression.callee. .name);
237
- //get min/max parameter count for callable
238
- let minParams = 0;
239
- let maxParams = 0;
240
- for (let param of funcType.params) {
241
- maxParams++;
242
- //optional parameters must come last, so we can assume that minParams won't increase once we hit
243
- //the first isOptional
244
- if (param.isOptional !== true) {
245
- minParams++;
216
+ const firstParamToken = (_d = (_c = call === null || call === void 0 ? void 0 : call.args[0]) === null || _c === void 0 ? void 0 : _c.expression) === null || _d === void 0 ? void 0 : _d.token;
217
+ const firstParamStringValue = (_e = firstParamToken === null || firstParamToken === void 0 ? void 0 : firstParamToken.text) === null || _e === void 0 ? void 0 : _e.replace(/"/g, '');
218
+ //if this is a `createObject('roSGNode'` call, only support known sg node types
219
+ if ((firstParamStringValue === null || firstParamStringValue === void 0 ? void 0 : firstParamStringValue.toLowerCase()) === 'rosgnode' && (0, reflection_1.isLiteralExpression)((_f = call === null || call === void 0 ? void 0 : call.args[1]) === null || _f === void 0 ? void 0 : _f.expression)) {
220
+ const componentName = (_h = (_g = call === null || call === void 0 ? void 0 : call.args[1]) === null || _g === void 0 ? void 0 : _g.expression) === null || _h === void 0 ? void 0 : _h.token;
221
+ //don't validate any components with a colon in their name (probably component libraries, but regular components can have them too).
222
+ if ((_j = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _j === void 0 ? void 0 : _j.includes(':')) {
223
+ continue;
246
224
  }
247
- }
248
- if (funcType.isVariadic) {
249
- // function accepts variable number of arguments
250
- maxParams = Expression_1.CallExpression.MaximumArguments;
251
- }
252
- let expCallArgCount = expression.args.length;
253
- if (expCallArgCount > maxParams || expCallArgCount < minParams) {
254
- let minMaxParamsText = minParams === maxParams ? maxParams : `${minParams}-${maxParams}`;
255
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(minMaxParamsText, expCallArgCount)), { range: expression.callee.range,
256
- //TODO detect end of expression call
257
- file: file }));
258
- }
259
- let paramIndex = 0;
260
- for (let arg of expression.args) {
261
- const argType = arg.getType({ flags: SymbolTable_1.SymbolTypeFlag.runtime });
262
- const paramType = (_b = funcType.params[paramIndex]) === null || _b === void 0 ? void 0 : _b.type;
263
- if (!paramType) {
264
- // unable to find a paramType -- maybe there are more args than params
265
- break;
225
+ //add diagnostic for unknown components
226
+ const unquotedComponentName = (_k = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _k === void 0 ? void 0 : _k.replace(/"/g, '');
227
+ if (unquotedComponentName && !platformNodeNames.has(unquotedComponentName.toLowerCase()) && !this.event.program.getComponent(unquotedComponentName)) {
228
+ this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownRoSGNode(unquotedComponentName)), { range: componentName.range }));
266
229
  }
267
- const compatibilityData = {};
268
- if (!(paramType === null || paramType === void 0 ? void 0 : paramType.isTypeCompatible(argType, compatibilityData))) {
269
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch(argType.toString(), paramType.toString(), compatibilityData)), { range: arg.range,
270
- //TODO detect end of expression call
271
- file: file }));
230
+ else if ((call === null || call === void 0 ? void 0 : call.args.length) !== 2) {
231
+ // roSgNode should only ever have 2 args in `createObject`
232
+ this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.mismatchCreateObjectArgumentCount(firstParamStringValue, [2], call === null || call === void 0 ? void 0 : call.args.length)), { range: call.range }));
272
233
  }
273
- paramIndex++;
274
234
  }
275
- }
276
- }
277
- /**
278
- * Detect return statements with incompatible types vs. declared return type
279
- */
280
- validateReturnStatement(file, returnStmt) {
281
- var _a;
282
- const getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
283
- let funcType = returnStmt.findAncestor(reflection_1.isFunctionExpression).getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
284
- if ((0, reflection_1.isTypedFunctionType)(funcType)) {
285
- const actualReturnType = (_a = returnStmt.value) === null || _a === void 0 ? void 0 : _a.getType(getTypeOptions);
286
- const compatibilityData = {};
287
- if (actualReturnType && !funcType.returnType.isTypeCompatible(actualReturnType, compatibilityData)) {
288
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch(actualReturnType.toString(), funcType.returnType.toString(), compatibilityData)), { range: returnStmt.value.range, file: file }));
235
+ else if (!platformComponentNames.has(firstParamStringValue.toLowerCase())) {
236
+ this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownBrightScriptComponent(firstParamStringValue)), { range: firstParamToken.range }));
289
237
  }
290
- }
291
- }
292
- /**
293
- * Detect return statements with incompatible types vs. declared return type
294
- */
295
- validateDottedSetStatement(file, dottedSetStmt) {
296
- var _a, _b, _c;
297
- const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
298
- const expectedLHSType = (_b = (_a = dottedSetStmt === null || dottedSetStmt === void 0 ? void 0 : dottedSetStmt.obj) === null || _a === void 0 ? void 0 : _a.getType(getTypeOpts)) === null || _b === void 0 ? void 0 : _b.getMemberType(dottedSetStmt.name.text, getTypeOpts);
299
- const actualRHSType = (_c = dottedSetStmt === null || dottedSetStmt === void 0 ? void 0 : dottedSetStmt.value) === null || _c === void 0 ? void 0 : _c.getType(getTypeOpts);
300
- const compatibilityData = {};
301
- if ((expectedLHSType === null || expectedLHSType === void 0 ? void 0 : expectedLHSType.isResolvable()) && !(expectedLHSType === null || expectedLHSType === void 0 ? void 0 : expectedLHSType.isTypeCompatible(actualRHSType, compatibilityData))) {
302
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch(actualRHSType.toString(), expectedLHSType.toString(), compatibilityData)), { range: dottedSetStmt.range, file: file }));
303
- }
304
- }
305
- /**
306
- * Detect invalid use of a binary operator
307
- */
308
- validateBinaryExpression(file, binaryExpr) {
309
- const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
310
- if (util_1.default.isInTypeExpression(binaryExpr)) {
311
- return;
312
- }
313
- let leftType = binaryExpr.left.getType(getTypeOpts);
314
- let rightType = binaryExpr.right.getType(getTypeOpts);
315
- if (!leftType.isResolvable() || !rightType.isResolvable()) {
316
- // Can not find the type. error handled elsewhere
317
- return;
318
- }
319
- let leftTypeToTest = leftType;
320
- let rightTypeToTest = rightType;
321
- if ((0, reflection_1.isEnumMemberType)(leftType) || (0, reflection_1.isEnumType)(leftType)) {
322
- leftTypeToTest = leftType.underlyingType;
323
- }
324
- if ((0, reflection_1.isEnumMemberType)(rightType) || (0, reflection_1.isEnumType)(rightType)) {
325
- rightTypeToTest = rightType.underlyingType;
326
- }
327
- if ((0, reflection_1.isUnionType)(leftType) || (0, reflection_1.isUnionType)(rightType)) {
328
- // TODO: it is possible to validate based on innerTypes, but more complicated
329
- // Because you need to verify each combination of types
330
- return;
331
- }
332
- const leftIsPrimitive = (0, reflection_1.isPrimitiveType)(leftTypeToTest);
333
- const rightIsPrimitive = (0, reflection_1.isPrimitiveType)(rightTypeToTest);
334
- const leftIsAny = (0, reflection_1.isDynamicType)(leftTypeToTest) || (0, reflection_1.isObjectType)(leftTypeToTest);
335
- const rightIsAny = (0, reflection_1.isDynamicType)(rightTypeToTest) || (0, reflection_1.isObjectType)(rightTypeToTest);
336
- if (leftIsAny && rightIsAny) {
337
- // both operands are basically "any" type... ignore;
338
- return;
339
- }
340
- else if ((leftIsAny && rightIsPrimitive) || (leftIsPrimitive && rightIsAny)) {
341
- // one operand is basically "any" type... ignore;
342
- return;
343
- }
344
- const opResult = util_1.default.binaryOperatorResultType(leftTypeToTest, binaryExpr.operator, rightTypeToTest);
345
- if ((0, reflection_1.isDynamicType)(opResult)) {
346
- // if the result was dynamic, that means there wasn't a valid operation
347
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(binaryExpr.operator.text, leftType.toString(), rightType.toString())), { range: binaryExpr.range, file: file }));
348
- }
349
- }
350
- /**
351
- * Detect invalid use of a Unary operator
352
- */
353
- validateUnaryExpression(file, unaryExpr) {
354
- const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
355
- let rightType = unaryExpr.right.getType(getTypeOpts);
356
- if (!rightType.isResolvable()) {
357
- // Can not find the type. error handled elsewhere
358
- return;
359
- }
360
- let rightTypeToTest = rightType;
361
- if ((0, reflection_1.isEnumMemberType)(rightType)) {
362
- rightTypeToTest = rightType.underlyingType;
363
- }
364
- if ((0, reflection_1.isUnionType)(rightTypeToTest)) {
365
- // TODO: it is possible to validate based on innerTypes, but more complicated
366
- // Because you need to verify each combination of types
367
- }
368
- else if ((0, reflection_1.isDynamicType)(rightTypeToTest) || (0, reflection_1.isObjectType)(rightTypeToTest)) {
369
- // operand is basically "any" type... ignore;
370
- }
371
- else if ((0, reflection_1.isPrimitiveType)(rightType)) {
372
- const opResult = util_1.default.unaryOperatorResultType(unaryExpr.operator, rightTypeToTest);
373
- if ((0, reflection_1.isDynamicType)(opResult)) {
374
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(unaryExpr.operator.text, rightType.toString())), { range: unaryExpr.range, file: file }));
375
- }
376
- }
377
- else {
378
- // rhs is not a primitive, so no binary operator is allowed
379
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(unaryExpr.operator.text, rightType.toString())), { range: unaryExpr.range, file: file }));
380
- }
381
- }
382
- validateVariableAndDottedGetExpressions(file, expression) {
383
- var _a, _b;
384
- if ((0, reflection_1.isDottedGetExpression)(expression.parent)) {
385
- // We validate dottedGetExpressions at the top-most level
386
- return;
387
- }
388
- if ((0, reflection_1.isVariableExpression)(expression)) {
389
- if ((0, reflection_1.isAssignmentStatement)(expression.parent) && expression.parent.name === expression.name) {
390
- // Don't validate LHS of assignments
391
- return;
392
- }
393
- else if ((0, reflection_1.isNamespaceStatement)(expression.parent)) {
394
- return;
395
- }
396
- }
397
- let symbolType = SymbolTable_1.SymbolTypeFlag.runtime;
398
- let oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.typetime;
399
- const isUsedAsType = util_1.default.isInTypeExpression(expression);
400
- if (isUsedAsType) {
401
- // This is used in a TypeExpression - only look up types from SymbolTable
402
- symbolType = SymbolTable_1.SymbolTypeFlag.typetime;
403
- oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.runtime;
404
- }
405
- // Do a complete type check on all DottedGet and Variable expressions
406
- // this will create a diagnostic if an invalid member is accessed
407
- const typeChain = [];
408
- const typeData = {};
409
- let exprType = expression.getType({
410
- flags: symbolType,
411
- typeChain: typeChain,
412
- data: typeData
413
- });
414
- const shouldIgnoreLHS = this.ignoreUnresolvedAssignmentLHS(expression, exprType, typeData === null || typeData === void 0 ? void 0 : typeData.definingNode);
415
- if (!this.isTypeKnown(exprType) && !shouldIgnoreLHS) {
416
- if ((_a = expression.getType({ flags: oppositeSymbolType })) === null || _a === void 0 ? void 0 : _a.isResolvable()) {
417
- const oppoSiteTypeChain = [];
418
- const invalidlyUsedResolvedType = expression.getType({ flags: oppositeSymbolType, typeChain: oppoSiteTypeChain });
419
- const typeChainScan = util_1.default.processTypeChain(oppoSiteTypeChain);
420
- if (isUsedAsType) {
421
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsType(typeChainScan.fullChainName)), { range: expression.range, file: file }));
238
+ else {
239
+ // This is valid brightscript component
240
+ // Test for invalid arg counts
241
+ const brightScriptComponent = roku_types_1.components[firstParamStringValue.toLowerCase()];
242
+ // Valid arg counts for createObject are 1+ number of args for constructor
243
+ let validArgCounts = brightScriptComponent.constructors.map(cnstr => cnstr.params.length + 1);
244
+ if (validArgCounts.length === 0) {
245
+ // no constructors for this component, so createObject only takes 1 arg
246
+ validArgCounts = [1];
422
247
  }
423
- else {
424
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable(invalidlyUsedResolvedType.toString())), { range: expression.range, file: file }));
248
+ if (!validArgCounts.includes(call === null || call === void 0 ? void 0 : call.args.length)) {
249
+ // Incorrect number of arguments included in `createObject()`
250
+ this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.mismatchCreateObjectArgumentCount(firstParamStringValue, validArgCounts, call === null || call === void 0 ? void 0 : call.args.length)), { range: call.range }));
251
+ }
252
+ // Test for deprecation
253
+ if (brightScriptComponent.isDeprecated) {
254
+ this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.deprecatedBrightScriptComponent(firstParamStringValue, brightScriptComponent.deprecatedDescription)), { range: call.range }));
425
255
  }
426
- }
427
- else {
428
- const typeChainScan = util_1.default.processTypeChain(typeChain);
429
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(typeChainScan.itemName, typeChainScan.fullNameOfItem)), { range: typeChainScan.range }));
430
- }
431
- }
432
- if (isUsedAsType) {
433
- return;
434
- }
435
- const lastTypeInfo = typeChain[typeChain.length - 1];
436
- const parentTypeInfo = typeChain[typeChain.length - 2];
437
- if ((0, reflection_1.isNamespaceType)(exprType)) {
438
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('namespace')), { range: expression.range, file: file }));
439
- }
440
- else if ((0, reflection_1.isEnumType)(exprType)) {
441
- const enumStatement = this.event.scope.getEnum(util_1.default.getAllDottedGetPartsAsString(expression));
442
- if (enumStatement) {
443
- // there's an enum with this name
444
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('enum')), { range: expression.range, file: file }));
445
- }
446
- }
447
- else if ((0, reflection_1.isDynamicType)(exprType) && (0, reflection_1.isEnumType)(parentTypeInfo === null || parentTypeInfo === void 0 ? void 0 : parentTypeInfo.type) && (0, reflection_1.isDottedGetExpression)(expression)) {
448
- const enumFileLink = this.event.scope.getEnumFileLink(util_1.default.getAllDottedGetPartsAsString(expression.obj));
449
- const typeChainScanForParent = util_1.default.processTypeChain(typeChain.slice(0, -1));
450
- if (enumFileLink) {
451
- this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownEnumValue(lastTypeInfo === null || lastTypeInfo === void 0 ? void 0 : lastTypeInfo.name, typeChainScanForParent.fullChainName)), { range: lastTypeInfo === null || lastTypeInfo === void 0 ? void 0 : lastTypeInfo.range, relatedInformation: [{
452
- message: 'Enum declared here',
453
- location: util_1.default.createLocation(vscode_uri_1.URI.file(enumFileLink === null || enumFileLink === void 0 ? void 0 : enumFileLink.file.srcPath).toString(), (_b = enumFileLink === null || enumFileLink === void 0 ? void 0 : enumFileLink.item) === null || _b === void 0 ? void 0 : _b.tokens.name.range)
454
- }] }));
455
256
  }
456
257
  }
258
+ this.event.scope.addDiagnostics(diagnostics);
457
259
  }
458
260
  /**
459
261
  * Adds a diagnostic to the first scope for this key. Prevents duplicate diagnostics
@@ -461,58 +263,35 @@ class ScopeValidator {
461
263
  */
462
264
  addDiagnosticOnce(diagnostic) {
463
265
  this.onceCache.getOrAdd(`${diagnostic.code}-${diagnostic.message}-${util_1.default.rangeToString(diagnostic.range)}`, () => {
464
- const diagnosticWithOrigin = Object.assign({}, diagnostic);
465
- if (!diagnosticWithOrigin.origin) {
466
- // diagnostic does not have origin.
467
- // set the origin to the current astSegment
468
- diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
469
- diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
470
- }
471
- this.event.scope.addDiagnostics([diagnosticWithOrigin]);
266
+ this.event.scope.addDiagnostics([diagnostic]);
472
267
  return true;
473
268
  });
474
269
  }
475
270
  addDiagnostic(diagnostic) {
476
- const diagnosticWithOrigin = Object.assign({}, diagnostic);
477
- if (!diagnosticWithOrigin.origin) {
478
- // diagnostic does not have origin.
479
- // set the origin to the current astSegment
480
- diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
481
- diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
482
- }
483
- this.event.scope.addDiagnostics([diagnosticWithOrigin]);
271
+ this.event.scope.addDiagnostics([diagnostic]);
484
272
  }
485
273
  /**
486
274
  * Add a diagnostic (to the first scope) that will have `relatedInformation` for each affected scope
487
275
  */
488
- addMultiScopeDiagnostic(diagnostic) {
489
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
276
+ addMultiScopeDiagnostic(diagnostic, message = 'Not defined in scope') {
277
+ var _a, _b, _c, _d, _e, _f, _g, _h;
490
278
  diagnostic = this.multiScopeCache.getOrAdd(`${(_a = diagnostic.file) === null || _a === void 0 ? void 0 : _a.srcPath}-${diagnostic.code}-${diagnostic.message}-${util_1.default.rangeToString(diagnostic.range)}`, () => {
491
279
  if (!diagnostic.relatedInformation) {
492
280
  diagnostic.relatedInformation = [];
493
281
  }
494
- const diagnosticWithOrigin = Object.assign({}, diagnostic);
495
- if (!diagnosticWithOrigin.origin) {
496
- // diagnostic does not have origin.
497
- // set the origin to the current astSegment
498
- diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
499
- diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
500
- }
501
- this.addDiagnostic(diagnosticWithOrigin);
502
- return diagnosticWithOrigin;
282
+ this.addDiagnostic(diagnostic);
283
+ return diagnostic;
503
284
  });
285
+ const info = {
286
+ message: `${message} '${this.event.scope.name}'`
287
+ };
504
288
  if ((0, reflection_1.isXmlScope)(this.event.scope) && ((_b = this.event.scope.xmlFile) === null || _b === void 0 ? void 0 : _b.srcPath)) {
505
- diagnostic.relatedInformation.push({
506
- message: `In component scope '${(_e = (_d = (_c = this.event.scope) === null || _c === void 0 ? void 0 : _c.xmlFile) === null || _d === void 0 ? void 0 : _d.componentName) === null || _e === void 0 ? void 0 : _e.text}'`,
507
- location: util_1.default.createLocation(vscode_uri_1.URI.file(this.event.scope.xmlFile.srcPath).toString(), (_o = (_m = (_l = (_k = (_j = (_h = (_g = (_f = this.event.scope) === null || _f === void 0 ? void 0 : _f.xmlFile) === null || _g === void 0 ? void 0 : _g.ast) === null || _h === void 0 ? void 0 : _h.componentElement) === null || _j === void 0 ? void 0 : _j.getAttribute('name')) === null || _k === void 0 ? void 0 : _k.tokens) === null || _l === void 0 ? void 0 : _l.value) === null || _m === void 0 ? void 0 : _m.range) !== null && _o !== void 0 ? _o : util_1.default.createRange(0, 0, 0, 10))
508
- });
289
+ info.location = util_1.default.createLocation(vscode_uri_1.URI.file(this.event.scope.xmlFile.srcPath).toString(), (_h = (_g = (_f = (_e = (_d = (_c = this.event.scope) === null || _c === void 0 ? void 0 : _c.xmlFile) === null || _d === void 0 ? void 0 : _d.ast) === null || _e === void 0 ? void 0 : _e.component) === null || _f === void 0 ? void 0 : _f.getAttribute('name')) === null || _g === void 0 ? void 0 : _g.value.range) !== null && _h !== void 0 ? _h : util_1.default.createRange(0, 0, 0, 10));
509
290
  }
510
291
  else {
511
- diagnostic.relatedInformation.push({
512
- message: `In scope '${this.event.scope.name}'`,
513
- location: util_1.default.createLocation(vscode_uri_1.URI.file(diagnostic.file.srcPath).toString(), diagnostic.range)
514
- });
292
+ info.location = util_1.default.createLocation(vscode_uri_1.URI.file(diagnostic.file.srcPath).toString(), diagnostic.range);
515
293
  }
294
+ diagnostic.relatedInformation.push(info);
516
295
  }
517
296
  }
518
297
  exports.ScopeValidator = ScopeValidator;