brighterscript 1.0.0-alpha.23 → 1.0.0-alpha.25
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 +585 -218
- package/README.md +45 -139
- package/bsconfig.schema.json +41 -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 +39 -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 +79 -15
- package/dist/DiagnosticMessages.js +134 -21
- 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 +222 -87
- 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 +162 -81
- package/dist/Program.js +903 -732
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +22 -12
- package/dist/ProgramBuilder.js +132 -104
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +95 -134
- package/dist/Scope.js +477 -551
- 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 +95 -29
- package/dist/SymbolTable.js +256 -102
- 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 -6
- package/dist/XmlScope.js +74 -68
- 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} +68 -64
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +10 -10
- package/dist/astUtils/creators.js +26 -16
- 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 -100
- package/dist/astUtils/reflection.js +225 -166
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +208 -126
- 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 +54 -35
- package/dist/astUtils/visitors.js +29 -3
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +178 -33
- 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 +12 -2
- package/dist/bscPlugin/BscPlugin.js +41 -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 +135 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +21 -12
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +86 -12
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +57 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js +544 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1909 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.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 +17 -0
- package/dist/bscPlugin/hover/HoverProcessor.js +188 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +513 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +3 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +102 -29
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +167 -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/BrsFileTranspileProcessor.d.ts +16 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +123 -0
- 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 +22 -1
- package/dist/bscPlugin/validation/BrsFileValidator.js +316 -29
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +264 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
- 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 +56 -8
- package/dist/bscPlugin/validation/ScopeValidator.js +514 -116
- 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 +2454 -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 +107 -8
- 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 +529 -486
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +124 -112
- package/dist/files/BrsFile.js +819 -1131
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1869 -1277
- 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 -117
- 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 +49 -41
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.js +104 -40
- package/dist/files/tests/optionalChaning.spec.js.map +1 -1
- package/dist/globalCallables.js +16 -18
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +440 -150
- 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 +187 -134
- 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 +9 -0
- package/dist/lexer/TokenKind.js +30 -5
- 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 +126 -167
- package/dist/parser/Expression.js +524 -394
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +152 -146
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +45 -196
- package/dist/parser/Parser.js +470 -926
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +1034 -805
- 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 +208 -122
- package/dist/parser/Statement.js +599 -364
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +45 -21
- 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 +61 -20
- 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 +67 -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 +123 -81
- 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 +221 -81
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +287 -105
- 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.d.ts +1 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js +262 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -0
- 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 +111 -300
- 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 +107 -90
- 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 +3 -3
- 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 +15 -11
- 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 +6544 -10519
- package/dist/roku-types/index.d.ts +662 -1934
- 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 +164 -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 +10 -5
- package/dist/types/DynamicType.js +16 -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 +167 -131
- package/dist/util.js +890 -350
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +7 -25
- package/dist/validators/ClassValidator.js +103 -194
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +165 -149
- package/dist/astUtils/AstEditor.js.map +0 -1
- package/dist/astUtils/AstEditor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +0 -8
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +0 -40
- 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/hover/HoverProcessor.spec.d.ts} +0 -0
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ScopeValidator = void 0;
|
|
4
|
-
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
5
4
|
const vscode_uri_1 = require("vscode-uri");
|
|
6
5
|
const reflection_1 = require("../../astUtils/reflection");
|
|
7
6
|
const Cache_1 = require("../../Cache");
|
|
8
7
|
const DiagnosticMessages_1 = require("../../DiagnosticMessages");
|
|
8
|
+
const interfaces_1 = require("../../interfaces");
|
|
9
|
+
const SymbolTable_1 = require("../../SymbolTable");
|
|
9
10
|
const util_1 = require("../../util");
|
|
10
11
|
const roku_types_1 = require("../../roku-types");
|
|
12
|
+
const Expression_1 = require("../../parser/Expression");
|
|
13
|
+
const visitors_1 = require("../../astUtils/visitors");
|
|
14
|
+
const AstValidationSegmenter_1 = require("../../AstValidationSegmenter");
|
|
15
|
+
const TokenKind_1 = require("../../lexer/TokenKind");
|
|
16
|
+
const Parser_1 = require("../../parser/Parser");
|
|
11
17
|
/**
|
|
12
18
|
* The lower-case names of all platform-included scenegraph nodes
|
|
13
19
|
*/
|
|
14
|
-
|
|
15
|
-
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();
|
|
16
23
|
/**
|
|
17
24
|
* A validator that handles all scope validations for a program validation cycle.
|
|
18
25
|
* You should create ONE of these to handle all scope events between beforeProgramValidate and afterProgramValidate,
|
|
@@ -20,85 +27,117 @@ const platformComponentNames = new Set(Object.values(roku_types_1.components).ma
|
|
|
20
27
|
*/
|
|
21
28
|
class ScopeValidator {
|
|
22
29
|
constructor() {
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
30
|
+
this.onceCache = new Cache_1.Cache();
|
|
31
|
+
this.multiScopeCache = new Cache_1.Cache();
|
|
25
32
|
}
|
|
26
33
|
processEvent(event) {
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
this.event = event;
|
|
35
|
+
if (this.event.program.globalScope === this.event.scope) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.walkFiles();
|
|
39
|
+
this.detectDuplicateEnums();
|
|
31
40
|
}
|
|
32
41
|
reset() {
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
42
|
+
this.event = undefined;
|
|
43
|
+
this.onceCache.clear();
|
|
44
|
+
this.multiScopeCache.clear();
|
|
35
45
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//if there are any enums defined in this scope
|
|
53
|
-
const enumLookup = event.scope.getEnumMap();
|
|
54
|
-
//skip enum validation if there are no enums defined in this scope
|
|
55
|
-
if (enumLookup.size === 0) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
event.scope.enumerateOwnFiles((file) => {
|
|
59
|
-
var _a;
|
|
60
|
-
//skip non-brs files
|
|
61
|
-
if (!(0, reflection_1.isBrsFile)(file)) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
// const namespaceLookup = this.event.scopes[0]?.namespaceLookup;
|
|
65
|
-
for (const referenceExpression of file.parser.references.expressions) {
|
|
66
|
-
const actualExpressions = [];
|
|
67
|
-
//binary expressions actually have two expressions (left and right), so handle them independently
|
|
68
|
-
if ((0, reflection_1.isBinaryExpression)(referenceExpression)) {
|
|
69
|
-
actualExpressions.push(referenceExpression.left, referenceExpression.right);
|
|
46
|
+
walkFiles() {
|
|
47
|
+
this.event.scope.enumerateOwnFiles((file) => {
|
|
48
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
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;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
70
62
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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;
|
|
74
67
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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);
|
|
91
93
|
}
|
|
94
|
+
});
|
|
95
|
+
const segmentsToWalkForValidation = (thisFileHasChanges || !hasChangeInfo)
|
|
96
|
+
? file.validationSegmenter.segmentsForValidation // validate everything in the file
|
|
97
|
+
: file.getValidationSegments(this.event.changedSymbols); // validate only what's needed in the file
|
|
98
|
+
for (const segment of segmentsToWalkForValidation) {
|
|
99
|
+
this.currentSegmentBeingValidated = segment;
|
|
100
|
+
this.event.scope.clearAstSegmentDiagnostics(segment);
|
|
101
|
+
segment.walk(validationVisitor, {
|
|
102
|
+
walkMode: AstValidationSegmenter_1.InsideSegmentWalkMode
|
|
103
|
+
});
|
|
104
|
+
file.markSegmentAsValidated(segment);
|
|
92
105
|
}
|
|
93
106
|
}
|
|
94
107
|
});
|
|
95
|
-
event.scope.addDiagnostics(diagnostics);
|
|
96
108
|
}
|
|
97
|
-
|
|
109
|
+
isTypeKnown(exprType) {
|
|
110
|
+
let isKnownType = exprType === null || exprType === void 0 ? void 0 : exprType.isResolvable();
|
|
111
|
+
return isKnownType;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* If this is the lhs of an assignment, we don't need to flag it as unresolved
|
|
115
|
+
*/
|
|
116
|
+
ignoreUnresolvedAssignmentLHS(expression, exprType, definingNode) {
|
|
117
|
+
var _a, _b;
|
|
118
|
+
if (!(0, reflection_1.isVariableExpression)(expression)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
let assignmentAncestor;
|
|
122
|
+
if ((0, reflection_1.isAssignmentStatement)(definingNode) && definingNode.equals.kind === TokenKind_1.TokenKind.Equal) {
|
|
123
|
+
// this symbol was defined in a "normal" assignment (eg. not a compound assignment)
|
|
124
|
+
assignmentAncestor = definingNode;
|
|
125
|
+
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());
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
assignmentAncestor = expression === null || expression === void 0 ? void 0 : expression.findAncestor(reflection_1.isAssignmentStatement);
|
|
129
|
+
}
|
|
130
|
+
return (assignmentAncestor === null || assignmentAncestor === void 0 ? void 0 : assignmentAncestor.name) === (expression === null || expression === void 0 ? void 0 : expression.name) && (0, reflection_1.isUnionType)(exprType);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Flag duplicate enums
|
|
134
|
+
*/
|
|
135
|
+
detectDuplicateEnums() {
|
|
98
136
|
const diagnostics = [];
|
|
99
137
|
const enumLocationsByName = new Cache_1.Cache();
|
|
100
|
-
event.scope.enumerateBrsFiles((file) => {
|
|
101
|
-
|
|
138
|
+
this.event.scope.enumerateBrsFiles((file) => {
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
140
|
+
for (const enumStatement of file['_cachedLookups'].enumStatements) {
|
|
102
141
|
const fullName = enumStatement.fullName;
|
|
103
142
|
const nameLower = fullName === null || fullName === void 0 ? void 0 : fullName.toLowerCase();
|
|
104
143
|
if ((nameLower === null || nameLower === void 0 ? void 0 : nameLower.length) > 0) {
|
|
@@ -112,17 +151,28 @@ class ScopeValidator {
|
|
|
112
151
|
//now that we've collected all enum declarations, flag duplicates
|
|
113
152
|
for (const enumLocations of enumLocationsByName.values()) {
|
|
114
153
|
//sort by srcPath to keep the primary enum location consistent
|
|
115
|
-
enumLocations.sort((a, b) => {
|
|
154
|
+
enumLocations.sort((a, b) => {
|
|
155
|
+
var _a, _b;
|
|
156
|
+
const pathA = (_a = a.file) === null || _a === void 0 ? void 0 : _a.srcPath;
|
|
157
|
+
const pathB = (_b = b.file) === null || _b === void 0 ? void 0 : _b.srcPath;
|
|
158
|
+
if (pathA < pathB) {
|
|
159
|
+
return -1;
|
|
160
|
+
}
|
|
161
|
+
else if (pathA > pathB) {
|
|
162
|
+
return 1;
|
|
163
|
+
}
|
|
164
|
+
return 0;
|
|
165
|
+
});
|
|
116
166
|
const primaryEnum = enumLocations.shift();
|
|
117
167
|
const fullName = primaryEnum.statement.fullName;
|
|
118
168
|
for (const duplicateEnumInfo of enumLocations) {
|
|
119
|
-
diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateEnumDeclaration(event.scope.name, fullName)), { file: duplicateEnumInfo.file, range: duplicateEnumInfo.statement.tokens.name.range, relatedInformation: [{
|
|
169
|
+
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: [{
|
|
120
170
|
message: 'Enum declared here',
|
|
121
|
-
location:
|
|
122
|
-
}] }));
|
|
171
|
+
location: util_1.default.createLocation(vscode_uri_1.URI.file(primaryEnum.file.srcPath).toString(), primaryEnum.statement.tokens.name.range)
|
|
172
|
+
}], origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
123
173
|
}
|
|
124
174
|
}
|
|
125
|
-
event.scope.addDiagnostics(diagnostics);
|
|
175
|
+
this.event.scope.addDiagnostics(diagnostics);
|
|
126
176
|
}
|
|
127
177
|
/**
|
|
128
178
|
* Validate every function call to `CreateObject`.
|
|
@@ -130,59 +180,407 @@ class ScopeValidator {
|
|
|
130
180
|
* what these calls are supposed to look like, and this is a very common thing for brs devs to do, so just
|
|
131
181
|
* do this manually for now.
|
|
132
182
|
*/
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
183
|
+
validateCreateObjectCall(file, call) {
|
|
184
|
+
var _a, _b, _c, _d, _e, _f;
|
|
185
|
+
//skip non CreateObject function calls
|
|
186
|
+
const callName = (_a = util_1.default.getAllDottedGetPartsAsString(call.callee)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
187
|
+
if (callName !== 'createobject' || !(0, reflection_1.isLiteralExpression)(call === null || call === void 0 ? void 0 : call.args[0])) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const firstParamToken = (_b = call === null || call === void 0 ? void 0 : call.args[0]) === null || _b === void 0 ? void 0 : _b.token;
|
|
191
|
+
const firstParamStringValue = (_c = firstParamToken === null || firstParamToken === void 0 ? void 0 : firstParamToken.text) === null || _c === void 0 ? void 0 : _c.replace(/"/g, '');
|
|
192
|
+
//if this is a `createObject('roSGNode'` call, only support known sg node types
|
|
193
|
+
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])) {
|
|
194
|
+
const componentName = (_d = call === null || call === void 0 ? void 0 : call.args[1]) === null || _d === void 0 ? void 0 : _d.token;
|
|
195
|
+
//don't validate any components with a colon in their name (probably component libraries, but regular components can have them too).
|
|
196
|
+
if ((_e = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _e === void 0 ? void 0 : _e.includes(':')) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
//add diagnostic for unknown components
|
|
200
|
+
const unquotedComponentName = (_f = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _f === void 0 ? void 0 : _f.replace(/"/g, '');
|
|
201
|
+
if (unquotedComponentName && !platformNodeNames.has(unquotedComponentName.toLowerCase()) && !this.event.program.getComponent(unquotedComponentName)) {
|
|
202
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownRoSGNode(unquotedComponentName)), { range: componentName.range }));
|
|
203
|
+
}
|
|
204
|
+
else if ((call === null || call === void 0 ? void 0 : call.args.length) !== 2) {
|
|
205
|
+
// roSgNode should only ever have 2 args in `createObject`
|
|
206
|
+
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 }));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else if (!platformComponentNames.has(firstParamStringValue.toLowerCase())) {
|
|
210
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownBrightScriptComponent(firstParamStringValue)), { range: firstParamToken.range }));
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// This is valid brightscript component
|
|
214
|
+
// Test for invalid arg counts
|
|
215
|
+
const brightScriptComponent = roku_types_1.components[firstParamStringValue.toLowerCase()];
|
|
216
|
+
// Valid arg counts for createObject are 1+ number of args for constructor
|
|
217
|
+
let validArgCounts = brightScriptComponent.constructors.map(cnstr => cnstr.params.length + 1);
|
|
218
|
+
if (validArgCounts.length === 0) {
|
|
219
|
+
// no constructors for this component, so createObject only takes 1 arg
|
|
220
|
+
validArgCounts = [1];
|
|
221
|
+
}
|
|
222
|
+
if (!validArgCounts.includes(call === null || call === void 0 ? void 0 : call.args.length)) {
|
|
223
|
+
// Incorrect number of arguments included in `createObject()`
|
|
224
|
+
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 }));
|
|
225
|
+
}
|
|
226
|
+
// Test for deprecation
|
|
227
|
+
if (brightScriptComponent.isDeprecated) {
|
|
228
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.deprecatedBrightScriptComponent(firstParamStringValue, brightScriptComponent.deprecatedDescription)), { range: call.range }));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Detect calls to functions with the incorrect number of parameters, or wrong types of arguments
|
|
234
|
+
*/
|
|
235
|
+
validateFunctionCall(file, expression) {
|
|
236
|
+
var _a, _b;
|
|
237
|
+
const getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime, data: {} };
|
|
238
|
+
let funcType = (_a = expression === null || expression === void 0 ? void 0 : expression.callee) === null || _a === void 0 ? void 0 : _a.getType(getTypeOptions);
|
|
239
|
+
if ((funcType === null || funcType === void 0 ? void 0 : funcType.isResolvable()) && (0, reflection_1.isClassType)(funcType)) {
|
|
240
|
+
// We're calling a class - get the constructor
|
|
241
|
+
funcType = funcType.getMemberType('new', getTypeOptions);
|
|
242
|
+
}
|
|
243
|
+
if ((funcType === null || funcType === void 0 ? void 0 : funcType.isResolvable()) && (0, reflection_1.isTypedFunctionType)(funcType)) {
|
|
244
|
+
//funcType.setName(expression.callee. .name);
|
|
245
|
+
//get min/max parameter count for callable
|
|
246
|
+
let minParams = 0;
|
|
247
|
+
let maxParams = 0;
|
|
248
|
+
for (let param of funcType.params) {
|
|
249
|
+
maxParams++;
|
|
250
|
+
//optional parameters must come last, so we can assume that minParams won't increase once we hit
|
|
251
|
+
//the first isOptional
|
|
252
|
+
if (param.isOptional !== true) {
|
|
253
|
+
minParams++;
|
|
141
254
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
255
|
+
}
|
|
256
|
+
if (funcType.isVariadic) {
|
|
257
|
+
// function accepts variable number of arguments
|
|
258
|
+
maxParams = Expression_1.CallExpression.MaximumArguments;
|
|
259
|
+
}
|
|
260
|
+
let expCallArgCount = expression.args.length;
|
|
261
|
+
if (expCallArgCount > maxParams || expCallArgCount < minParams) {
|
|
262
|
+
let minMaxParamsText = minParams === maxParams ? maxParams : `${minParams}-${maxParams}`;
|
|
263
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(minMaxParamsText, expCallArgCount)), { range: expression.callee.range,
|
|
264
|
+
//TODO detect end of expression call
|
|
265
|
+
file: file }));
|
|
266
|
+
}
|
|
267
|
+
let paramIndex = 0;
|
|
268
|
+
for (let arg of expression.args) {
|
|
269
|
+
const data = {};
|
|
270
|
+
let argType = arg.getType({ flags: SymbolTable_1.SymbolTypeFlag.runtime, data: data });
|
|
271
|
+
const paramType = (_b = funcType.params[paramIndex]) === null || _b === void 0 ? void 0 : _b.type;
|
|
272
|
+
if (!paramType) {
|
|
273
|
+
// unable to find a paramType -- maybe there are more args than params
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
if ((0, reflection_1.isCallableType)(paramType) && (0, reflection_1.isClassType)(argType) && (0, reflection_1.isClassStatement)(data.definingNode)) {
|
|
277
|
+
// the param is expecting a function, but we're passing a Class... are we actually passing the constructor? then we're ok!
|
|
278
|
+
const namespace = expression.findAncestor(reflection_1.isNamespaceStatement);
|
|
279
|
+
if (file.calleeIsKnownFunction(arg, namespace === null || namespace === void 0 ? void 0 : namespace.getName(Parser_1.ParseMode.BrighterScript))) {
|
|
280
|
+
argType = data.definingNode.getConstructorType();
|
|
159
281
|
}
|
|
160
282
|
}
|
|
161
|
-
|
|
162
|
-
|
|
283
|
+
const compatibilityData = {};
|
|
284
|
+
if (!(paramType === null || paramType === void 0 ? void 0 : paramType.isTypeCompatible(argType, compatibilityData))) {
|
|
285
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch(argType.toString(), paramType.toString(), compatibilityData)), { range: arg.range,
|
|
286
|
+
//TODO detect end of expression call
|
|
287
|
+
file: file }));
|
|
288
|
+
}
|
|
289
|
+
paramIndex++;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Detect return statements with incompatible types vs. declared return type
|
|
295
|
+
*/
|
|
296
|
+
validateReturnStatement(file, returnStmt) {
|
|
297
|
+
var _a;
|
|
298
|
+
const getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
299
|
+
let funcType = returnStmt.findAncestor(reflection_1.isFunctionExpression).getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
300
|
+
if ((0, reflection_1.isTypedFunctionType)(funcType)) {
|
|
301
|
+
const actualReturnType = (_a = returnStmt.value) === null || _a === void 0 ? void 0 : _a.getType(getTypeOptions);
|
|
302
|
+
const compatibilityData = {};
|
|
303
|
+
if (actualReturnType && !funcType.returnType.isTypeCompatible(actualReturnType, compatibilityData)) {
|
|
304
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch(actualReturnType.toString(), funcType.returnType.toString(), compatibilityData)), { range: returnStmt.value.range, file: file }));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Detect return statements with incompatible types vs. declared return type
|
|
310
|
+
*/
|
|
311
|
+
validateDottedSetStatement(file, dottedSetStmt) {
|
|
312
|
+
var _a;
|
|
313
|
+
const typeChainExpectedLHS = [];
|
|
314
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
315
|
+
const expectedLHSType = dottedSetStmt === null || dottedSetStmt === void 0 ? void 0 : dottedSetStmt.getType(Object.assign(Object.assign({}, getTypeOpts), { data: {}, typeChain: typeChainExpectedLHS }));
|
|
316
|
+
const actualRHSType = (_a = dottedSetStmt === null || dottedSetStmt === void 0 ? void 0 : dottedSetStmt.value) === null || _a === void 0 ? void 0 : _a.getType(getTypeOpts);
|
|
317
|
+
const compatibilityData = {};
|
|
318
|
+
const typeChainScan = util_1.default.processTypeChain(typeChainExpectedLHS);
|
|
319
|
+
if (!(expectedLHSType === null || expectedLHSType === void 0 ? void 0 : expectedLHSType.isResolvable())) {
|
|
320
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(typeChainScan.itemName, typeChainScan.fullNameOfItem)), { range: typeChainScan.range }));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const accessibilityIsOk = this.checkMemberAccessibility(file, dottedSetStmt, typeChainExpectedLHS);
|
|
324
|
+
if (accessibilityIsOk && !(expectedLHSType === null || expectedLHSType === void 0 ? void 0 : expectedLHSType.isTypeCompatible(actualRHSType, compatibilityData))) {
|
|
325
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch(actualRHSType.toString(), expectedLHSType.toString(), compatibilityData)), { range: dottedSetStmt.range, file: file }));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Detect invalid use of a binary operator
|
|
330
|
+
*/
|
|
331
|
+
validateBinaryExpression(file, binaryExpr) {
|
|
332
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
333
|
+
if (util_1.default.isInTypeExpression(binaryExpr)) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
let leftType = binaryExpr.left.getType(getTypeOpts);
|
|
337
|
+
let rightType = binaryExpr.right.getType(getTypeOpts);
|
|
338
|
+
if (!leftType.isResolvable() || !rightType.isResolvable()) {
|
|
339
|
+
// Can not find the type. error handled elsewhere
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
let leftTypeToTest = leftType;
|
|
343
|
+
let rightTypeToTest = rightType;
|
|
344
|
+
if ((0, reflection_1.isEnumMemberType)(leftType) || (0, reflection_1.isEnumType)(leftType)) {
|
|
345
|
+
leftTypeToTest = leftType.underlyingType;
|
|
346
|
+
}
|
|
347
|
+
if ((0, reflection_1.isEnumMemberType)(rightType) || (0, reflection_1.isEnumType)(rightType)) {
|
|
348
|
+
rightTypeToTest = rightType.underlyingType;
|
|
349
|
+
}
|
|
350
|
+
if ((0, reflection_1.isUnionType)(leftType) || (0, reflection_1.isUnionType)(rightType)) {
|
|
351
|
+
// TODO: it is possible to validate based on innerTypes, but more complicated
|
|
352
|
+
// Because you need to verify each combination of types
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const leftIsPrimitive = (0, reflection_1.isPrimitiveType)(leftTypeToTest);
|
|
356
|
+
const rightIsPrimitive = (0, reflection_1.isPrimitiveType)(rightTypeToTest);
|
|
357
|
+
const leftIsAny = (0, reflection_1.isDynamicType)(leftTypeToTest) || (0, reflection_1.isObjectType)(leftTypeToTest);
|
|
358
|
+
const rightIsAny = (0, reflection_1.isDynamicType)(rightTypeToTest) || (0, reflection_1.isObjectType)(rightTypeToTest);
|
|
359
|
+
if (leftIsAny && rightIsAny) {
|
|
360
|
+
// both operands are basically "any" type... ignore;
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
else if ((leftIsAny && rightIsPrimitive) || (leftIsPrimitive && rightIsAny)) {
|
|
364
|
+
// one operand is basically "any" type... ignore;
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const opResult = util_1.default.binaryOperatorResultType(leftTypeToTest, binaryExpr.operator, rightTypeToTest);
|
|
368
|
+
if ((0, reflection_1.isDynamicType)(opResult)) {
|
|
369
|
+
// if the result was dynamic, that means there wasn't a valid operation
|
|
370
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(binaryExpr.operator.text, leftType.toString(), rightType.toString())), { range: binaryExpr.range, file: file }));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Detect invalid use of a Unary operator
|
|
375
|
+
*/
|
|
376
|
+
validateUnaryExpression(file, unaryExpr) {
|
|
377
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
378
|
+
let rightType = unaryExpr.right.getType(getTypeOpts);
|
|
379
|
+
if (!rightType.isResolvable()) {
|
|
380
|
+
// Can not find the type. error handled elsewhere
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
let rightTypeToTest = rightType;
|
|
384
|
+
if ((0, reflection_1.isEnumMemberType)(rightType)) {
|
|
385
|
+
rightTypeToTest = rightType.underlyingType;
|
|
386
|
+
}
|
|
387
|
+
if ((0, reflection_1.isUnionType)(rightTypeToTest)) {
|
|
388
|
+
// TODO: it is possible to validate based on innerTypes, but more complicated
|
|
389
|
+
// Because you need to verify each combination of types
|
|
390
|
+
}
|
|
391
|
+
else if ((0, reflection_1.isDynamicType)(rightTypeToTest) || (0, reflection_1.isObjectType)(rightTypeToTest)) {
|
|
392
|
+
// operand is basically "any" type... ignore;
|
|
393
|
+
}
|
|
394
|
+
else if ((0, reflection_1.isPrimitiveType)(rightType)) {
|
|
395
|
+
const opResult = util_1.default.unaryOperatorResultType(unaryExpr.operator, rightTypeToTest);
|
|
396
|
+
if ((0, reflection_1.isDynamicType)(opResult)) {
|
|
397
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(unaryExpr.operator.text, rightType.toString())), { range: unaryExpr.range, file: file }));
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
// rhs is not a primitive, so no binary operator is allowed
|
|
402
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(unaryExpr.operator.text, rightType.toString())), { range: unaryExpr.range, file: file }));
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
validateVariableAndDottedGetExpressions(file, expression) {
|
|
406
|
+
var _a, _b;
|
|
407
|
+
if ((0, reflection_1.isDottedGetExpression)(expression.parent)) {
|
|
408
|
+
// We validate dottedGetExpressions at the top-most level
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if ((0, reflection_1.isVariableExpression)(expression)) {
|
|
412
|
+
if ((0, reflection_1.isAssignmentStatement)(expression.parent) && expression.parent.name === expression.name) {
|
|
413
|
+
// Don't validate LHS of assignments
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
else if ((0, reflection_1.isNamespaceStatement)(expression.parent)) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
let symbolType = SymbolTable_1.SymbolTypeFlag.runtime;
|
|
421
|
+
let oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.typetime;
|
|
422
|
+
const isUsedAsType = util_1.default.isInTypeExpression(expression);
|
|
423
|
+
if (isUsedAsType) {
|
|
424
|
+
// This is used in a TypeExpression - only look up types from SymbolTable
|
|
425
|
+
symbolType = SymbolTable_1.SymbolTypeFlag.typetime;
|
|
426
|
+
oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.runtime;
|
|
427
|
+
}
|
|
428
|
+
// Do a complete type check on all DottedGet and Variable expressions
|
|
429
|
+
// this will create a diagnostic if an invalid member is accessed
|
|
430
|
+
const typeChain = [];
|
|
431
|
+
const typeData = {};
|
|
432
|
+
let exprType = expression.getType({
|
|
433
|
+
flags: symbolType,
|
|
434
|
+
typeChain: typeChain,
|
|
435
|
+
data: typeData
|
|
436
|
+
});
|
|
437
|
+
const shouldIgnoreLHS = this.ignoreUnresolvedAssignmentLHS(expression, exprType, typeData === null || typeData === void 0 ? void 0 : typeData.definingNode);
|
|
438
|
+
if (!this.isTypeKnown(exprType) && !shouldIgnoreLHS) {
|
|
439
|
+
if ((_a = expression.getType({ flags: oppositeSymbolType })) === null || _a === void 0 ? void 0 : _a.isResolvable()) {
|
|
440
|
+
const oppoSiteTypeChain = [];
|
|
441
|
+
const invalidlyUsedResolvedType = expression.getType({ flags: oppositeSymbolType, typeChain: oppoSiteTypeChain });
|
|
442
|
+
const typeChainScan = util_1.default.processTypeChain(oppoSiteTypeChain);
|
|
443
|
+
if (isUsedAsType) {
|
|
444
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsType(typeChainScan.fullChainName)), { range: expression.range, file: file }));
|
|
163
445
|
}
|
|
164
446
|
else {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
447
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable(invalidlyUsedResolvedType.toString())), { range: expression.range, file: file }));
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
const typeChainScan = util_1.default.processTypeChain(typeChain);
|
|
452
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(typeChainScan.itemName, typeChainScan.fullNameOfItem)), { range: typeChainScan.range }));
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (isUsedAsType) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
const lastTypeInfo = typeChain[typeChain.length - 1];
|
|
459
|
+
const parentTypeInfo = typeChain[typeChain.length - 2];
|
|
460
|
+
this.checkMemberAccessibility(file, expression, typeChain);
|
|
461
|
+
if ((0, reflection_1.isNamespaceType)(exprType)) {
|
|
462
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('namespace')), { range: expression.range, file: file }));
|
|
463
|
+
}
|
|
464
|
+
else if ((0, reflection_1.isEnumType)(exprType)) {
|
|
465
|
+
const enumStatement = this.event.scope.getEnum(util_1.default.getAllDottedGetPartsAsString(expression));
|
|
466
|
+
if (enumStatement) {
|
|
467
|
+
// there's an enum with this name
|
|
468
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('enum')), { range: expression.range, file: file }));
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
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)) {
|
|
472
|
+
const enumFileLink = this.event.scope.getEnumFileLink(util_1.default.getAllDottedGetPartsAsString(expression.obj));
|
|
473
|
+
const typeChainScanForParent = util_1.default.processTypeChain(typeChain.slice(0, -1));
|
|
474
|
+
if (enumFileLink) {
|
|
475
|
+
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: [{
|
|
476
|
+
message: 'Enum declared here',
|
|
477
|
+
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)
|
|
478
|
+
}] }));
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Adds diagnostics for accibility mismatches
|
|
484
|
+
*
|
|
485
|
+
* @param file file
|
|
486
|
+
* @param expression containing expression
|
|
487
|
+
* @param typeChain type chain to check
|
|
488
|
+
* @returns true if member accesiibility is okay
|
|
489
|
+
*/
|
|
490
|
+
checkMemberAccessibility(file, expression, typeChain) {
|
|
491
|
+
var _a, _b, _c;
|
|
492
|
+
for (let i = 0; i < typeChain.length - 1; i++) {
|
|
493
|
+
const parentChainItem = typeChain[i];
|
|
494
|
+
const childChainItem = typeChain[i + 1];
|
|
495
|
+
if ((0, reflection_1.isClassType)(parentChainItem.type)) {
|
|
496
|
+
const containingClassStmt = expression.findAncestor(reflection_1.isClassStatement);
|
|
497
|
+
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);
|
|
498
|
+
if (classStmtThatDefinesChildMember) {
|
|
499
|
+
const definingClassName = classStmtThatDefinesChildMember.getName(Parser_1.ParseMode.BrighterScript);
|
|
500
|
+
const inMatchingClassStmt = (containingClassStmt === null || containingClassStmt === void 0 ? void 0 : containingClassStmt.getName(Parser_1.ParseMode.BrighterScript).toLowerCase()) === parentChainItem.type.name.toLowerCase();
|
|
501
|
+
// eslint-disable-next-line no-bitwise
|
|
502
|
+
if (childChainItem.data.flags & SymbolTable_1.SymbolTypeFlag.private) {
|
|
503
|
+
if (!inMatchingClassStmt || childChainItem.data.memberOfAncestor) {
|
|
504
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.memberAccessibilityMismatch(childChainItem.name, childChainItem.data.flags, definingClassName)), { range: expression.range, file: file }));
|
|
505
|
+
// there's an error... don't worry about the rest of the chain
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
177
508
|
}
|
|
178
|
-
//
|
|
179
|
-
if (
|
|
180
|
-
|
|
509
|
+
// eslint-disable-next-line no-bitwise
|
|
510
|
+
if (childChainItem.data.flags & SymbolTable_1.SymbolTypeFlag.protected) {
|
|
511
|
+
const containingClassName = containingClassStmt === null || containingClassStmt === void 0 ? void 0 : containingClassStmt.getName(Parser_1.ParseMode.BrighterScript);
|
|
512
|
+
const containingNamespaceName = (_c = expression.findAncestor(reflection_1.isNamespaceStatement)) === null || _c === void 0 ? void 0 : _c.getName(Parser_1.ParseMode.BrighterScript);
|
|
513
|
+
const ancestorClasses = this.event.scope.getClassHierarchy(containingClassName, containingNamespaceName).map(link => link.item);
|
|
514
|
+
const isSubClassOfDefiningClass = ancestorClasses.includes(classStmtThatDefinesChildMember);
|
|
515
|
+
if (!isSubClassOfDefiningClass) {
|
|
516
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.memberAccessibilityMismatch(childChainItem.name, childChainItem.data.flags, definingClassName)), { range: expression.range, file: file }));
|
|
517
|
+
// there's an error... don't worry about the rest of the chain
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
181
520
|
}
|
|
182
521
|
}
|
|
183
522
|
}
|
|
523
|
+
}
|
|
524
|
+
return true;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Adds a diagnostic to the first scope for this key. Prevents duplicate diagnostics
|
|
528
|
+
* for diagnostics where scope isn't important. (i.e. CreateObject validations)
|
|
529
|
+
*/
|
|
530
|
+
addDiagnosticOnce(diagnostic) {
|
|
531
|
+
this.onceCache.getOrAdd(`${diagnostic.code}-${diagnostic.message}-${util_1.default.rangeToString(diagnostic.range)}`, () => {
|
|
532
|
+
const diagnosticWithOrigin = Object.assign({}, diagnostic);
|
|
533
|
+
if (!diagnosticWithOrigin.origin) {
|
|
534
|
+
// diagnostic does not have origin.
|
|
535
|
+
// set the origin to the current astSegment
|
|
536
|
+
diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
|
|
537
|
+
diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
|
|
538
|
+
}
|
|
539
|
+
this.event.scope.addDiagnostics([diagnosticWithOrigin]);
|
|
540
|
+
return true;
|
|
184
541
|
});
|
|
185
|
-
|
|
542
|
+
}
|
|
543
|
+
addDiagnostic(diagnostic) {
|
|
544
|
+
const diagnosticWithOrigin = Object.assign({}, diagnostic);
|
|
545
|
+
if (!diagnosticWithOrigin.origin) {
|
|
546
|
+
// diagnostic does not have origin.
|
|
547
|
+
// set the origin to the current astSegment
|
|
548
|
+
diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
|
|
549
|
+
diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
|
|
550
|
+
}
|
|
551
|
+
this.event.scope.addDiagnostics([diagnosticWithOrigin]);
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Add a diagnostic (to the first scope) that will have `relatedInformation` for each affected scope
|
|
555
|
+
*/
|
|
556
|
+
addMultiScopeDiagnostic(diagnostic) {
|
|
557
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
558
|
+
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)}`, () => {
|
|
559
|
+
if (!diagnostic.relatedInformation) {
|
|
560
|
+
diagnostic.relatedInformation = [];
|
|
561
|
+
}
|
|
562
|
+
const diagnosticWithOrigin = Object.assign({}, diagnostic);
|
|
563
|
+
if (!diagnosticWithOrigin.origin) {
|
|
564
|
+
// diagnostic does not have origin.
|
|
565
|
+
// set the origin to the current astSegment
|
|
566
|
+
diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
|
|
567
|
+
diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
|
|
568
|
+
}
|
|
569
|
+
this.addDiagnostic(diagnosticWithOrigin);
|
|
570
|
+
return diagnosticWithOrigin;
|
|
571
|
+
});
|
|
572
|
+
if ((0, reflection_1.isXmlScope)(this.event.scope) && ((_b = this.event.scope.xmlFile) === null || _b === void 0 ? void 0 : _b.srcPath)) {
|
|
573
|
+
diagnostic.relatedInformation.push({
|
|
574
|
+
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}'`,
|
|
575
|
+
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))
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
diagnostic.relatedInformation.push({
|
|
580
|
+
message: `In scope '${this.event.scope.name}'`,
|
|
581
|
+
location: util_1.default.createLocation(vscode_uri_1.URI.file(diagnostic.file.srcPath).toString(), diagnostic.range)
|
|
582
|
+
});
|
|
583
|
+
}
|
|
186
584
|
}
|
|
187
585
|
}
|
|
188
586
|
exports.ScopeValidator = ScopeValidator;
|