brighterscript 1.0.0-alpha.24 → 1.0.0-alpha.26
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.
- package/CHANGELOG.md +521 -233
- package/README.md +45 -139
- package/bsconfig.schema.json +46 -0
- package/dist/ActionPipeline.d.ts +10 -0
- package/dist/ActionPipeline.js +40 -0
- package/dist/ActionPipeline.js.map +1 -0
- package/dist/AstValidationSegmenter.d.ts +25 -0
- package/dist/AstValidationSegmenter.js +152 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +40 -4
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.js +3 -3
- package/dist/Cache.js.map +1 -1
- package/dist/CacheVerifier.d.ts +7 -0
- package/dist/CacheVerifier.js +20 -0
- package/dist/CacheVerifier.js.map +1 -0
- package/dist/CodeActionUtil.d.ts +3 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +3 -2
- package/dist/CommentFlagProcessor.js +5 -4
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +3 -2
- package/dist/DependencyGraph.js +11 -10
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.js +9 -5
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +1 -0
- package/dist/DiagnosticFilterer.js +5 -3
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +61 -13
- package/dist/DiagnosticMessages.js +116 -19
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
- package/dist/DiagnosticSeverityAdjuster.js +41 -0
- package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
- package/dist/FunctionScope.d.ts +28 -0
- package/dist/FunctionScope.js +52 -0
- package/dist/FunctionScope.js.map +1 -0
- package/dist/KeyedThrottler.d.ts +3 -3
- package/dist/KeyedThrottler.js +3 -3
- package/dist/KeyedThrottler.js.map +1 -1
- package/dist/LanguageServer.d.ts +23 -11
- package/dist/LanguageServer.js +150 -69
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +3 -2
- package/dist/Logger.js +11 -3
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +21 -3
- package/dist/PluginInterface.js +74 -6
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +158 -79
- package/dist/Program.js +841 -706
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +22 -12
- package/dist/ProgramBuilder.js +130 -103
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +86 -137
- package/dist/Scope.js +453 -519
- package/dist/Scope.js.map +1 -1
- package/dist/Stopwatch.js +1 -1
- package/dist/Stopwatch.js.map +1 -1
- package/dist/SymbolTable.d.ts +89 -34
- package/dist/SymbolTable.js +239 -114
- package/dist/SymbolTable.js.map +1 -1
- package/dist/Throttler.d.ts +12 -0
- package/dist/Throttler.js +39 -0
- package/dist/Throttler.js.map +1 -1
- package/dist/Watcher.d.ts +0 -3
- package/dist/Watcher.js +0 -3
- package/dist/Watcher.js.map +1 -1
- package/dist/XmlScope.d.ts +4 -11
- package/dist/XmlScope.js +75 -88
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +48 -0
- package/dist/astUtils/CachedLookups.js +323 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +9 -5
- package/dist/astUtils/{AstEditor.js → Editor.js} +10 -4
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +69 -65
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +10 -10
- package/dist/astUtils/creators.js +54 -24
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +5 -5
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +132 -104
- package/dist/astUtils/reflection.js +220 -174
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +256 -157
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +12 -12
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +53 -35
- package/dist/astUtils/visitors.js +29 -3
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +208 -52
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -9
- package/dist/astUtils/xml.js +9 -9
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +11 -2
- package/dist/bscPlugin/BscPlugin.js +37 -3
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
- package/dist/bscPlugin/CallExpressionInfo.js +131 -0
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
- package/dist/bscPlugin/FileWriter.d.ts +6 -0
- package/dist/bscPlugin/FileWriter.js +24 -0
- package/dist/bscPlugin/FileWriter.js.map +1 -0
- package/dist/bscPlugin/SignatureHelpUtil.d.ts +10 -0
- package/dist/bscPlugin/SignatureHelpUtil.js +136 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +16 -13
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +16 -16
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +52 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.js +517 -26
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1909 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js +210 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js +88 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
- package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +7 -7
- package/dist/bscPlugin/hover/HoverProcessor.js +123 -125
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +371 -53
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +2 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +83 -23
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +83 -6
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +1 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
- package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
- package/dist/bscPlugin/serialize/BslibManager.js +40 -0
- package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
- package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
- package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
- package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
- package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.d.ts → BrsFileTranspileProcessor.d.ts} +4 -2
- package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.js → BrsFileTranspileProcessor.js} +38 -12
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +12 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +13 -5
- package/dist/bscPlugin/validation/BrsFileValidator.js +262 -52
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +230 -14
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
- package/dist/bscPlugin/validation/ProgramValidator.d.ts +10 -0
- package/dist/bscPlugin/validation/ProgramValidator.js +32 -0
- package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +58 -27
- package/dist/bscPlugin/validation/ScopeValidator.js +514 -286
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2527 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js +44 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
- package/dist/cli.js +104 -13
- package/dist/cli.js.map +1 -1
- package/dist/deferred.d.ts +3 -3
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +8 -2
- package/dist/diagnosticUtils.js +47 -17
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +8 -10
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +26 -0
- package/dist/files/AssetFile.js +26 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +523 -493
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +111 -117
- package/dist/files/BrsFile.js +684 -1142
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1783 -1233
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +104 -0
- package/dist/files/BscFile.js +16 -0
- package/dist/files/BscFile.js.map +1 -0
- package/dist/files/Factory.d.ts +25 -0
- package/dist/files/Factory.js +22 -0
- package/dist/files/Factory.js.map +1 -0
- package/dist/files/LazyFileData.d.ts +20 -0
- package/dist/files/LazyFileData.js +54 -0
- package/dist/files/LazyFileData.js.map +1 -0
- package/dist/files/LazyFileData.spec.d.ts +1 -0
- package/dist/files/LazyFileData.spec.js +27 -0
- package/dist/files/LazyFileData.spec.js.map +1 -0
- package/dist/files/XmlFile.d.ts +70 -32
- package/dist/files/XmlFile.js +106 -118
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +325 -262
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +48 -40
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.js +84 -24
- package/dist/files/tests/optionalChaning.spec.js.map +1 -1
- package/dist/globalCallables.js +16 -21
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +421 -162
- package/dist/interfaces.js +27 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Character.spec.js +5 -5
- package/dist/lexer/Character.spec.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +12 -5
- package/dist/lexer/Lexer.js +28 -13
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +181 -135
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +9 -1
- package/dist/lexer/Token.js +9 -1
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +8 -0
- package/dist/lexer/TokenKind.js +24 -4
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +162 -0
- package/dist/parser/AstNode.js +225 -0
- package/dist/parser/AstNode.js.map +1 -0
- package/dist/parser/AstNode.spec.d.ts +1 -0
- package/dist/parser/AstNode.spec.js +165 -0
- package/dist/parser/AstNode.spec.js.map +1 -0
- package/dist/parser/BrsTranspileState.d.ts +4 -7
- package/dist/parser/BrsTranspileState.js +4 -12
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +376 -283
- package/dist/parser/Expression.js +742 -585
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +151 -145
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +48 -201
- package/dist/parser/Parser.js +705 -1026
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +861 -848
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +9 -8
- package/dist/parser/SGParser.js +10 -8
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +27 -38
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +98 -35
- package/dist/parser/SGTypes.js +169 -99
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +468 -272
- package/dist/parser/Statement.js +904 -631
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +47 -23
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +1 -1
- package/dist/parser/TranspileState.js +7 -12
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.js +3 -2
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +33 -23
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +25 -20
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +96 -94
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +22 -16
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +8 -8
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +58 -21
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +62 -21
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +8 -8
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +129 -21
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +5 -5
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +36 -36
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +92 -22
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +9 -9
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +59 -59
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +12 -12
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +12 -12
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/Relational.spec.js +13 -13
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +96 -57
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +89 -89
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js +127 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +15 -15
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/ConstStatement.spec.js +82 -33
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Continue.spec.d.ts +1 -0
- package/dist/parser/tests/statement/Continue.spec.js +119 -0
- package/dist/parser/tests/statement/Continue.spec.js.map +1 -0
- package/dist/parser/tests/statement/Declaration.spec.js +19 -19
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +22 -22
- package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.js +98 -302
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
- package/dist/parser/tests/statement/For.spec.js +9 -10
- package/dist/parser/tests/statement/For.spec.js.map +1 -1
- package/dist/parser/tests/statement/ForEach.spec.js +8 -9
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/statement/Function.spec.js +44 -35
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +5 -5
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +20 -20
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +30 -196
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +11 -11
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +16 -78
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +36 -34
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +14 -12
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +48 -35
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +6 -6
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +6 -6
- package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +18 -16
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +1 -1
- package/dist/preprocessor/Manifest.js +2 -2
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/preprocessor/Manifest.spec.js +8 -8
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/preprocessor/Preprocessor.d.ts +5 -6
- package/dist/preprocessor/Preprocessor.js +5 -5
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/preprocessor/Preprocessor.spec.js +25 -25
- package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.d.ts +1 -1
- package/dist/preprocessor/PreprocessorParser.js +7 -1
- package/dist/preprocessor/PreprocessorParser.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +13 -13
- package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
- package/dist/roku-types/data.json +5892 -10081
- package/dist/roku-types/index.d.ts +622 -1719
- package/dist/types/ArrayType.d.ts +10 -9
- package/dist/types/ArrayType.js +65 -60
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +36 -68
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +11 -0
- package/dist/types/AssociativeArrayType.js +52 -0
- package/dist/types/AssociativeArrayType.js.map +1 -0
- package/dist/types/BaseFunctionType.d.ts +9 -0
- package/dist/types/BaseFunctionType.js +25 -0
- package/dist/types/BaseFunctionType.js.map +1 -0
- package/dist/types/BooleanType.d.ts +8 -5
- package/dist/types/BooleanType.js +14 -7
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +10 -6
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +32 -21
- package/dist/types/BscType.js +118 -21
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BscTypeKind.d.ts +25 -0
- package/dist/types/BscTypeKind.js +30 -0
- package/dist/types/BscTypeKind.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
- package/dist/types/BuiltInInterfaceAdder.js +171 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +116 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
- package/dist/types/ClassType.d.ts +17 -0
- package/dist/types/ClassType.js +58 -0
- package/dist/types/ClassType.js.map +1 -0
- package/dist/types/ClassType.spec.d.ts +1 -0
- package/dist/types/ClassType.spec.js +77 -0
- package/dist/types/ClassType.spec.js.map +1 -0
- package/dist/types/ComponentType.d.ts +26 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +8 -5
- package/dist/types/DoubleType.js +18 -16
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +12 -6
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +9 -5
- package/dist/types/DynamicType.js +15 -4
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/DynamicType.spec.js +16 -5
- package/dist/types/DynamicType.spec.js.map +1 -1
- package/dist/types/EnumType.d.ts +30 -12
- package/dist/types/EnumType.js +43 -17
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/EnumType.spec.d.ts +1 -0
- package/dist/types/EnumType.spec.js +33 -0
- package/dist/types/EnumType.spec.js.map +1 -0
- package/dist/types/FloatType.d.ts +8 -5
- package/dist/types/FloatType.js +18 -16
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -6
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +13 -8
- package/dist/types/FunctionType.js +30 -14
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +28 -0
- package/dist/types/InheritableType.js +152 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +8 -5
- package/dist/types/IntegerType.js +18 -16
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +8 -6
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +12 -13
- package/dist/types/InterfaceType.js +20 -48
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +90 -56
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/InvalidType.d.ts +7 -5
- package/dist/types/InvalidType.js +13 -7
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +8 -6
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +8 -5
- package/dist/types/LongIntegerType.js +17 -15
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +10 -6
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/NamespaceType.d.ts +12 -0
- package/dist/types/NamespaceType.js +28 -0
- package/dist/types/NamespaceType.js.map +1 -0
- package/dist/types/ObjectType.d.ts +9 -8
- package/dist/types/ObjectType.js +21 -11
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ObjectType.spec.js +3 -3
- package/dist/types/ObjectType.spec.js.map +1 -1
- package/dist/types/ReferenceType.d.ts +63 -0
- package/dist/types/ReferenceType.js +423 -0
- package/dist/types/ReferenceType.js.map +1 -0
- package/dist/types/ReferenceType.spec.d.ts +1 -0
- package/dist/types/ReferenceType.spec.js +137 -0
- package/dist/types/ReferenceType.spec.js.map +1 -0
- package/dist/types/StringType.d.ts +11 -5
- package/dist/types/StringType.js +18 -7
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +3 -5
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +22 -17
- package/dist/types/TypedFunctionType.js +78 -60
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/TypedFunctionType.spec.js +105 -20
- package/dist/types/TypedFunctionType.spec.js.map +1 -1
- package/dist/types/UninitializedType.d.ts +8 -6
- package/dist/types/UninitializedType.js +13 -7
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +20 -0
- package/dist/types/UnionType.js +123 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +130 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +8 -5
- package/dist/types/VoidType.js +14 -7
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/VoidType.spec.js +3 -3
- package/dist/types/VoidType.spec.js.map +1 -1
- package/dist/types/helper.spec.d.ts +1 -0
- package/dist/types/helper.spec.js +145 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +19 -37
- package/dist/types/helpers.js +159 -99
- package/dist/types/helpers.js.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.js +39 -0
- package/dist/types/index.js.map +1 -0
- package/dist/util.d.ts +143 -139
- package/dist/util.js +864 -385
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +8 -25
- package/dist/validators/ClassValidator.js +99 -179
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +165 -152
- package/dist/astUtils/AstEditor.js.map +0 -1
- package/dist/astUtils/AstEditor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -32
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
- package/dist/parser/SGTypes.spec.js +0 -351
- package/dist/parser/SGTypes.spec.js.map +0 -1
- package/dist/types/CustomType.d.ts +0 -12
- package/dist/types/CustomType.js +0 -44
- package/dist/types/CustomType.js.map +0 -1
- package/dist/types/LazyType.d.ts +0 -16
- package/dist/types/LazyType.js +0 -44
- package/dist/types/LazyType.js.map +0 -1
- /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
- /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{parser/SGTypes.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
|
@@ -5,15 +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");
|
|
9
|
+
const SymbolTable_1 = require("../../SymbolTable");
|
|
8
10
|
const util_1 = require("../../util");
|
|
9
11
|
const roku_types_1 = require("../../roku-types");
|
|
10
|
-
const
|
|
11
|
-
const
|
|
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");
|
|
16
|
+
const Parser_1 = require("../../parser/Parser");
|
|
12
17
|
/**
|
|
13
18
|
* The lower-case names of all platform-included scenegraph nodes
|
|
14
19
|
*/
|
|
15
|
-
|
|
16
|
-
const
|
|
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();
|
|
17
23
|
/**
|
|
18
24
|
* A validator that handles all scope validations for a program validation cycle.
|
|
19
25
|
* You should create ONE of these to handle all scope events between beforeProgramValidate and afterProgramValidate,
|
|
@@ -21,183 +27,120 @@ const platformComponentNames = new Set(Object.values(roku_types_1.components).ma
|
|
|
21
27
|
*/
|
|
22
28
|
class ScopeValidator {
|
|
23
29
|
constructor() {
|
|
24
|
-
this.events = [];
|
|
25
30
|
this.onceCache = new Cache_1.Cache();
|
|
26
31
|
this.multiScopeCache = new Cache_1.Cache();
|
|
27
32
|
}
|
|
28
33
|
processEvent(event) {
|
|
29
|
-
this.
|
|
30
|
-
event.scope
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
event.scope.unlinkSymbolTable();
|
|
34
|
+
this.event = event;
|
|
35
|
+
if (this.event.program.globalScope === this.event.scope) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.walkFiles();
|
|
39
|
+
this.detectDuplicateEnums();
|
|
36
40
|
}
|
|
37
41
|
reset() {
|
|
42
|
+
this.event = undefined;
|
|
38
43
|
this.onceCache.clear();
|
|
39
44
|
this.multiScopeCache.clear();
|
|
40
|
-
this.events = [];
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Adds a diagnostic to the first scope for this key. Prevents duplicate diagnostics
|
|
44
|
-
* for diagnostics where scope isn't important. (i.e. CreateObject validations)
|
|
45
|
-
*/
|
|
46
|
-
addDiagnosticOnce(event, diagnostic) {
|
|
47
|
-
this.onceCache.getOrAdd(`${diagnostic.code}-${diagnostic.message}-${util_1.default.rangeToString(diagnostic.range)}`, () => {
|
|
48
|
-
event.scope.addDiagnostics([diagnostic]);
|
|
49
|
-
return true;
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
addDiagnostic(event, diagnostic) {
|
|
53
|
-
event.scope.addDiagnostics([diagnostic]);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Add a diagnostic (to the first scope) that will have `relatedInformation` for each affected scope
|
|
57
|
-
*/
|
|
58
|
-
addMultiScopeDiagnostic(event, diagnostic, message = 'Not defined in scope') {
|
|
59
|
-
var _a, _b;
|
|
60
|
-
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)}`, () => {
|
|
61
|
-
if (!diagnostic.relatedInformation) {
|
|
62
|
-
diagnostic.relatedInformation = [];
|
|
63
|
-
}
|
|
64
|
-
this.addDiagnostic(event, diagnostic);
|
|
65
|
-
return diagnostic;
|
|
66
|
-
});
|
|
67
|
-
const info = {
|
|
68
|
-
message: `${message} '${event.scope.name}'`
|
|
69
|
-
};
|
|
70
|
-
if ((0, reflection_1.isXmlScope)(event.scope) && ((_b = event.scope.xmlFile) === null || _b === void 0 ? void 0 : _b.srcPath)) {
|
|
71
|
-
info.location = util_1.default.createLocation(vscode_uri_1.URI.file(event.scope.xmlFile.srcPath).toString(), util_1.default.createRange(0, 0, 0, 10));
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
info.location = util_1.default.createLocation(vscode_uri_1.URI.file(diagnostic.file.srcPath).toString(), diagnostic.range);
|
|
75
|
-
}
|
|
76
|
-
diagnostic.relatedInformation.push(info);
|
|
77
45
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
*/
|
|
81
|
-
getSymbolTable(scope, file, position) {
|
|
82
|
-
var _a, _b;
|
|
83
|
-
let symbolTable;
|
|
84
|
-
symbolTable = (_a = file.getFunctionExpressionAtPosition(position)) === null || _a === void 0 ? void 0 : _a.symbolTable;
|
|
85
|
-
if (!symbolTable) {
|
|
86
|
-
symbolTable = (_b = file.getNamespaceStatementForPosition(position)) === null || _b === void 0 ? void 0 : _b.symbolTable;
|
|
87
|
-
}
|
|
88
|
-
if (!symbolTable) {
|
|
89
|
-
symbolTable = scope.symbolTable;
|
|
90
|
-
}
|
|
91
|
-
return symbolTable;
|
|
92
|
-
}
|
|
93
|
-
iterateExpressions(event) {
|
|
94
|
-
const { scope } = event;
|
|
95
|
-
event.scope.enumerateOwnFiles((file) => {
|
|
96
|
-
var _a, _b, _c;
|
|
46
|
+
walkFiles() {
|
|
47
|
+
this.event.scope.enumerateOwnFiles((file) => {
|
|
97
48
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
let expression;
|
|
110
|
-
//lift the callee from call expressions to handle namespaced function calls
|
|
111
|
-
if ((0, reflection_1.isCallExpression)(referenceExpression)) {
|
|
112
|
-
expression = referenceExpression.callee;
|
|
113
|
-
}
|
|
114
|
-
else if ((0, reflection_1.isNewExpression)(referenceExpression)) {
|
|
115
|
-
expression = referenceExpression.call.callee;
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
expression = referenceExpression;
|
|
119
|
-
}
|
|
120
|
-
if ((0, reflection_1.isCallExpression)(expression.parent) && !(0, reflection_1.isNewExpression)(referenceExpression)) {
|
|
121
|
-
// function calls are validated in detectInvalidFunctionCalls
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
const tokens = util_1.default.getAllDottedGetParts(expression);
|
|
125
|
-
if ((tokens === null || tokens === void 0 ? void 0 : tokens.length) > 0) {
|
|
126
|
-
const symbolTable = this.getSymbolTable(scope, file, tokens[0].range.start); //flag all unknown left-most variables
|
|
127
|
-
if (!symbolTable.hasSymbol((_a = tokens[0]) === null || _a === void 0 ? void 0 : _a.text)) {
|
|
128
|
-
this.addMultiScopeDiagnostic(event, Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(tokens[0].text)), { range: tokens[0].range }));
|
|
129
|
-
//skip to the next expression
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
//at this point, we know the first item is a known symbol. find unknown namespace parts after the first part
|
|
133
|
-
if (tokens.length > 1) {
|
|
134
|
-
const firstNamespacePart = tokens.shift().text;
|
|
135
|
-
const firstNamespacePartLower = firstNamespacePart === null || firstNamespacePart === void 0 ? void 0 : firstNamespacePart.toLowerCase();
|
|
136
|
-
const namespaceContainer = scope.namespaceLookup.get(firstNamespacePartLower);
|
|
137
|
-
const enumStatement = scope.getEnum(firstNamespacePartLower);
|
|
138
|
-
//if this isn't a namespace, skip it
|
|
139
|
-
if (!namespaceContainer && !enumStatement) {
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
//catch unknown namespace items
|
|
143
|
-
const processedNames = [firstNamespacePart];
|
|
144
|
-
for (const token of tokens !== null && tokens !== void 0 ? tokens : []) {
|
|
145
|
-
processedNames.push(token.text);
|
|
146
|
-
const entityName = processedNames.join('.');
|
|
147
|
-
const entityNameLower = entityName.toLowerCase();
|
|
148
|
-
//if this is an enum member, stop validating here to prevent errors further down the chain
|
|
149
|
-
if (scope.getEnumMemberMap().has(entityNameLower)) {
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
if (!scope.getEnumMap().has(entityNameLower) &&
|
|
153
|
-
!scope.getClassMap().has(entityNameLower) &&
|
|
154
|
-
!scope.getConstMap().has(entityNameLower) &&
|
|
155
|
-
!scope.getCallableByName(entityNameLower) &&
|
|
156
|
-
!scope.namespaceLookup.has(entityNameLower)) {
|
|
157
|
-
//if this looks like an enum, provide a nicer error message
|
|
158
|
-
const theEnum = (_b = this.getEnum(scope, entityNameLower)) === null || _b === void 0 ? void 0 : _b.item;
|
|
159
|
-
if (theEnum) {
|
|
160
|
-
this.addMultiScopeDiagnostic(event, Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownEnumValue((_c = token.text) === null || _c === void 0 ? void 0 : _c.split('.').pop(), theEnum.fullName)), { range: tokens[tokens.length - 1].range, relatedInformation: [{
|
|
161
|
-
message: 'Enum declared here',
|
|
162
|
-
location: util_1.default.createLocation(vscode_uri_1.URI.file(file.srcPath).toString(), theEnum.tokens.name.range)
|
|
163
|
-
}] }));
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
this.addMultiScopeDiagnostic(event, Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(token.text, entityName)), { range: token.range, file: file }));
|
|
167
|
-
}
|
|
168
|
-
//no need to add another diagnostic for future unknown items
|
|
169
|
-
continue outer;
|
|
170
|
-
}
|
|
49
|
+
const hasChangeInfo = this.event.changedFiles && this.event.changedSymbols;
|
|
50
|
+
let thisFileRequiresChangedSymbol = false;
|
|
51
|
+
for (let requiredSymbol of file.requiredSymbols) {
|
|
52
|
+
// eslint-disable-next-line no-bitwise
|
|
53
|
+
for (const flag of [SymbolTable_1.SymbolTypeFlag.runtime, SymbolTable_1.SymbolTypeFlag.typetime]) {
|
|
54
|
+
// eslint-disable-next-line no-bitwise
|
|
55
|
+
if (flag & requiredSymbol.flags) {
|
|
56
|
+
const changeSymbolSetForFlag = this.event.changedSymbols.get(flag);
|
|
57
|
+
if (util_1.default.setContainsUnresolvedSymbol(changeSymbolSetForFlag, requiredSymbol)) {
|
|
58
|
+
thisFileRequiresChangedSymbol = true;
|
|
171
59
|
}
|
|
172
60
|
}
|
|
173
61
|
}
|
|
174
62
|
}
|
|
63
|
+
const thisFileHasChanges = this.event.changedFiles.includes(file);
|
|
64
|
+
if (hasChangeInfo && !thisFileRequiresChangedSymbol && !thisFileHasChanges) {
|
|
65
|
+
// this file does not require a symbol that has changed, and this file has not changed
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (thisFileHasChanges) {
|
|
69
|
+
this.event.scope.clearAstSegmentDiagnosticsByFile(file);
|
|
70
|
+
}
|
|
71
|
+
const validationVisitor = (0, visitors_1.createVisitor)({
|
|
72
|
+
VariableExpression: (varExpr) => {
|
|
73
|
+
this.validateVariableAndDottedGetExpressions(file, varExpr);
|
|
74
|
+
},
|
|
75
|
+
DottedGetExpression: (dottedGet) => {
|
|
76
|
+
this.validateVariableAndDottedGetExpressions(file, dottedGet);
|
|
77
|
+
},
|
|
78
|
+
CallExpression: (functionCall) => {
|
|
79
|
+
this.validateFunctionCall(file, functionCall);
|
|
80
|
+
this.validateCreateObjectCall(file, functionCall);
|
|
81
|
+
},
|
|
82
|
+
ReturnStatement: (returnStatement) => {
|
|
83
|
+
this.validateReturnStatement(file, returnStatement);
|
|
84
|
+
},
|
|
85
|
+
DottedSetStatement: (dottedSetStmt) => {
|
|
86
|
+
this.validateDottedSetStatement(file, dottedSetStmt);
|
|
87
|
+
},
|
|
88
|
+
BinaryExpression: (binaryExpr) => {
|
|
89
|
+
this.validateBinaryExpression(file, binaryExpr);
|
|
90
|
+
},
|
|
91
|
+
UnaryExpression: (unaryExpr) => {
|
|
92
|
+
this.validateUnaryExpression(file, unaryExpr);
|
|
93
|
+
},
|
|
94
|
+
AssignmentStatement: (assignStmt) => {
|
|
95
|
+
this.validateAssignmentStatement(file, assignStmt);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
const segmentsToWalkForValidation = (thisFileHasChanges || !hasChangeInfo)
|
|
99
|
+
? file.validationSegmenter.segmentsForValidation // validate everything in the file
|
|
100
|
+
: file.getValidationSegments(this.event.changedSymbols); // validate only what's needed in the file
|
|
101
|
+
for (const segment of segmentsToWalkForValidation) {
|
|
102
|
+
this.currentSegmentBeingValidated = segment;
|
|
103
|
+
this.event.scope.clearAstSegmentDiagnostics(segment);
|
|
104
|
+
segment.walk(validationVisitor, {
|
|
105
|
+
walkMode: AstValidationSegmenter_1.InsideSegmentWalkMode
|
|
106
|
+
});
|
|
107
|
+
file.markSegmentAsValidated(segment);
|
|
108
|
+
}
|
|
175
109
|
}
|
|
176
110
|
});
|
|
177
111
|
}
|
|
112
|
+
isTypeKnown(exprType) {
|
|
113
|
+
let isKnownType = exprType === null || exprType === void 0 ? void 0 : exprType.isResolvable();
|
|
114
|
+
return isKnownType;
|
|
115
|
+
}
|
|
178
116
|
/**
|
|
179
|
-
*
|
|
180
|
-
* For example, all of these would return the enum: `SomeNamespace.SomeEnum.SomeMember`, SomeEnum.SomeMember, `SomeEnum`
|
|
117
|
+
* If this is the lhs of an assignment, we don't need to flag it as unresolved
|
|
181
118
|
*/
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
119
|
+
ignoreUnresolvedAssignmentLHS(expression, exprType, definingNode) {
|
|
120
|
+
var _a, _b;
|
|
121
|
+
if (!(0, reflection_1.isVariableExpression)(expression)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
let assignmentAncestor;
|
|
125
|
+
if ((0, reflection_1.isAssignmentStatement)(definingNode) && definingNode.tokens.equals.kind === TokenKind_1.TokenKind.Equal) {
|
|
126
|
+
// this symbol was defined in a "normal" assignment (eg. not a compound assignment)
|
|
127
|
+
assignmentAncestor = definingNode;
|
|
128
|
+
return ((_a = assignmentAncestor === null || assignmentAncestor === void 0 ? void 0 : assignmentAncestor.tokens.name) === null || _a === void 0 ? void 0 : _a.text.toLowerCase()) === ((_b = expression === null || expression === void 0 ? void 0 : expression.tokens.name) === null || _b === void 0 ? void 0 : _b.text.toLowerCase());
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
assignmentAncestor = expression === null || expression === void 0 ? void 0 : expression.findAncestor(reflection_1.isAssignmentStatement);
|
|
132
|
+
}
|
|
133
|
+
return (assignmentAncestor === null || assignmentAncestor === void 0 ? void 0 : assignmentAncestor.tokens.name) === (expression === null || expression === void 0 ? void 0 : expression.tokens.name) && (0, reflection_1.isUnionType)(exprType);
|
|
192
134
|
}
|
|
193
135
|
/**
|
|
194
136
|
* Flag duplicate enums
|
|
195
137
|
*/
|
|
196
|
-
detectDuplicateEnums(
|
|
138
|
+
detectDuplicateEnums() {
|
|
197
139
|
const diagnostics = [];
|
|
198
140
|
const enumLocationsByName = new Cache_1.Cache();
|
|
199
|
-
event.scope.enumerateBrsFiles((file) => {
|
|
200
|
-
|
|
141
|
+
this.event.scope.enumerateBrsFiles((file) => {
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
143
|
+
for (const enumStatement of file['_cachedLookups'].enumStatements) {
|
|
201
144
|
const fullName = enumStatement.fullName;
|
|
202
145
|
const nameLower = fullName === null || fullName === void 0 ? void 0 : fullName.toLowerCase();
|
|
203
146
|
if ((nameLower === null || nameLower === void 0 ? void 0 : nameLower.length) > 0) {
|
|
@@ -226,13 +169,13 @@ class ScopeValidator {
|
|
|
226
169
|
const primaryEnum = enumLocations.shift();
|
|
227
170
|
const fullName = primaryEnum.statement.fullName;
|
|
228
171
|
for (const duplicateEnumInfo of enumLocations) {
|
|
229
|
-
diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateEnumDeclaration(event.scope.name, fullName)), { file: duplicateEnumInfo.file, range: duplicateEnumInfo.statement.tokens.name.range, relatedInformation: [{
|
|
172
|
+
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: [{
|
|
230
173
|
message: 'Enum declared here',
|
|
231
174
|
location: util_1.default.createLocation(vscode_uri_1.URI.file(primaryEnum.file.srcPath).toString(), primaryEnum.statement.tokens.name.range)
|
|
232
|
-
}] }));
|
|
175
|
+
}], origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
233
176
|
}
|
|
234
177
|
}
|
|
235
|
-
event.scope.addDiagnostics(diagnostics);
|
|
178
|
+
this.event.scope.addDiagnostics(diagnostics);
|
|
236
179
|
}
|
|
237
180
|
/**
|
|
238
181
|
* Validate every function call to `CreateObject`.
|
|
@@ -240,150 +183,435 @@ class ScopeValidator {
|
|
|
240
183
|
* what these calls are supposed to look like, and this is a very common thing for brs devs to do, so just
|
|
241
184
|
* do this manually for now.
|
|
242
185
|
*/
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
186
|
+
validateCreateObjectCall(file, call) {
|
|
187
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
188
|
+
//skip non CreateObject function calls
|
|
189
|
+
const callName = (_a = util_1.default.getAllDottedGetPartsAsString(call.callee)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
190
|
+
if (callName !== 'createobject' || !(0, reflection_1.isLiteralExpression)(call === null || call === void 0 ? void 0 : call.args[0])) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const firstParamToken = (_c = (_b = call === null || call === void 0 ? void 0 : call.args[0]) === null || _b === void 0 ? void 0 : _b.tokens) === null || _c === void 0 ? void 0 : _c.value;
|
|
194
|
+
const firstParamStringValue = (_d = firstParamToken === null || firstParamToken === void 0 ? void 0 : firstParamToken.text) === null || _d === void 0 ? void 0 : _d.replace(/"/g, '');
|
|
195
|
+
if (!firstParamStringValue) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const firstParamStringValueLower = firstParamStringValue.toLowerCase();
|
|
199
|
+
//if this is a `createObject('roSGNode'` call, only support known sg node types
|
|
200
|
+
if (firstParamStringValueLower === 'rosgnode' && (0, reflection_1.isLiteralExpression)(call === null || call === void 0 ? void 0 : call.args[1])) {
|
|
201
|
+
const componentName = (_e = call === null || call === void 0 ? void 0 : call.args[1]) === null || _e === void 0 ? void 0 : _e.tokens.value;
|
|
202
|
+
//don't validate any components with a colon in their name (probably component libraries, but regular components can have them too).
|
|
203
|
+
if (!componentName || ((_f = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _f === void 0 ? void 0 : _f.includes(':'))) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
//add diagnostic for unknown components
|
|
207
|
+
const unquotedComponentName = (_g = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _g === void 0 ? void 0 : _g.replace(/"/g, '');
|
|
208
|
+
if (unquotedComponentName && !platformNodeNames.has(unquotedComponentName.toLowerCase()) && !this.event.program.getComponent(unquotedComponentName)) {
|
|
209
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownRoSGNode(unquotedComponentName)), { range: componentName.range }));
|
|
210
|
+
}
|
|
211
|
+
else if ((call === null || call === void 0 ? void 0 : call.args.length) !== 2) {
|
|
212
|
+
// roSgNode should only ever have 2 args in `createObject`
|
|
213
|
+
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 }));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else if (!platformComponentNames.has(firstParamStringValueLower)) {
|
|
217
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownBrightScriptComponent(firstParamStringValue)), { range: firstParamToken.range }));
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
// This is valid brightscript component
|
|
221
|
+
// Test for invalid arg counts
|
|
222
|
+
const brightScriptComponent = roku_types_1.components[firstParamStringValueLower];
|
|
223
|
+
// Valid arg counts for createObject are 1+ number of args for constructor
|
|
224
|
+
let validArgCounts = brightScriptComponent === null || brightScriptComponent === void 0 ? void 0 : brightScriptComponent.constructors.map(cnstr => cnstr.params.length + 1);
|
|
225
|
+
if (validArgCounts.length === 0) {
|
|
226
|
+
// no constructors for this component, so createObject only takes 1 arg
|
|
227
|
+
validArgCounts = [1];
|
|
228
|
+
}
|
|
229
|
+
if (!validArgCounts.includes(call === null || call === void 0 ? void 0 : call.args.length)) {
|
|
230
|
+
// Incorrect number of arguments included in `createObject()`
|
|
231
|
+
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 }));
|
|
232
|
+
}
|
|
233
|
+
// Test for deprecation
|
|
234
|
+
if (brightScriptComponent === null || brightScriptComponent === void 0 ? void 0 : brightScriptComponent.isDeprecated) {
|
|
235
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.deprecatedBrightScriptComponent(firstParamStringValue, brightScriptComponent.deprecatedDescription)), { range: call.range }));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Detect calls to functions with the incorrect number of parameters, or wrong types of arguments
|
|
241
|
+
*/
|
|
242
|
+
validateFunctionCall(file, expression) {
|
|
243
|
+
var _a, _b;
|
|
244
|
+
const getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime, data: {} };
|
|
245
|
+
let funcType = (_a = expression === null || expression === void 0 ? void 0 : expression.callee) === null || _a === void 0 ? void 0 : _a.getType(getTypeOptions);
|
|
246
|
+
if ((funcType === null || funcType === void 0 ? void 0 : funcType.isResolvable()) && (0, reflection_1.isClassType)(funcType)) {
|
|
247
|
+
// We're calling a class - get the constructor
|
|
248
|
+
funcType = funcType.getMemberType('new', getTypeOptions);
|
|
249
|
+
}
|
|
250
|
+
if ((funcType === null || funcType === void 0 ? void 0 : funcType.isResolvable()) && (0, reflection_1.isTypedFunctionType)(funcType)) {
|
|
251
|
+
//funcType.setName(expression.callee. .name);
|
|
252
|
+
//get min/max parameter count for callable
|
|
253
|
+
let minParams = 0;
|
|
254
|
+
let maxParams = 0;
|
|
255
|
+
for (let param of funcType.params) {
|
|
256
|
+
maxParams++;
|
|
257
|
+
//optional parameters must come last, so we can assume that minParams won't increase once we hit
|
|
258
|
+
//the first isOptional
|
|
259
|
+
if (param.isOptional !== true) {
|
|
260
|
+
minParams++;
|
|
270
261
|
}
|
|
271
|
-
|
|
272
|
-
|
|
262
|
+
}
|
|
263
|
+
if (funcType.isVariadic) {
|
|
264
|
+
// function accepts variable number of arguments
|
|
265
|
+
maxParams = Expression_1.CallExpression.MaximumArguments;
|
|
266
|
+
}
|
|
267
|
+
let expCallArgCount = expression.args.length;
|
|
268
|
+
if (expCallArgCount > maxParams || expCallArgCount < minParams) {
|
|
269
|
+
let minMaxParamsText = minParams === maxParams ? maxParams : `${minParams}-${maxParams}`;
|
|
270
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(minMaxParamsText, expCallArgCount)), { range: expression.callee.range,
|
|
271
|
+
//TODO detect end of expression call
|
|
272
|
+
file: file }));
|
|
273
|
+
}
|
|
274
|
+
let paramIndex = 0;
|
|
275
|
+
for (let arg of expression.args) {
|
|
276
|
+
const data = {};
|
|
277
|
+
let argType = arg.getType({ flags: SymbolTable_1.SymbolTypeFlag.runtime, data: data });
|
|
278
|
+
const paramType = (_b = funcType.params[paramIndex]) === null || _b === void 0 ? void 0 : _b.type;
|
|
279
|
+
if (!paramType) {
|
|
280
|
+
// unable to find a paramType -- maybe there are more args than params
|
|
281
|
+
break;
|
|
273
282
|
}
|
|
274
|
-
|
|
275
|
-
//
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
let validArgCounts = brightScriptComponent.constructors.map(cnstr => cnstr.params.length + 1);
|
|
280
|
-
if (validArgCounts.length === 0) {
|
|
281
|
-
// no constructors for this component, so createObject only takes 1 arg
|
|
282
|
-
validArgCounts = [1];
|
|
283
|
-
}
|
|
284
|
-
if (!validArgCounts.includes(call === null || call === void 0 ? void 0 : call.args.length)) {
|
|
285
|
-
// Incorrect number of arguments included in `createObject()`
|
|
286
|
-
this.addDiagnosticOnce(event, 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 }));
|
|
287
|
-
}
|
|
288
|
-
// Test for deprecation
|
|
289
|
-
if (brightScriptComponent.isDeprecated) {
|
|
290
|
-
this.addDiagnosticOnce(event, Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.deprecatedBrightScriptComponent(firstParamStringValue, brightScriptComponent.deprecatedDescription)), { range: call.range }));
|
|
283
|
+
if ((0, reflection_1.isCallableType)(paramType) && (0, reflection_1.isClassType)(argType) && (0, reflection_1.isClassStatement)(data.definingNode)) {
|
|
284
|
+
// the param is expecting a function, but we're passing a Class... are we actually passing the constructor? then we're ok!
|
|
285
|
+
const namespace = expression.findAncestor(reflection_1.isNamespaceStatement);
|
|
286
|
+
if (file.calleeIsKnownFunction(arg, namespace === null || namespace === void 0 ? void 0 : namespace.getName(Parser_1.ParseMode.BrighterScript))) {
|
|
287
|
+
argType = data.definingNode.getConstructorType();
|
|
291
288
|
}
|
|
292
289
|
}
|
|
290
|
+
const compatibilityData = {};
|
|
291
|
+
if (!(paramType === null || paramType === void 0 ? void 0 : paramType.isTypeCompatible(argType, compatibilityData))) {
|
|
292
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch(argType.toString(), paramType.toString(), compatibilityData)), { range: arg.range,
|
|
293
|
+
//TODO detect end of expression call
|
|
294
|
+
file: file }));
|
|
295
|
+
}
|
|
296
|
+
paramIndex++;
|
|
293
297
|
}
|
|
294
|
-
}
|
|
295
|
-
event.scope.addDiagnostics(diagnostics);
|
|
298
|
+
}
|
|
296
299
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
});
|
|
304
|
-
|
|
300
|
+
/**
|
|
301
|
+
* Detect return statements with incompatible types vs. declared return type
|
|
302
|
+
*/
|
|
303
|
+
validateReturnStatement(file, returnStmt) {
|
|
304
|
+
var _a;
|
|
305
|
+
const getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
306
|
+
let funcType = returnStmt.findAncestor(reflection_1.isFunctionExpression).getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
307
|
+
if ((0, reflection_1.isTypedFunctionType)(funcType)) {
|
|
308
|
+
const actualReturnType = (_a = returnStmt.value) === null || _a === void 0 ? void 0 : _a.getType(getTypeOptions);
|
|
309
|
+
const compatibilityData = {};
|
|
310
|
+
if (actualReturnType && !funcType.returnType.isTypeCompatible(actualReturnType, compatibilityData)) {
|
|
311
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch(actualReturnType.toString(), funcType.returnType.toString(), compatibilityData)), { range: returnStmt.value.range, file: file }));
|
|
312
|
+
}
|
|
313
|
+
}
|
|
305
314
|
}
|
|
306
315
|
/**
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
var _a
|
|
311
|
-
const
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
316
|
+
* Detect return statements with incompatible types vs. declared return type
|
|
317
|
+
*/
|
|
318
|
+
validateDottedSetStatement(file, dottedSetStmt) {
|
|
319
|
+
var _a;
|
|
320
|
+
const typeChainExpectedLHS = [];
|
|
321
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
322
|
+
const expectedLHSType = dottedSetStmt === null || dottedSetStmt === void 0 ? void 0 : dottedSetStmt.getType(Object.assign(Object.assign({}, getTypeOpts), { data: {}, typeChain: typeChainExpectedLHS }));
|
|
323
|
+
const actualRHSType = (_a = dottedSetStmt === null || dottedSetStmt === void 0 ? void 0 : dottedSetStmt.value) === null || _a === void 0 ? void 0 : _a.getType(getTypeOpts);
|
|
324
|
+
const compatibilityData = {};
|
|
325
|
+
const typeChainScan = util_1.default.processTypeChain(typeChainExpectedLHS);
|
|
326
|
+
// check if anything in typeChain is an AA - if so, just allow it
|
|
327
|
+
if (typeChainExpectedLHS.find(typeChainItem => (0, reflection_1.isAssociativeArrayType)(typeChainItem.type))) {
|
|
328
|
+
// something in the chain is an AA
|
|
329
|
+
// treat members as dynamic - they could have been set without the type system's knowledge
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
if (!(expectedLHSType === null || expectedLHSType === void 0 ? void 0 : expectedLHSType.isResolvable())) {
|
|
333
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(typeChainScan.itemName, typeChainScan.fullNameOfItem)), { range: typeChainScan.range }));
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const accessibilityIsOk = this.checkMemberAccessibility(file, dottedSetStmt, typeChainExpectedLHS);
|
|
337
|
+
if (accessibilityIsOk && !(expectedLHSType === null || expectedLHSType === void 0 ? void 0 : expectedLHSType.isTypeCompatible(actualRHSType, compatibilityData))) {
|
|
338
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch(actualRHSType.toString(), expectedLHSType.toString(), compatibilityData)), { range: dottedSetStmt.range, file: file }));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Detect when declared type does not match rhs type
|
|
343
|
+
*/
|
|
344
|
+
validateAssignmentStatement(file, assignStmt) {
|
|
345
|
+
var _a;
|
|
346
|
+
if (!(assignStmt === null || assignStmt === void 0 ? void 0 : assignStmt.typeExpression)) {
|
|
347
|
+
// nothing to check
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const typeChainExpectedLHS = [];
|
|
351
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
352
|
+
const expectedLHSType = assignStmt.typeExpression.getType(Object.assign(Object.assign({}, getTypeOpts), { data: {}, typeChain: typeChainExpectedLHS }));
|
|
353
|
+
const actualRHSType = (_a = assignStmt.value) === null || _a === void 0 ? void 0 : _a.getType(getTypeOpts);
|
|
354
|
+
const compatibilityData = {};
|
|
355
|
+
if (!(expectedLHSType === null || expectedLHSType === void 0 ? void 0 : expectedLHSType.isTypeCompatible(actualRHSType, compatibilityData))) {
|
|
356
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch(actualRHSType.toString(), expectedLHSType.toString(), compatibilityData)), { range: assignStmt.range, file: file }));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Detect invalid use of a binary operator
|
|
361
|
+
*/
|
|
362
|
+
validateBinaryExpression(file, binaryExpr) {
|
|
363
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
364
|
+
if (util_1.default.isInTypeExpression(binaryExpr)) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
let leftType = binaryExpr.left.getType(getTypeOpts);
|
|
368
|
+
let rightType = binaryExpr.right.getType(getTypeOpts);
|
|
369
|
+
if (!leftType.isResolvable() || !rightType.isResolvable()) {
|
|
370
|
+
// Can not find the type. error handled elsewhere
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
let leftTypeToTest = leftType;
|
|
374
|
+
let rightTypeToTest = rightType;
|
|
375
|
+
if ((0, reflection_1.isEnumMemberType)(leftType) || (0, reflection_1.isEnumType)(leftType)) {
|
|
376
|
+
leftTypeToTest = leftType.underlyingType;
|
|
377
|
+
}
|
|
378
|
+
if ((0, reflection_1.isEnumMemberType)(rightType) || (0, reflection_1.isEnumType)(rightType)) {
|
|
379
|
+
rightTypeToTest = rightType.underlyingType;
|
|
380
|
+
}
|
|
381
|
+
if ((0, reflection_1.isUnionType)(leftType) || (0, reflection_1.isUnionType)(rightType)) {
|
|
382
|
+
// TODO: it is possible to validate based on innerTypes, but more complicated
|
|
383
|
+
// Because you need to verify each combination of types
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
const leftIsPrimitive = (0, reflection_1.isPrimitiveType)(leftTypeToTest);
|
|
387
|
+
const rightIsPrimitive = (0, reflection_1.isPrimitiveType)(rightTypeToTest);
|
|
388
|
+
const leftIsAny = (0, reflection_1.isDynamicType)(leftTypeToTest) || (0, reflection_1.isObjectType)(leftTypeToTest);
|
|
389
|
+
const rightIsAny = (0, reflection_1.isDynamicType)(rightTypeToTest) || (0, reflection_1.isObjectType)(rightTypeToTest);
|
|
390
|
+
if (leftIsAny && rightIsAny) {
|
|
391
|
+
// both operands are basically "any" type... ignore;
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
else if ((leftIsAny && rightIsPrimitive) || (leftIsPrimitive && rightIsAny)) {
|
|
395
|
+
// one operand is basically "any" type... ignore;
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const opResult = util_1.default.binaryOperatorResultType(leftTypeToTest, binaryExpr.tokens.operator, rightTypeToTest);
|
|
399
|
+
if ((0, reflection_1.isDynamicType)(opResult)) {
|
|
400
|
+
// if the result was dynamic, that means there wasn't a valid operation
|
|
401
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(binaryExpr.tokens.operator.text, leftType.toString(), rightType.toString())), { range: binaryExpr.range, file: file }));
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Detect invalid use of a Unary operator
|
|
406
|
+
*/
|
|
407
|
+
validateUnaryExpression(file, unaryExpr) {
|
|
408
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
409
|
+
let rightType = unaryExpr.right.getType(getTypeOpts);
|
|
410
|
+
if (!rightType.isResolvable()) {
|
|
411
|
+
// Can not find the type. error handled elsewhere
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
let rightTypeToTest = rightType;
|
|
415
|
+
if ((0, reflection_1.isEnumMemberType)(rightType)) {
|
|
416
|
+
rightTypeToTest = rightType.underlyingType;
|
|
417
|
+
}
|
|
418
|
+
if ((0, reflection_1.isUnionType)(rightTypeToTest)) {
|
|
419
|
+
// TODO: it is possible to validate based on innerTypes, but more complicated
|
|
420
|
+
// Because you need to verify each combination of types
|
|
421
|
+
}
|
|
422
|
+
else if ((0, reflection_1.isDynamicType)(rightTypeToTest) || (0, reflection_1.isObjectType)(rightTypeToTest)) {
|
|
423
|
+
// operand is basically "any" type... ignore;
|
|
424
|
+
}
|
|
425
|
+
else if ((0, reflection_1.isPrimitiveType)(rightType)) {
|
|
426
|
+
const opResult = util_1.default.unaryOperatorResultType(unaryExpr.tokens.operator, rightTypeToTest);
|
|
427
|
+
if ((0, reflection_1.isDynamicType)(opResult)) {
|
|
428
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(unaryExpr.tokens.operator.text, rightType.toString())), { range: unaryExpr.range, file: file }));
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
// rhs is not a primitive, so no binary operator is allowed
|
|
433
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(unaryExpr.tokens.operator.text, rightType.toString())), { range: unaryExpr.range, file: file }));
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
validateVariableAndDottedGetExpressions(file, expression) {
|
|
437
|
+
var _a, _b;
|
|
438
|
+
if ((0, reflection_1.isDottedGetExpression)(expression.parent)) {
|
|
439
|
+
// We validate dottedGetExpressions at the top-most level
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if ((0, reflection_1.isVariableExpression)(expression)) {
|
|
443
|
+
if ((0, reflection_1.isAssignmentStatement)(expression.parent) && expression.parent.tokens.name === expression.tokens.name) {
|
|
444
|
+
// Don't validate LHS of assignments
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
else if ((0, reflection_1.isNamespaceStatement)(expression.parent)) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
let symbolType = SymbolTable_1.SymbolTypeFlag.runtime;
|
|
452
|
+
let oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.typetime;
|
|
453
|
+
const isUsedAsType = util_1.default.isInTypeExpression(expression);
|
|
454
|
+
if (isUsedAsType) {
|
|
455
|
+
// This is used in a TypeExpression - only look up types from SymbolTable
|
|
456
|
+
symbolType = SymbolTable_1.SymbolTypeFlag.typetime;
|
|
457
|
+
oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.runtime;
|
|
458
|
+
}
|
|
459
|
+
// Do a complete type check on all DottedGet and Variable expressions
|
|
460
|
+
// this will create a diagnostic if an invalid member is accessed
|
|
461
|
+
const typeChain = [];
|
|
462
|
+
const typeData = {};
|
|
463
|
+
let exprType = expression.getType({
|
|
464
|
+
flags: symbolType,
|
|
465
|
+
typeChain: typeChain,
|
|
466
|
+
data: typeData
|
|
467
|
+
});
|
|
468
|
+
const shouldIgnoreLHS = this.ignoreUnresolvedAssignmentLHS(expression, exprType, typeData === null || typeData === void 0 ? void 0 : typeData.definingNode);
|
|
469
|
+
if (!this.isTypeKnown(exprType) && !shouldIgnoreLHS) {
|
|
470
|
+
if ((_a = expression.getType({ flags: oppositeSymbolType })) === null || _a === void 0 ? void 0 : _a.isResolvable()) {
|
|
471
|
+
const oppoSiteTypeChain = [];
|
|
472
|
+
const invalidlyUsedResolvedType = expression.getType({ flags: oppositeSymbolType, typeChain: oppoSiteTypeChain });
|
|
473
|
+
const typeChainScan = util_1.default.processTypeChain(oppoSiteTypeChain);
|
|
474
|
+
if (isUsedAsType) {
|
|
475
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsType(typeChainScan.fullChainName)), { range: expression.range, file: file }));
|
|
332
476
|
}
|
|
333
|
-
|
|
334
|
-
|
|
477
|
+
else {
|
|
478
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable(invalidlyUsedResolvedType.toString())), { range: expression.range, file: file }));
|
|
335
479
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
const typeChainScan = util_1.default.processTypeChain(typeChain);
|
|
483
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(typeChainScan.itemName, typeChainScan.fullNameOfItem)), { range: typeChainScan.range }));
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (isUsedAsType) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
const lastTypeInfo = typeChain[typeChain.length - 1];
|
|
490
|
+
const parentTypeInfo = typeChain[typeChain.length - 2];
|
|
491
|
+
this.checkMemberAccessibility(file, expression, typeChain);
|
|
492
|
+
if ((0, reflection_1.isNamespaceType)(exprType)) {
|
|
493
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('namespace')), { range: expression.range, file: file }));
|
|
494
|
+
}
|
|
495
|
+
else if ((0, reflection_1.isEnumType)(exprType)) {
|
|
496
|
+
const enumStatement = this.event.scope.getEnum(util_1.default.getAllDottedGetPartsAsString(expression));
|
|
497
|
+
if (enumStatement) {
|
|
498
|
+
// there's an enum with this name
|
|
499
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('enum')), { range: expression.range, file: file }));
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
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)) {
|
|
503
|
+
const enumFileLink = this.event.scope.getEnumFileLink(util_1.default.getAllDottedGetPartsAsString(expression.obj));
|
|
504
|
+
const typeChainScanForParent = util_1.default.processTypeChain(typeChain.slice(0, -1));
|
|
505
|
+
if (enumFileLink) {
|
|
506
|
+
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: [{
|
|
507
|
+
message: 'Enum declared here',
|
|
508
|
+
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)
|
|
509
|
+
}] }));
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Adds diagnostics for accibility mismatches
|
|
515
|
+
*
|
|
516
|
+
* @param file file
|
|
517
|
+
* @param expression containing expression
|
|
518
|
+
* @param typeChain type chain to check
|
|
519
|
+
* @returns true if member accesiibility is okay
|
|
520
|
+
*/
|
|
521
|
+
checkMemberAccessibility(file, expression, typeChain) {
|
|
522
|
+
var _a, _b, _c;
|
|
523
|
+
for (let i = 0; i < typeChain.length - 1; i++) {
|
|
524
|
+
const parentChainItem = typeChain[i];
|
|
525
|
+
const childChainItem = typeChain[i + 1];
|
|
526
|
+
if ((0, reflection_1.isClassType)(parentChainItem.type)) {
|
|
527
|
+
const containingClassStmt = expression.findAncestor(reflection_1.isClassStatement);
|
|
528
|
+
const classStmtThatDefinesChildMember = (_b = (_a = childChainItem.data) === null || _a === void 0 ? void 0 : _a.definingNode) === null || _b === void 0 ? void 0 : _b.findAncestor(reflection_1.isClassStatement);
|
|
529
|
+
if (classStmtThatDefinesChildMember) {
|
|
530
|
+
const definingClassName = classStmtThatDefinesChildMember.getName(Parser_1.ParseMode.BrighterScript);
|
|
531
|
+
const inMatchingClassStmt = (containingClassStmt === null || containingClassStmt === void 0 ? void 0 : containingClassStmt.getName(Parser_1.ParseMode.BrighterScript).toLowerCase()) === parentChainItem.type.name.toLowerCase();
|
|
532
|
+
// eslint-disable-next-line no-bitwise
|
|
533
|
+
if (childChainItem.data.flags & SymbolTable_1.SymbolTypeFlag.private) {
|
|
534
|
+
if (!inMatchingClassStmt || childChainItem.data.memberOfAncestor) {
|
|
535
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.memberAccessibilityMismatch(childChainItem.name, childChainItem.data.flags, definingClassName)), { range: expression.range, file: file }));
|
|
536
|
+
// there's an error... don't worry about the rest of the chain
|
|
537
|
+
return false;
|
|
364
538
|
}
|
|
365
|
-
|
|
366
|
-
|
|
539
|
+
}
|
|
540
|
+
// eslint-disable-next-line no-bitwise
|
|
541
|
+
if (childChainItem.data.flags & SymbolTable_1.SymbolTypeFlag.protected) {
|
|
542
|
+
const containingClassName = containingClassStmt === null || containingClassStmt === void 0 ? void 0 : containingClassStmt.getName(Parser_1.ParseMode.BrighterScript);
|
|
543
|
+
const containingNamespaceName = (_c = expression.findAncestor(reflection_1.isNamespaceStatement)) === null || _c === void 0 ? void 0 : _c.getName(Parser_1.ParseMode.BrighterScript);
|
|
544
|
+
const ancestorClasses = this.event.scope.getClassHierarchy(containingClassName, containingNamespaceName).map(link => link.item);
|
|
545
|
+
const isSubClassOfDefiningClass = ancestorClasses.includes(classStmtThatDefinesChildMember);
|
|
546
|
+
if (!isSubClassOfDefiningClass) {
|
|
547
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.memberAccessibilityMismatch(childChainItem.name, childChainItem.data.flags, definingClassName)), { range: expression.range, file: file }));
|
|
548
|
+
// there's an error... don't worry about the rest of the chain
|
|
549
|
+
return false;
|
|
367
550
|
}
|
|
368
551
|
}
|
|
369
552
|
}
|
|
370
|
-
else if ((0, reflection_1.isInvalidType)(symbolTypeInfo.type)) {
|
|
371
|
-
// TODO TYPES: standard member functions like integer.ToStr() are not detectable yet.
|
|
372
|
-
}
|
|
373
|
-
else if ((0, reflection_1.isDynamicType)(symbolTypeInfo.type)) {
|
|
374
|
-
// maybe this is a function? who knows
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(symbolTypeInfo.expandedTokenText, symbolTypeInfo.fullName)), { range: expCall.range, file: file }));
|
|
378
|
-
}
|
|
379
553
|
}
|
|
380
554
|
}
|
|
381
|
-
return
|
|
555
|
+
return true;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Adds a diagnostic to the first scope for this key. Prevents duplicate diagnostics
|
|
559
|
+
* for diagnostics where scope isn't important. (i.e. CreateObject validations)
|
|
560
|
+
*/
|
|
561
|
+
addDiagnosticOnce(diagnostic) {
|
|
562
|
+
this.onceCache.getOrAdd(`${diagnostic.code}-${diagnostic.message}-${util_1.default.rangeToString(diagnostic.range)}`, () => {
|
|
563
|
+
const diagnosticWithOrigin = Object.assign({}, diagnostic);
|
|
564
|
+
if (!diagnosticWithOrigin.origin) {
|
|
565
|
+
// diagnostic does not have origin.
|
|
566
|
+
// set the origin to the current astSegment
|
|
567
|
+
diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
|
|
568
|
+
diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
|
|
569
|
+
}
|
|
570
|
+
this.event.scope.addDiagnostics([diagnosticWithOrigin]);
|
|
571
|
+
return true;
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
addDiagnostic(diagnostic) {
|
|
575
|
+
const diagnosticWithOrigin = Object.assign({}, diagnostic);
|
|
576
|
+
if (!diagnosticWithOrigin.origin) {
|
|
577
|
+
// diagnostic does not have origin.
|
|
578
|
+
// set the origin to the current astSegment
|
|
579
|
+
diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
|
|
580
|
+
diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
|
|
581
|
+
}
|
|
582
|
+
this.event.scope.addDiagnostics([diagnosticWithOrigin]);
|
|
382
583
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
584
|
+
/**
|
|
585
|
+
* Add a diagnostic (to the first scope) that will have `relatedInformation` for each affected scope
|
|
586
|
+
*/
|
|
587
|
+
addMultiScopeDiagnostic(diagnostic) {
|
|
588
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
589
|
+
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)}`, () => {
|
|
590
|
+
if (!diagnostic.relatedInformation) {
|
|
591
|
+
diagnostic.relatedInformation = [];
|
|
592
|
+
}
|
|
593
|
+
const diagnosticWithOrigin = Object.assign({}, diagnostic);
|
|
594
|
+
if (!diagnosticWithOrigin.origin) {
|
|
595
|
+
// diagnostic does not have origin.
|
|
596
|
+
// set the origin to the current astSegment
|
|
597
|
+
diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
|
|
598
|
+
diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
|
|
599
|
+
}
|
|
600
|
+
this.addDiagnostic(diagnosticWithOrigin);
|
|
601
|
+
return diagnosticWithOrigin;
|
|
602
|
+
});
|
|
603
|
+
if ((0, reflection_1.isXmlScope)(this.event.scope) && ((_b = this.event.scope.xmlFile) === null || _b === void 0 ? void 0 : _b.srcPath)) {
|
|
604
|
+
diagnostic.relatedInformation.push({
|
|
605
|
+
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}'`,
|
|
606
|
+
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))
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
diagnostic.relatedInformation.push({
|
|
611
|
+
message: `In scope '${this.event.scope.name}'`,
|
|
612
|
+
location: util_1.default.createLocation(vscode_uri_1.URI.file(diagnostic.file.srcPath).toString(), diagnostic.range)
|
|
613
|
+
});
|
|
614
|
+
}
|
|
387
615
|
}
|
|
388
616
|
}
|
|
389
617
|
exports.ScopeValidator = ScopeValidator;
|