brighterscript 0.66.0-alpha.1 → 0.66.0-alpha.11

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