brighterscript 1.0.0-alpha.24 → 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 +493 -233
- 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 +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 +831 -695
- 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 +87 -133
- package/dist/Scope.js +450 -510
- 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 -6
- package/dist/XmlScope.js +74 -69
- 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 -104
- package/dist/astUtils/reflection.js +220 -174
- 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 +53 -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 +10 -2
- package/dist/bscPlugin/BscPlugin.js +33 -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.js +14 -11
- 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/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 +85 -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.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} +33 -9
- 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 +259 -49
- 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 +54 -27
- package/dist/bscPlugin/validation/ScopeValidator.js +483 -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 +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 +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 +112 -111
- package/dist/files/BrsFile.js +741 -1032
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1728 -1232
- 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 +389 -161
- 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 +126 -176
- package/dist/parser/Expression.js +523 -405
- 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 +43 -201
- package/dist/parser/Parser.js +446 -962
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +1002 -846
- 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 +183 -131
- package/dist/parser/Statement.js +549 -387
- 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 +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 +35 -33
- 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 +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 +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 +132 -137
- package/dist/util.js +796 -362
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +8 -25
- package/dist/validators/ClassValidator.js +96 -176
- 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/serialize/BslibInjector.spec.d.ts} +0 -0
package/dist/Scope.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Scope = void 0;
|
|
4
|
-
const
|
|
4
|
+
const path = require("path");
|
|
5
5
|
const chalk_1 = require("chalk");
|
|
6
6
|
const DiagnosticMessages_1 = require("./DiagnosticMessages");
|
|
7
|
+
const interfaces_1 = require("./interfaces");
|
|
7
8
|
const ClassValidator_1 = require("./validators/ClassValidator");
|
|
8
9
|
const Parser_1 = require("./parser/Parser");
|
|
9
10
|
const util_1 = require("./util");
|
|
@@ -13,9 +14,18 @@ const vscode_uri_1 = require("vscode-uri");
|
|
|
13
14
|
const Logger_1 = require("./Logger");
|
|
14
15
|
const reflection_1 = require("./astUtils/reflection");
|
|
15
16
|
const SymbolTable_1 = require("./SymbolTable");
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
17
|
+
const NamespaceType_1 = require("./types/NamespaceType");
|
|
18
|
+
const ReferenceType_1 = require("./types/ReferenceType");
|
|
19
|
+
const UnionType_1 = require("./types/UnionType");
|
|
20
|
+
const AssociativeArrayType_1 = require("./types/AssociativeArrayType");
|
|
21
|
+
const AstNode_1 = require("./parser/AstNode");
|
|
22
|
+
const visitors_1 = require("./astUtils/visitors");
|
|
23
|
+
/**
|
|
24
|
+
* Assign some few factories to the SymbolTable to prevent cyclical imports. This file seems like the most intuitive place to do the linking
|
|
25
|
+
* since Scope will be used by pretty much everything
|
|
26
|
+
*/
|
|
27
|
+
SymbolTable_1.SymbolTable.referenceTypeFactory = ReferenceType_1.referenceTypeFactory;
|
|
28
|
+
SymbolTable_1.SymbolTable.unionTypeFactory = UnionType_1.unionTypeFactory;
|
|
19
29
|
/**
|
|
20
30
|
* A class to keep track of all declarations within a given scope (like source scope, component scope)
|
|
21
31
|
*/
|
|
@@ -29,6 +39,11 @@ class Scope {
|
|
|
29
39
|
* The list of diagnostics found specifically for this scope. Individual file diagnostics are stored on the files themselves.
|
|
30
40
|
*/
|
|
31
41
|
this.diagnostics = [];
|
|
42
|
+
/**
|
|
43
|
+
* A list of functions that will be called whenever `unlinkSymbolTable` is called
|
|
44
|
+
*/
|
|
45
|
+
this.linkSymbolTableDisposables = [];
|
|
46
|
+
this.symbolsAddedDuringLinking = [];
|
|
32
47
|
this.isValidated = false;
|
|
33
48
|
//used for improved logging performance
|
|
34
49
|
this._debugLogComponentName = `Scope '${chalk_1.default.redBright(this.name)}'`;
|
|
@@ -42,8 +57,52 @@ class Scope {
|
|
|
42
57
|
* "namea", "namea.nameb", "namea.nameb.namec"
|
|
43
58
|
*/
|
|
44
59
|
get namespaceLookup() {
|
|
60
|
+
let allFilesValidated = true;
|
|
61
|
+
for (const file of this.getAllFiles()) {
|
|
62
|
+
if ((0, reflection_1.isBrsFile)(file) && !file.hasTypedef) {
|
|
63
|
+
allFilesValidated = allFilesValidated && file.isValidated;
|
|
64
|
+
if (!allFilesValidated) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!allFilesValidated) {
|
|
70
|
+
// This is not fit to cache
|
|
71
|
+
// Since the files have not been validated, all namespace info might not have been available
|
|
72
|
+
return this.buildNamespaceLookup();
|
|
73
|
+
}
|
|
45
74
|
return this.cache.getOrAdd('namespaceLookup', () => this.buildNamespaceLookup());
|
|
46
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Get a NamespaceContainer by its name, looking for a fully qualified version first, then global version next if not found
|
|
78
|
+
*/
|
|
79
|
+
getNamespace(name, containingNamespace) {
|
|
80
|
+
const nameLower = name === null || name === void 0 ? void 0 : name.toLowerCase();
|
|
81
|
+
const lookup = this.namespaceLookup;
|
|
82
|
+
let ns;
|
|
83
|
+
if (containingNamespace) {
|
|
84
|
+
ns = lookup.get(`${containingNamespace === null || containingNamespace === void 0 ? void 0 : containingNamespace.toLowerCase()}.${nameLower}`);
|
|
85
|
+
}
|
|
86
|
+
//if we couldn't find the namespace by its full namespaced name, look for a global version
|
|
87
|
+
if (!ns) {
|
|
88
|
+
ns = lookup.get(nameLower);
|
|
89
|
+
}
|
|
90
|
+
return ns;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get a NamespaceContainer by its name, looking for a fully qualified version first, then global version next if not found
|
|
94
|
+
*/
|
|
95
|
+
getNamespacesWithRoot(rootName, containingNamespace) {
|
|
96
|
+
const nameLower = rootName === null || rootName === void 0 ? void 0 : rootName.toLowerCase();
|
|
97
|
+
const lookup = this.namespaceLookup;
|
|
98
|
+
const lookupKeys = [...lookup.keys()];
|
|
99
|
+
let lookupName = nameLower;
|
|
100
|
+
if (containingNamespace) {
|
|
101
|
+
lookupName = `${containingNamespace === null || containingNamespace === void 0 ? void 0 : containingNamespace.toLowerCase()}.${nameLower}`;
|
|
102
|
+
}
|
|
103
|
+
const nsList = lookupKeys.filter(key => key === lookupName).map(key => lookup.get(key));
|
|
104
|
+
return nsList;
|
|
105
|
+
}
|
|
47
106
|
/**
|
|
48
107
|
* Get the class with the specified name.
|
|
49
108
|
* @param className - The class name, including the namespace of the class if possible
|
|
@@ -62,23 +121,6 @@ class Scope {
|
|
|
62
121
|
var _a;
|
|
63
122
|
return (_a = this.getInterfaceFileLink(ifaceName, containingNamespace)) === null || _a === void 0 ? void 0 : _a.item;
|
|
64
123
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Get either the class or interface, etc. with a given name
|
|
67
|
-
* @param name - The name, including the namespace of the interface if possible
|
|
68
|
-
* @param containingNamespace - The namespace used to resolve relative names. (i.e. the namespace around the current statement trying to find the interface or class)
|
|
69
|
-
*/
|
|
70
|
-
getNamedTypeStatement(name, containingNamespace) {
|
|
71
|
-
var _a;
|
|
72
|
-
return (_a = this.getNamedTypeFileLink(name, containingNamespace)) === null || _a === void 0 ? void 0 : _a.item;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* A cache of a map of tokens -> TokenSymbolLookups, which are the result of getSymbolTypeFromToken()
|
|
76
|
-
* Sometimes the lookup of symbols may take a while if there are lazyTypes or multiple tokens in a chain
|
|
77
|
-
* By caching the result of this lookup, subsequent lookups of the same tokens are quicker
|
|
78
|
-
*/
|
|
79
|
-
get symbolCache() {
|
|
80
|
-
return this.cache.getOrAdd('symbolCache', () => new Map());
|
|
81
|
-
}
|
|
82
124
|
/**
|
|
83
125
|
* Get the enum with the specified name.
|
|
84
126
|
* @param enumName - The enum name, including the namespace if possible
|
|
@@ -104,10 +146,10 @@ class Scope {
|
|
|
104
146
|
return cls;
|
|
105
147
|
}
|
|
106
148
|
/**
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
149
|
+
* Get an interface and its containing file by the interface name
|
|
150
|
+
* @param ifaceName - The interface name, including the namespace of the interface if possible
|
|
151
|
+
* @param containingNamespace - The namespace used to resolve relative interface names. (i.e. the namespace around the current statement trying to find a interface)
|
|
152
|
+
*/
|
|
111
153
|
getInterfaceFileLink(ifaceName, containingNamespace) {
|
|
112
154
|
const lowerName = ifaceName === null || ifaceName === void 0 ? void 0 : ifaceName.toLowerCase();
|
|
113
155
|
const ifaceMap = this.getInterfaceMap();
|
|
@@ -134,34 +176,24 @@ class Scope {
|
|
|
134
176
|
return enumeration;
|
|
135
177
|
}
|
|
136
178
|
/**
|
|
137
|
-
* Get
|
|
138
|
-
* @param
|
|
139
|
-
* @param containingNamespace - The namespace used to resolve relative names. (i.e. the namespace around the current statement trying to find a
|
|
140
|
-
*/
|
|
141
|
-
getNamedTypeFileLink(name, containingNamespace) {
|
|
142
|
-
return this.getInheritableFileLink(name, containingNamespace) || this.getEnumFileLink(name, containingNamespace);
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Get a InheritableStatement and its containing file by the name of the interface or class
|
|
146
|
-
* @param name - The name of the interface or class, including the namespace of the class if possible
|
|
147
|
-
* @param containingNamespace - The namespace used to resolve relative names. (i.e. the namespace around the current statement trying to find a class)
|
|
148
|
-
*/
|
|
149
|
-
getInheritableFileLink(name, containingNamespace) {
|
|
150
|
-
return this.getClassFileLink(name, containingNamespace) || this.getInterfaceFileLink(name, containingNamespace);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Gets the parent class of the given class
|
|
154
|
-
* @param klass - The class to get the parent of, if possible
|
|
179
|
+
* Get an Enum and its containing file by the Enum name
|
|
180
|
+
* @param enumMemberName - The Enum name, including the namespace of the enum if possible
|
|
181
|
+
* @param containingNamespace - The namespace used to resolve relative enum names. (i.e. the namespace around the current statement trying to find a enum)
|
|
155
182
|
*/
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
183
|
+
getEnumMemberFileLink(enumMemberName, containingNamespace) {
|
|
184
|
+
var _a, _b;
|
|
185
|
+
let lowerNameParts = (_a = enumMemberName === null || enumMemberName === void 0 ? void 0 : enumMemberName.toLowerCase()) === null || _a === void 0 ? void 0 : _a.split('.');
|
|
186
|
+
let memberName = (_b = lowerNameParts === null || lowerNameParts === void 0 ? void 0 : lowerNameParts.splice(lowerNameParts.length - 1, 1)) === null || _b === void 0 ? void 0 : _b[0];
|
|
187
|
+
let lowerName = lowerNameParts === null || lowerNameParts === void 0 ? void 0 : lowerNameParts.join('.');
|
|
188
|
+
const enumMap = this.getEnumMap();
|
|
189
|
+
let enumeration = enumMap.get(util_1.util.getFullyQualifiedClassName(lowerName, containingNamespace === null || containingNamespace === void 0 ? void 0 : containingNamespace.toLowerCase()));
|
|
190
|
+
//if we couldn't find the enum by its full namespaced name, look for a global enum with that name
|
|
191
|
+
if (!enumeration) {
|
|
192
|
+
enumeration = enumMap.get(lowerName);
|
|
193
|
+
}
|
|
194
|
+
if (enumeration) {
|
|
195
|
+
let member = enumeration.item.findChild((child) => { var _a; return (0, reflection_1.isEnumMemberStatement)(child) && ((_a = child.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === memberName; });
|
|
196
|
+
return member ? { item: member, file: enumeration.file } : undefined;
|
|
165
197
|
}
|
|
166
198
|
}
|
|
167
199
|
/**
|
|
@@ -179,38 +211,33 @@ class Scope {
|
|
|
179
211
|
}
|
|
180
212
|
return result;
|
|
181
213
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if (
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (foundParent) {
|
|
192
|
-
return foundParent.item;
|
|
193
|
-
}
|
|
214
|
+
getAllFileLinks(name, containingNamespace) {
|
|
215
|
+
var _a, _b, _c, _d, _e, _f;
|
|
216
|
+
let links = [];
|
|
217
|
+
links.push((_a = this.getClassFileLink(name)) !== null && _a !== void 0 ? _a : this.getClassFileLink(name, containingNamespace), (_b = this.getInterfaceFileLink(name)) !== null && _b !== void 0 ? _b : this.getInterfaceFileLink(name, containingNamespace), (_c = this.getConstFileLink(name)) !== null && _c !== void 0 ? _c : this.getConstFileLink(name, containingNamespace), (_d = this.getEnumFileLink(name)) !== null && _d !== void 0 ? _d : this.getEnumFileLink(name, containingNamespace));
|
|
218
|
+
const nameSpaces = this.getNamespacesWithRoot(name, containingNamespace);
|
|
219
|
+
if ((nameSpaces === null || nameSpaces === void 0 ? void 0 : nameSpaces.length) > 0) {
|
|
220
|
+
const nsContainersWithStatement = (_e = nameSpaces.filter(nsContainer => { var _a; return ((_a = nsContainer === null || nsContainer === void 0 ? void 0 : nsContainer.namespaceStatements) === null || _a === void 0 ? void 0 : _a.length) > 0; })) === null || _e === void 0 ? void 0 : _e[0];
|
|
221
|
+
if (nsContainersWithStatement) {
|
|
222
|
+
links.push({ item: (_f = nsContainersWithStatement === null || nsContainersWithStatement === void 0 ? void 0 : nsContainersWithStatement.namespaceStatements) === null || _f === void 0 ? void 0 : _f[0], file: nsContainersWithStatement === null || nsContainersWithStatement === void 0 ? void 0 : nsContainersWithStatement.file });
|
|
194
223
|
}
|
|
195
224
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
return this.getParentInterface(stmt);
|
|
204
|
-
}
|
|
205
|
-
else if ((0, reflection_1.isClassStatement)(stmt)) {
|
|
206
|
-
return this.getParentClass(stmt);
|
|
225
|
+
const fullNameLower = (containingNamespace ? `${containingNamespace}.${name}` : name).toLowerCase();
|
|
226
|
+
const callable = this.getCallableByName(name);
|
|
227
|
+
if (callable) {
|
|
228
|
+
if (!callable.hasNamespace || callable.getName(Parser_1.ParseMode.BrighterScript).toLowerCase() === fullNameLower) {
|
|
229
|
+
// this callable has no namespace, or has same namespace
|
|
230
|
+
links.push({ item: callable.functionStatement, file: callable.file });
|
|
231
|
+
}
|
|
207
232
|
}
|
|
233
|
+
// remove empty links
|
|
234
|
+
return links.filter(link => link);
|
|
208
235
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
236
|
+
/**
|
|
237
|
+
* Get a map of all enums by their member name.
|
|
238
|
+
* The keys are lower-case fully-qualified paths to the enum and its member. For example:
|
|
239
|
+
* namespace.enum.value
|
|
240
|
+
*/
|
|
214
241
|
getEnumMemberMap() {
|
|
215
242
|
return this.cache.getOrAdd('enumMemberMap', () => {
|
|
216
243
|
const result = new Map();
|
|
@@ -223,36 +250,28 @@ class Scope {
|
|
|
223
250
|
});
|
|
224
251
|
}
|
|
225
252
|
/**
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
253
|
+
* Tests if a class exists with the specified name
|
|
254
|
+
* @param className - the all-lower-case namespace-included class name
|
|
255
|
+
* @param namespaceName - The namespace used to resolve relative class names. (i.e. the namespace around the current statement trying to find a class)
|
|
256
|
+
*/
|
|
230
257
|
hasClass(className, namespaceName) {
|
|
231
258
|
return !!this.getClass(className, namespaceName);
|
|
232
259
|
}
|
|
233
260
|
/**
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
261
|
+
* Tests if an interface exists with the specified name
|
|
262
|
+
* @param ifaceName - the all-lower-case namespace-included interface name
|
|
263
|
+
* @param namespaceName - the current namespace name
|
|
264
|
+
*/
|
|
238
265
|
hasInterface(ifaceName, namespaceName) {
|
|
239
266
|
return !!this.getInterface(ifaceName, namespaceName);
|
|
240
267
|
}
|
|
241
268
|
/**
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
* @param namespaceName - the current namespace name
|
|
245
|
-
*/
|
|
246
|
-
hasEnum(enumName, namespaceName) {
|
|
247
|
-
return !!this.getEnum(enumName, namespaceName);
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Tests if a class OR an interface, etc. exists with the specified name
|
|
251
|
-
* @param name - the all-lower-case namespace-included class or interface name
|
|
269
|
+
* Tests if an enum exists with the specified name
|
|
270
|
+
* @param enumName - the all-lower-case namespace-included enum name
|
|
252
271
|
* @param namespaceName - the current namespace name
|
|
253
272
|
*/
|
|
254
|
-
|
|
255
|
-
return !!this.
|
|
273
|
+
hasEnum(enumName, namespaceName) {
|
|
274
|
+
return !!this.getEnum(enumName, namespaceName);
|
|
256
275
|
}
|
|
257
276
|
/**
|
|
258
277
|
* A dictionary of all classes in this scope. This includes namespaced classes always with their full name.
|
|
@@ -262,13 +281,12 @@ class Scope {
|
|
|
262
281
|
return this.cache.getOrAdd('classMap', () => {
|
|
263
282
|
const map = new Map();
|
|
264
283
|
this.enumerateBrsFiles((file) => {
|
|
265
|
-
var _a;
|
|
266
284
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
267
|
-
for (let cls of file.
|
|
268
|
-
const
|
|
285
|
+
for (let cls of file['_cachedLookups'].classStatements) {
|
|
286
|
+
const className = cls.getName(Parser_1.ParseMode.BrighterScript);
|
|
269
287
|
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
270
|
-
if (
|
|
271
|
-
map.set(
|
|
288
|
+
if (className) {
|
|
289
|
+
map.set(className.toLowerCase(), { item: cls, file: file });
|
|
272
290
|
}
|
|
273
291
|
}
|
|
274
292
|
}
|
|
@@ -276,29 +294,20 @@ class Scope {
|
|
|
276
294
|
return map;
|
|
277
295
|
});
|
|
278
296
|
}
|
|
279
|
-
getAncestorTypeListByContext(thisType, context) {
|
|
280
|
-
var _a;
|
|
281
|
-
const funcExpr = (_a = context === null || context === void 0 ? void 0 : context.file) === null || _a === void 0 ? void 0 : _a.getFunctionExpressionAtPosition(context === null || context === void 0 ? void 0 : context.position);
|
|
282
|
-
if ((0, reflection_1.isCustomType)(thisType) || (0, reflection_1.isInterfaceType)(thisType)) {
|
|
283
|
-
return this.getAncestorTypeList(thisType.name, funcExpr);
|
|
284
|
-
}
|
|
285
|
-
return [];
|
|
286
|
-
}
|
|
287
297
|
/**
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
298
|
+
* A dictionary of all Interfaces in this scope. This includes namespaced Interfaces always with their full name.
|
|
299
|
+
* The key is stored in lower case
|
|
300
|
+
*/
|
|
291
301
|
getInterfaceMap() {
|
|
292
302
|
return this.cache.getOrAdd('interfaceMap', () => {
|
|
293
303
|
const map = new Map();
|
|
294
304
|
this.enumerateBrsFiles((file) => {
|
|
295
|
-
var _a;
|
|
296
305
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
297
|
-
for (let iface of file.
|
|
298
|
-
const
|
|
306
|
+
for (let iface of file['_cachedLookups'].interfaceStatements) {
|
|
307
|
+
const ifaceName = iface.getName(Parser_1.ParseMode.BrighterScript);
|
|
299
308
|
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
300
|
-
if (
|
|
301
|
-
map.set(
|
|
309
|
+
if (ifaceName) {
|
|
310
|
+
map.set(ifaceName.toLowerCase(), { item: iface, file: file });
|
|
302
311
|
}
|
|
303
312
|
}
|
|
304
313
|
}
|
|
@@ -306,21 +315,6 @@ class Scope {
|
|
|
306
315
|
return map;
|
|
307
316
|
});
|
|
308
317
|
}
|
|
309
|
-
getAncestorTypeList(className, functionExpression) {
|
|
310
|
-
var _a, _b;
|
|
311
|
-
const lowerNamespaceName = (_a = functionExpression.namespaceName) === null || _a === void 0 ? void 0 : _a.getName().toLowerCase();
|
|
312
|
-
const ancestors = [];
|
|
313
|
-
let currentClassOrIFace = (_b = this.getInheritableFileLink(className, lowerNamespaceName)) === null || _b === void 0 ? void 0 : _b.item;
|
|
314
|
-
if (currentClassOrIFace) {
|
|
315
|
-
ancestors.push(currentClassOrIFace === null || currentClassOrIFace === void 0 ? void 0 : currentClassOrIFace.getThisBscType());
|
|
316
|
-
}
|
|
317
|
-
while (currentClassOrIFace === null || currentClassOrIFace === void 0 ? void 0 : currentClassOrIFace.hasParent()) {
|
|
318
|
-
currentClassOrIFace = this.getParentStatement(currentClassOrIFace);
|
|
319
|
-
ancestors.push(currentClassOrIFace === null || currentClassOrIFace === void 0 ? void 0 : currentClassOrIFace.getThisBscType());
|
|
320
|
-
}
|
|
321
|
-
// TODO TYPES: this should probably be cached
|
|
322
|
-
return ancestors;
|
|
323
|
-
}
|
|
324
318
|
/**
|
|
325
319
|
* A dictionary of all enums in this scope. This includes namespaced enums always with their full name.
|
|
326
320
|
* The key is stored in lower case
|
|
@@ -329,11 +323,10 @@ class Scope {
|
|
|
329
323
|
return this.cache.getOrAdd('enumMap', () => {
|
|
330
324
|
const map = new Map();
|
|
331
325
|
this.enumerateBrsFiles((file) => {
|
|
332
|
-
for (let enumStmt of file.
|
|
333
|
-
const lowerEnumName = enumStmt.fullName.toLowerCase();
|
|
326
|
+
for (let enumStmt of file['_cachedLookups'].enumStatements) {
|
|
334
327
|
//only track enums with a defined name (i.e. exclude nameless malformed enums)
|
|
335
|
-
if (
|
|
336
|
-
map.set(
|
|
328
|
+
if (enumStmt.fullName) {
|
|
329
|
+
map.set(enumStmt.fullName.toLowerCase(), { item: enumStmt, file: file });
|
|
337
330
|
}
|
|
338
331
|
}
|
|
339
332
|
});
|
|
@@ -348,11 +341,10 @@ class Scope {
|
|
|
348
341
|
return this.cache.getOrAdd('constMap', () => {
|
|
349
342
|
const map = new Map();
|
|
350
343
|
this.enumerateBrsFiles((file) => {
|
|
351
|
-
for (let stmt of file.
|
|
352
|
-
const lowerEnumName = stmt.fullName.toLowerCase();
|
|
344
|
+
for (let stmt of file['_cachedLookups'].constStatements) {
|
|
353
345
|
//only track enums with a defined name (i.e. exclude nameless malformed enums)
|
|
354
|
-
if (
|
|
355
|
-
map.set(
|
|
346
|
+
if (stmt.fullName) {
|
|
347
|
+
map.set(stmt.fullName.toLowerCase(), { item: stmt, file: file });
|
|
356
348
|
}
|
|
357
349
|
}
|
|
358
350
|
});
|
|
@@ -377,7 +369,7 @@ class Scope {
|
|
|
377
369
|
isKnownNamespace(namespaceName) {
|
|
378
370
|
let namespaceNameLower = namespaceName.toLowerCase();
|
|
379
371
|
this.enumerateBrsFiles((file) => {
|
|
380
|
-
for (let namespace of file.
|
|
372
|
+
for (let namespace of file['_cachedLookups'].namespaceStatements) {
|
|
381
373
|
let loopNamespaceNameLower = namespace.name.toLowerCase();
|
|
382
374
|
if (loopNamespaceNameLower === namespaceNameLower || loopNamespaceNameLower.startsWith(namespaceNameLower + '.')) {
|
|
383
375
|
return true;
|
|
@@ -393,7 +385,7 @@ class Scope {
|
|
|
393
385
|
*/
|
|
394
386
|
getParentScope() {
|
|
395
387
|
let scope;
|
|
396
|
-
//use the global scope if we didn't find a
|
|
388
|
+
//use the global scope if we didn't find a sope and this is not the global scope
|
|
397
389
|
if (this.program.globalScope !== this) {
|
|
398
390
|
scope = this.program.globalScope;
|
|
399
391
|
}
|
|
@@ -416,20 +408,23 @@ class Scope {
|
|
|
416
408
|
this.invalidate();
|
|
417
409
|
}
|
|
418
410
|
/**
|
|
419
|
-
* Get the file with the
|
|
420
|
-
* @param filePath can be a srcPath
|
|
411
|
+
* Get the file from this scope with the given path.
|
|
412
|
+
* @param filePath can be a srcPath or destPath
|
|
421
413
|
* @param normalizePath should this function repair and standardize the path? Passing false should have a performance boost if you can guarantee your path is already sanitized
|
|
422
414
|
*/
|
|
423
|
-
getFile(
|
|
424
|
-
if (
|
|
425
|
-
|
|
415
|
+
getFile(filePath, normalizePath = true) {
|
|
416
|
+
if (typeof filePath !== 'string') {
|
|
417
|
+
return undefined;
|
|
426
418
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
419
|
+
const key = path.isAbsolute(filePath) ? 'srcPath' : 'destPath';
|
|
420
|
+
let map = this.cache.getOrAdd('fileMaps-srcPath', () => {
|
|
421
|
+
const result = new Map();
|
|
422
|
+
for (const file of this.getAllFiles()) {
|
|
423
|
+
result.set(file[key].toLowerCase(), file);
|
|
431
424
|
}
|
|
432
|
-
|
|
425
|
+
return result;
|
|
426
|
+
});
|
|
427
|
+
return map.get((normalizePath ? util_1.util.standardizePath(filePath) : filePath).toLowerCase());
|
|
433
428
|
}
|
|
434
429
|
/**
|
|
435
430
|
* Get the list of files referenced by this scope that are actually loaded in the program.
|
|
@@ -456,32 +451,32 @@ class Scope {
|
|
|
456
451
|
}
|
|
457
452
|
}
|
|
458
453
|
else {
|
|
459
|
-
let file = this.program.getFile(dependency
|
|
454
|
+
let file = this.program.getFile(dependency);
|
|
460
455
|
if (file) {
|
|
461
456
|
result.push(file);
|
|
462
457
|
}
|
|
463
458
|
}
|
|
464
459
|
}
|
|
465
|
-
this.logDebug('getAllFiles', () => result.map(x => x.
|
|
460
|
+
this.logDebug('getAllFiles', () => result.map(x => x.destPath));
|
|
466
461
|
return result;
|
|
467
462
|
});
|
|
468
463
|
}
|
|
469
464
|
/**
|
|
470
|
-
* Get the list of errors for this scope. It's calculated on the fly, so
|
|
471
|
-
* call this sparingly.
|
|
465
|
+
* Get the list of errors for this scope. It's calculated on the fly, so call this sparingly.
|
|
472
466
|
*/
|
|
473
467
|
getDiagnostics() {
|
|
474
|
-
let diagnosticLists = [this.diagnostics];
|
|
475
468
|
//add diagnostics from every referenced file
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
469
|
+
const diagnostics = [
|
|
470
|
+
//diagnostics raised on this scope
|
|
471
|
+
...this.diagnostics,
|
|
472
|
+
//get diagnostics from all files
|
|
473
|
+
...this.getOwnFiles().map(x => { var _a; return (_a = x.diagnostics) !== null && _a !== void 0 ? _a : []; }).flat()
|
|
474
|
+
]
|
|
475
|
+
//exclude diagnostics that match any of the comment flags
|
|
476
|
+
.filter((x) => {
|
|
481
477
|
return !util_1.util.diagnosticIsSuppressed(x);
|
|
482
478
|
});
|
|
483
|
-
|
|
484
|
-
return filteredDiagnostics;
|
|
479
|
+
return diagnostics;
|
|
485
480
|
}
|
|
486
481
|
addDiagnostics(diagnostics) {
|
|
487
482
|
this.diagnostics.push(...diagnostics);
|
|
@@ -502,27 +497,23 @@ class Scope {
|
|
|
502
497
|
/**
|
|
503
498
|
* Get the callable with the specified name.
|
|
504
499
|
* If there are overridden callables with the same name, the closest callable to this scope is returned
|
|
505
|
-
* @param name
|
|
506
500
|
*/
|
|
507
501
|
getCallableByName(name) {
|
|
508
|
-
|
|
509
|
-
let lowerName = name.toLowerCase();
|
|
510
|
-
let callables = this.getAllCallables();
|
|
511
|
-
for (let callable of callables) {
|
|
512
|
-
const callableName = callable.callable.getName(Parser_1.ParseMode.BrighterScript);
|
|
513
|
-
// Split by `.` and check the last term to consider namespaces.
|
|
514
|
-
if (callableName.toLowerCase() === lowerName || ((_a = callableName.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === lowerName) {
|
|
515
|
-
return callable.callable;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
502
|
+
return this.getCallableMap().get(name.toLowerCase());
|
|
518
503
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
504
|
+
getCallableMap() {
|
|
505
|
+
return this.cache.getOrAdd('callableMap', () => {
|
|
506
|
+
var _a, _b;
|
|
507
|
+
const result = new Map();
|
|
508
|
+
for (let callable of this.getAllCallables()) {
|
|
509
|
+
const callableName = (_a = callable.callable.getName(Parser_1.ParseMode.BrighterScript)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
510
|
+
result.set(callableName, callable.callable);
|
|
511
|
+
result.set(
|
|
512
|
+
// Split by `.` and check the last term to consider namespaces.
|
|
513
|
+
(_b = callableName.split('.').pop()) === null || _b === void 0 ? void 0 : _b.toLowerCase(), callable.callable);
|
|
514
|
+
}
|
|
515
|
+
return result;
|
|
516
|
+
});
|
|
526
517
|
}
|
|
527
518
|
/**
|
|
528
519
|
* Iterate over Brs files not shadowed by typedefs
|
|
@@ -543,7 +534,7 @@ class Scope {
|
|
|
543
534
|
const files = this.getOwnFiles();
|
|
544
535
|
for (const file of files) {
|
|
545
536
|
//either XML components or files without a typedef
|
|
546
|
-
if ((0, reflection_1.isXmlFile)(file) || !file.hasTypedef) {
|
|
537
|
+
if ((0, reflection_1.isXmlFile)(file) || ((0, reflection_1.isBrsFile)(file) && !file.hasTypedef)) {
|
|
547
538
|
callback(file);
|
|
548
539
|
}
|
|
549
540
|
}
|
|
@@ -554,14 +545,16 @@ class Scope {
|
|
|
554
545
|
*/
|
|
555
546
|
getOwnCallables() {
|
|
556
547
|
let result = [];
|
|
557
|
-
this.logDebug('getOwnCallables() files: ', () => this.getOwnFiles().map(x => x.
|
|
548
|
+
this.logDebug('getOwnCallables() files: ', () => this.getOwnFiles().map(x => x.destPath));
|
|
558
549
|
//get callables from own files
|
|
559
550
|
this.enumerateOwnFiles((file) => {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
551
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
552
|
+
for (let callable of file.callables) {
|
|
553
|
+
result.push({
|
|
554
|
+
callable: callable,
|
|
555
|
+
scope: this
|
|
556
|
+
});
|
|
557
|
+
}
|
|
565
558
|
}
|
|
566
559
|
});
|
|
567
560
|
return result;
|
|
@@ -569,68 +562,27 @@ class Scope {
|
|
|
569
562
|
/**
|
|
570
563
|
* Builds a tree of namespace objects
|
|
571
564
|
*/
|
|
572
|
-
buildNamespaceLookup() {
|
|
565
|
+
buildNamespaceLookup(options = { okToCache: true }) {
|
|
573
566
|
let namespaceLookup = new Map();
|
|
567
|
+
options.okToCache = true;
|
|
574
568
|
this.enumerateBrsFiles((file) => {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
for (let part of nameParts) {
|
|
583
|
-
loopName = loopName === null ? part : `${loopName}.${part}`;
|
|
584
|
-
let lowerLoopName = loopName.toLowerCase();
|
|
585
|
-
if (!namespaceLookup.has(lowerLoopName)) {
|
|
586
|
-
namespaceLookup.set(lowerLoopName, {
|
|
587
|
-
file: file,
|
|
588
|
-
fullName: loopName,
|
|
589
|
-
nameRange: namespaceStatement.nameExpression.range,
|
|
590
|
-
lastPartName: part,
|
|
591
|
-
namespaces: new Map(),
|
|
592
|
-
classStatements: {},
|
|
593
|
-
functionStatements: {},
|
|
594
|
-
interfaceStatements: {},
|
|
595
|
-
enumStatements: new Map(),
|
|
596
|
-
constStatements: new Map(),
|
|
597
|
-
statements: [],
|
|
598
|
-
symbolTable: new SymbolTable_1.SymbolTable(this.symbolTable, `Namespace ${loopName}`)
|
|
599
|
-
});
|
|
600
|
-
}
|
|
569
|
+
options.okToCache = options.okToCache && file.isValidated;
|
|
570
|
+
const fileNamespaceLookup = file.getNamespaceLookupObject();
|
|
571
|
+
for (const [lowerNamespaceName, nsContainer] of fileNamespaceLookup) {
|
|
572
|
+
if (!namespaceLookup.has(lowerNamespaceName)) {
|
|
573
|
+
const clonedNsContainer = Object.assign(Object.assign({}, nsContainer), { namespaceStatements: [...nsContainer.namespaceStatements], symbolTable: new SymbolTable_1.SymbolTable(`Namespace Aggregate: '${nsContainer.fullName}'`) });
|
|
574
|
+
clonedNsContainer.symbolTable.mergeSymbolTable(nsContainer.symbolTable);
|
|
575
|
+
namespaceLookup.set(lowerNamespaceName, clonedNsContainer);
|
|
601
576
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
else if ((0, reflection_1.isFunctionStatement)(statement) && statement.name) {
|
|
612
|
-
ns.functionStatements[statement.name.text.toLowerCase()] = statement;
|
|
613
|
-
}
|
|
614
|
-
else if ((0, reflection_1.isEnumStatement)(statement) && statement.fullName) {
|
|
615
|
-
ns.enumStatements.set(statement.fullName.toLowerCase(), statement);
|
|
616
|
-
}
|
|
617
|
-
else if ((0, reflection_1.isConstStatement)(statement) && statement.fullName) {
|
|
618
|
-
ns.constStatements.set(statement.fullName.toLowerCase(), statement);
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
// Merges all the symbol tables of the namespace statements into the new symbol table created above.
|
|
622
|
-
// Set those symbol tables to have this new merged table as a parent
|
|
623
|
-
ns.symbolTable.mergeSymbolTable(namespaceStatement.symbolTable);
|
|
624
|
-
}
|
|
625
|
-
//associate child namespaces with their parents
|
|
626
|
-
for (let [, ns] of namespaceLookup) {
|
|
627
|
-
let parts = ns.fullName.split('.');
|
|
628
|
-
if (parts.length > 1) {
|
|
629
|
-
//remove the last part
|
|
630
|
-
parts.pop();
|
|
631
|
-
let parentName = parts.join('.');
|
|
632
|
-
const parent = namespaceLookup.get(parentName.toLowerCase());
|
|
633
|
-
parent.namespaces.set(ns.lastPartName.toLowerCase(), ns);
|
|
577
|
+
else {
|
|
578
|
+
const existingContainer = namespaceLookup.get(lowerNamespaceName);
|
|
579
|
+
existingContainer.classStatements = new Map([...existingContainer.classStatements, ...nsContainer.classStatements]);
|
|
580
|
+
existingContainer.constStatements = new Map([...existingContainer.constStatements, ...nsContainer.constStatements]);
|
|
581
|
+
existingContainer.enumStatements = new Map([...existingContainer.enumStatements, ...nsContainer.enumStatements]);
|
|
582
|
+
existingContainer.functionStatements = new Map([...existingContainer.functionStatements, ...nsContainer.functionStatements]);
|
|
583
|
+
existingContainer.namespaces = new Map([...existingContainer.namespaces, ...nsContainer.namespaces]);
|
|
584
|
+
existingContainer.namespaceStatements.push(...nsContainer.namespaceStatements);
|
|
585
|
+
existingContainer.symbolTable.mergeSymbolTable(nsContainer.symbolTable);
|
|
634
586
|
}
|
|
635
587
|
}
|
|
636
588
|
});
|
|
@@ -639,87 +591,96 @@ class Scope {
|
|
|
639
591
|
getAllNamespaceStatements() {
|
|
640
592
|
let result = [];
|
|
641
593
|
this.enumerateBrsFiles((file) => {
|
|
642
|
-
result.push(...file.
|
|
594
|
+
result.push(...file['_cachedLookups'].namespaceStatements);
|
|
643
595
|
});
|
|
644
596
|
return result;
|
|
645
597
|
}
|
|
646
598
|
logDebug(...args) {
|
|
647
599
|
this.program.logger.debug(this._debugLogComponentName, ...args);
|
|
648
600
|
}
|
|
649
|
-
validate() {
|
|
601
|
+
validate(validationOptions = { force: false }) {
|
|
602
|
+
//if this scope is already validated, no need to revalidate
|
|
603
|
+
if (this.isValidated === true && !validationOptions.force) {
|
|
604
|
+
this.logDebug('validate(): already validated');
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
650
607
|
this.program.logger.time(Logger_1.LogLevel.debug, [this._debugLogComponentName, 'validate()'], () => {
|
|
651
608
|
let parentScope = this.getParentScope();
|
|
652
609
|
//validate our parent before we validate ourself
|
|
653
|
-
if (
|
|
610
|
+
if (parentScope && parentScope.isValidated === false) {
|
|
654
611
|
this.logDebug('validate(): validating parent first');
|
|
655
|
-
parentScope.validate();
|
|
612
|
+
parentScope.validate(validationOptions);
|
|
656
613
|
}
|
|
657
614
|
//clear the scope's errors list (we will populate them from this method)
|
|
658
|
-
this.
|
|
615
|
+
this.clearScopeLevelDiagnostics();
|
|
616
|
+
let callables = this.getAllCallables();
|
|
617
|
+
//sort the callables by filepath and then method name, so the errors will be consistent
|
|
618
|
+
// eslint-disable-next-line prefer-arrow-callback
|
|
619
|
+
callables = callables.sort((a, b) => {
|
|
620
|
+
const pathA = a.callable.file.srcPath;
|
|
621
|
+
const pathB = b.callable.file.srcPath;
|
|
622
|
+
//sort by path
|
|
623
|
+
if (pathA < pathB) {
|
|
624
|
+
return -1;
|
|
625
|
+
}
|
|
626
|
+
else if (pathA > pathB) {
|
|
627
|
+
return 1;
|
|
628
|
+
}
|
|
629
|
+
//sort by function name
|
|
630
|
+
const funcA = b.callable.name;
|
|
631
|
+
const funcB = b.callable.name;
|
|
632
|
+
if (funcA < funcB) {
|
|
633
|
+
return -1;
|
|
634
|
+
}
|
|
635
|
+
else if (funcA > funcB) {
|
|
636
|
+
return 1;
|
|
637
|
+
}
|
|
638
|
+
return 0;
|
|
639
|
+
});
|
|
640
|
+
//get a list of all callables, indexed by their lower case names
|
|
641
|
+
let callableContainerMap = util_1.util.getCallableContainersByLowerName(callables);
|
|
659
642
|
//Since statements from files are shared across multiple scopes, we need to link those statements to the current scope
|
|
660
643
|
this.linkSymbolTable();
|
|
661
|
-
|
|
662
|
-
program: this.program,
|
|
663
|
-
scope: this
|
|
664
|
-
});
|
|
665
|
-
this.program.plugins.emit('onScopeValidate', {
|
|
644
|
+
const scopeValidateEvent = {
|
|
666
645
|
program: this.program,
|
|
667
|
-
scope: this
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
646
|
+
scope: this,
|
|
647
|
+
changedFiles: validationOptions === null || validationOptions === void 0 ? void 0 : validationOptions.changedFiles,
|
|
648
|
+
changedSymbols: validationOptions === null || validationOptions === void 0 ? void 0 : validationOptions.changedSymbols
|
|
649
|
+
};
|
|
650
|
+
this.program.plugins.emit('beforeScopeValidate', scopeValidateEvent);
|
|
651
|
+
this.program.plugins.emit('onScopeValidate', scopeValidateEvent);
|
|
652
|
+
this._validate(callableContainerMap);
|
|
653
|
+
this.program.plugins.emit('afterScopeValidate', scopeValidateEvent);
|
|
674
654
|
//unlink all symbol tables from this scope (so they don't accidentally stick around)
|
|
675
655
|
this.unlinkSymbolTable();
|
|
676
656
|
this.isValidated = true;
|
|
677
657
|
});
|
|
678
658
|
}
|
|
679
|
-
//Get a list of all callables, indexed by their lower case name
|
|
680
|
-
getCallableContainerMap() {
|
|
681
|
-
let callables = this.getAllCallables();
|
|
682
|
-
//sort the callables by filepath and then method name, so the errors will be consistent
|
|
683
|
-
// eslint-disable-next-line prefer-arrow-callback
|
|
684
|
-
callables = callables.sort((a, b) => {
|
|
685
|
-
const pathA = a.callable.file.srcPath;
|
|
686
|
-
const pathB = b.callable.file.srcPath;
|
|
687
|
-
//sort by path
|
|
688
|
-
if (pathA < pathB) {
|
|
689
|
-
return -1;
|
|
690
|
-
}
|
|
691
|
-
else if (pathA > pathB) {
|
|
692
|
-
return 1;
|
|
693
|
-
}
|
|
694
|
-
//sort by function name
|
|
695
|
-
const funcA = b.callable.name;
|
|
696
|
-
const funcB = b.callable.name;
|
|
697
|
-
if (funcA < funcB) {
|
|
698
|
-
return -1;
|
|
699
|
-
}
|
|
700
|
-
else if (funcA > funcB) {
|
|
701
|
-
return 1;
|
|
702
|
-
}
|
|
703
|
-
return 0;
|
|
704
|
-
});
|
|
705
|
-
//get a list of all callables, indexed by their lower case names
|
|
706
|
-
return util_1.util.getCallableContainersByLowerName(callables);
|
|
707
|
-
}
|
|
708
659
|
_validate(callableContainerMap) {
|
|
709
660
|
//find all duplicate function declarations
|
|
710
661
|
this.diagnosticFindDuplicateFunctionDeclarations(callableContainerMap);
|
|
711
662
|
//detect missing and incorrect-case script imports
|
|
712
663
|
this.diagnosticValidateScriptImportPaths();
|
|
664
|
+
//enforce a series of checks on the bodies of class methods
|
|
665
|
+
this.validateClasses();
|
|
713
666
|
//do many per-file checks
|
|
714
667
|
this.enumerateBrsFiles((file) => {
|
|
715
|
-
//enforce a series of checks on the bodies of class methods
|
|
716
|
-
this.validateClasses(file);
|
|
717
668
|
this.diagnosticDetectShadowedLocalVars(file, callableContainerMap);
|
|
718
669
|
this.diagnosticDetectFunctionCollisions(file);
|
|
719
670
|
this.detectVariableNamespaceCollisions(file);
|
|
720
|
-
this.
|
|
671
|
+
this.detectNameCollisions(file);
|
|
721
672
|
});
|
|
722
673
|
}
|
|
674
|
+
clearAstSegmentDiagnostics(astSegment) {
|
|
675
|
+
this.diagnostics = this.diagnostics.filter(diag => !(diag.origin === interfaces_1.DiagnosticOrigin.ASTSegment && diag.astSegment === astSegment));
|
|
676
|
+
}
|
|
677
|
+
clearAstSegmentDiagnosticsByFile(file) {
|
|
678
|
+
const lowerSrcPath = file.srcPath.toLowerCase();
|
|
679
|
+
this.diagnostics = this.diagnostics.filter(diag => !(diag.origin === interfaces_1.DiagnosticOrigin.ASTSegment && diag.file.srcPath.toLowerCase() === lowerSrcPath));
|
|
680
|
+
}
|
|
681
|
+
clearScopeLevelDiagnostics() {
|
|
682
|
+
this.diagnostics = this.diagnostics.filter(diag => diag.origin !== interfaces_1.DiagnosticOrigin.Scope);
|
|
683
|
+
}
|
|
723
684
|
/**
|
|
724
685
|
* Mark this scope as invalid, which means its `validate()` function needs to be called again before use.
|
|
725
686
|
*/
|
|
@@ -727,119 +688,129 @@ class Scope {
|
|
|
727
688
|
this.isValidated = false;
|
|
728
689
|
//clear out various lookups (they'll get regenerated on demand the next time they're requested)
|
|
729
690
|
this.cache.clear();
|
|
730
|
-
this.clearSymbolTable();
|
|
731
|
-
this.symbolCache.clear();
|
|
732
691
|
}
|
|
733
692
|
get symbolTable() {
|
|
734
693
|
return this.cache.getOrAdd('symbolTable', () => {
|
|
735
|
-
var _a
|
|
736
|
-
const result = new SymbolTable_1.SymbolTable((_a = this.getParentScope()) === null || _a === void 0 ? void 0 : _a.symbolTable
|
|
737
|
-
result.addSymbol('m',
|
|
694
|
+
var _a;
|
|
695
|
+
const result = new SymbolTable_1.SymbolTable(`Scope: '${this.name}'`, () => { var _a; return (_a = this.getParentScope()) === null || _a === void 0 ? void 0 : _a.symbolTable; });
|
|
696
|
+
result.addSymbol('m', undefined, new AssociativeArrayType_1.AssociativeArrayType(), SymbolTable_1.SymbolTypeFlag.runtime);
|
|
738
697
|
for (let file of this.getOwnFiles()) {
|
|
739
698
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
740
|
-
result.mergeSymbolTable((
|
|
699
|
+
result.mergeSymbolTable((_a = file.parser) === null || _a === void 0 ? void 0 : _a.symbolTable);
|
|
741
700
|
}
|
|
742
701
|
}
|
|
743
702
|
return result;
|
|
744
703
|
});
|
|
745
704
|
}
|
|
746
|
-
get memberTable() {
|
|
747
|
-
var _a;
|
|
748
|
-
if (!this._memberTable) {
|
|
749
|
-
this._memberTable = new SymbolTable_1.SymbolTable((_a = this.getParentScope()) === null || _a === void 0 ? void 0 : _a.memberTable);
|
|
750
|
-
if (!this.getParentScope()) {
|
|
751
|
-
this._memberTable.addSymbol('global', null, new ObjectType_1.ObjectType());
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
return this._memberTable;
|
|
755
|
-
}
|
|
756
|
-
clearSymbolTable() {
|
|
757
|
-
this.cache.delete('symbolTable');
|
|
758
|
-
this._memberTable = null;
|
|
759
|
-
}
|
|
760
705
|
/**
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
706
|
+
* Builds the current symbol table for the scope, by merging the tables for all the files in this scope.
|
|
707
|
+
* Also links all file symbols tables to this new table
|
|
708
|
+
* This will only rebuilt if the symbol table has not been built before
|
|
709
|
+
*
|
|
710
|
+
* Tree of symbol tables:
|
|
711
|
+
* ```
|
|
712
|
+
* Global Scope Symbol Table
|
|
713
|
+
* - Source Scope Symbol Table :: Aggregate Namespaces Symbol Table (Siblings)
|
|
714
|
+
* - File 1 Symbol Table
|
|
715
|
+
* - File 2 Symbol Table
|
|
716
|
+
* - Component A Scope Symbol Table :: Aggregate Namespaces Symbol Table (Siblings)
|
|
717
|
+
* - File 1 Symbol Table
|
|
718
|
+
* - File 2 Symbol Table
|
|
719
|
+
* - Component B Scope Symbol Table :: Aggregate Namespaces Symbol Table (Siblings)
|
|
720
|
+
* - File 1 Symbol Table
|
|
721
|
+
* - File 2 Symbol Table
|
|
722
|
+
* ```
|
|
723
|
+
*/
|
|
765
724
|
linkSymbolTable() {
|
|
766
|
-
var _a
|
|
725
|
+
var _a;
|
|
726
|
+
SymbolTable_1.SymbolTable.cacheVerifier.generateToken();
|
|
767
727
|
for (const file of this.getAllFiles()) {
|
|
768
728
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
769
|
-
file.parser.symbolTable.
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
729
|
+
this.linkSymbolTableDisposables.push(file.parser.symbolTable.pushParentProvider(() => this.symbolTable));
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
//Add namespace aggregates to namespace member tables
|
|
733
|
+
const namespaceTypesKnown = new Map();
|
|
734
|
+
// eslint-disable-next-line no-bitwise
|
|
735
|
+
let getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime | SymbolTable_1.SymbolTypeFlag.typetime };
|
|
736
|
+
for (const [nsName, nsContainer] of this.namespaceLookup) {
|
|
737
|
+
let currentNSType = null;
|
|
738
|
+
let parentNSType = null;
|
|
739
|
+
const existingNsStmt = (_a = nsContainer.namespaceStatements) === null || _a === void 0 ? void 0 : _a[0];
|
|
740
|
+
if (!nsContainer.isTopLevel) {
|
|
741
|
+
parentNSType = namespaceTypesKnown.get(nsContainer.parentNameLower);
|
|
742
|
+
if (!parentNSType) {
|
|
743
|
+
// we don't know about the parent namespace... uh, oh!
|
|
744
|
+
break;
|
|
775
745
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
746
|
+
currentNSType = parentNSType.getMemberType(nsContainer.fullNameLower, getTypeOptions);
|
|
747
|
+
}
|
|
748
|
+
else {
|
|
749
|
+
currentNSType = this.symbolTable.getSymbolType(nsContainer.fullNameLower, getTypeOptions);
|
|
750
|
+
}
|
|
751
|
+
if (!(0, reflection_1.isNamespaceType)(currentNSType)) {
|
|
752
|
+
if (!currentNSType || (0, reflection_1.isReferenceType)(currentNSType)) {
|
|
753
|
+
currentNSType = existingNsStmt
|
|
754
|
+
? existingNsStmt.getType(getTypeOptions)
|
|
755
|
+
: new NamespaceType_1.NamespaceType(nsName);
|
|
756
|
+
if (parentNSType) {
|
|
757
|
+
// adding as a member of existing NS
|
|
758
|
+
parentNSType.addMember(nsContainer.lastPartName, { definingNode: existingNsStmt }, currentNSType, getTypeOptions.flags);
|
|
759
|
+
this.symbolsAddedDuringLinking.push({ symbolTable: parentNSType.getMemberTable(), name: nsContainer.lastPartName, flags: getTypeOptions.flags });
|
|
785
760
|
}
|
|
786
761
|
else {
|
|
787
|
-
|
|
762
|
+
this.symbolTable.addSymbol(nsContainer.lastPartName, { definingNode: existingNsStmt }, currentNSType, getTypeOptions.flags);
|
|
763
|
+
this.symbolsAddedDuringLinking.push({ symbolTable: this.symbolTable, name: nsContainer.lastPartName, flags: getTypeOptions.flags });
|
|
788
764
|
}
|
|
789
765
|
}
|
|
766
|
+
else {
|
|
767
|
+
break;
|
|
768
|
+
}
|
|
790
769
|
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
const ifaceStmt = (_b = pair[1]) === null || _b === void 0 ? void 0 : _b.item;
|
|
802
|
-
ifaceStmt === null || ifaceStmt === void 0 ? void 0 : ifaceStmt.buildSymbolTable(this.getParentInterface(ifaceStmt));
|
|
803
|
-
}
|
|
804
|
-
//also link enums
|
|
805
|
-
const enumMap = this.getEnumMap();
|
|
806
|
-
for (const pair of enumMap) {
|
|
807
|
-
const enumStmt = (_c = pair[1]) === null || _c === void 0 ? void 0 : _c.item;
|
|
808
|
-
enumStmt === null || enumStmt === void 0 ? void 0 : enumStmt.buildSymbolTable();
|
|
770
|
+
else {
|
|
771
|
+
// Existing known namespace
|
|
772
|
+
}
|
|
773
|
+
if (!namespaceTypesKnown.has(nsName)) {
|
|
774
|
+
namespaceTypesKnown.set(nsName, currentNSType);
|
|
775
|
+
}
|
|
776
|
+
for (let nsStmt of nsContainer.namespaceStatements) {
|
|
777
|
+
this.linkSymbolTableDisposables.push(nsStmt === null || nsStmt === void 0 ? void 0 : nsStmt.getSymbolTable().addSibling(nsContainer.symbolTable));
|
|
778
|
+
}
|
|
779
|
+
this.linkSymbolTableDisposables.push(currentNSType.memberTable.addSibling(nsContainer.symbolTable));
|
|
809
780
|
}
|
|
810
781
|
}
|
|
811
782
|
unlinkSymbolTable() {
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
}
|
|
819
|
-
}
|
|
783
|
+
for (const symbolToRemove of this.symbolsAddedDuringLinking) {
|
|
784
|
+
this.symbolTable.removeSymbol(symbolToRemove.name);
|
|
785
|
+
}
|
|
786
|
+
this.symbolsAddedDuringLinking = [];
|
|
787
|
+
for (const dispose of this.linkSymbolTableDisposables) {
|
|
788
|
+
dispose();
|
|
820
789
|
}
|
|
790
|
+
this.linkSymbolTableDisposables = [];
|
|
821
791
|
}
|
|
822
792
|
detectVariableNamespaceCollisions(file) {
|
|
793
|
+
var _a, _b;
|
|
823
794
|
//find all function parameters
|
|
824
|
-
for (let func of file.
|
|
795
|
+
for (let func of file['_cachedLookups'].functionExpressions) {
|
|
825
796
|
for (let param of func.parameters) {
|
|
826
797
|
let lowerParamName = param.name.text.toLowerCase();
|
|
827
|
-
let namespace = this.
|
|
798
|
+
let namespace = this.getNamespace(lowerParamName, (_a = param.findAncestor(reflection_1.isNamespaceStatement)) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript).toLowerCase());
|
|
828
799
|
//see if the param matches any starting namespace part
|
|
829
800
|
if (namespace) {
|
|
830
|
-
this.diagnostics.push(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.parameterMayNotHaveSameNameAsNamespace(param.name.text)), { range: param.name.range, relatedInformation: [{
|
|
801
|
+
this.diagnostics.push(Object.assign(Object.assign({ origin: interfaces_1.DiagnosticOrigin.Scope, file: file }, DiagnosticMessages_1.DiagnosticMessages.parameterMayNotHaveSameNameAsNamespace(param.name.text)), { range: param.name.range, relatedInformation: [{
|
|
831
802
|
message: 'Namespace declared here',
|
|
832
803
|
location: util_1.util.createLocation(vscode_uri_1.URI.file(namespace.file.srcPath).toString(), namespace.nameRange)
|
|
833
804
|
}] }));
|
|
834
805
|
}
|
|
835
806
|
}
|
|
836
807
|
}
|
|
837
|
-
for (let assignment of file.
|
|
808
|
+
for (let assignment of file['_cachedLookups'].assignmentStatements) {
|
|
838
809
|
let lowerAssignmentName = assignment.name.text.toLowerCase();
|
|
839
|
-
let namespace = this.
|
|
810
|
+
let namespace = this.getNamespace(lowerAssignmentName, (_b = assignment.findAncestor(reflection_1.isNamespaceStatement)) === null || _b === void 0 ? void 0 : _b.getName(Parser_1.ParseMode.BrighterScript).toLowerCase());
|
|
840
811
|
//see if the param matches any starting namespace part
|
|
841
812
|
if (namespace) {
|
|
842
|
-
this.diagnostics.push(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.variableMayNotHaveSameNameAsNamespace(assignment.name.text)), { range: assignment.name.range, relatedInformation: [{
|
|
813
|
+
this.diagnostics.push(Object.assign(Object.assign({ origin: interfaces_1.DiagnosticOrigin.Scope, file: file }, DiagnosticMessages_1.DiagnosticMessages.variableMayNotHaveSameNameAsNamespace(assignment.name.text)), { range: assignment.name.range, relatedInformation: [{
|
|
843
814
|
message: 'Namespace declared here',
|
|
844
815
|
location: util_1.util.createLocation(vscode_uri_1.URI.file(namespace.file.srcPath).toString(), namespace.nameRange)
|
|
845
816
|
}] }));
|
|
@@ -856,50 +827,84 @@ class Scope {
|
|
|
856
827
|
if (lowerFuncName) {
|
|
857
828
|
//find function declarations with the same name as a stdlib function
|
|
858
829
|
if (globalCallables_1.globalCallableMap.has(lowerFuncName)) {
|
|
859
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.scopeFunctionShadowedByBuiltInFunction()), { range: func.nameRange, file: file }));
|
|
830
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.scopeFunctionShadowedByBuiltInFunction()), { range: func.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
860
831
|
}
|
|
861
832
|
//find any functions that have the same name as a class
|
|
862
|
-
|
|
863
|
-
|
|
833
|
+
const klassLink = this.getClassFileLink(lowerFuncName);
|
|
834
|
+
if (klassLink) {
|
|
835
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass(funcName)), { range: func.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope, relatedInformation: [{
|
|
836
|
+
location: util_1.util.createLocation(vscode_uri_1.URI.file(klassLink.file.srcPath).toString(), klassLink.item.name.range),
|
|
837
|
+
message: 'Original class declared here'
|
|
838
|
+
}] }));
|
|
864
839
|
}
|
|
865
840
|
}
|
|
866
841
|
}
|
|
867
842
|
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
843
|
+
detectNameCollisions(file) {
|
|
844
|
+
file.ast.walk((0, visitors_1.createVisitor)({
|
|
845
|
+
NamespaceStatement: (nsStmt) => {
|
|
846
|
+
var _a;
|
|
847
|
+
this.validateNameCollision(file, nsStmt, (_a = nsStmt.getNameParts()) === null || _a === void 0 ? void 0 : _a[0]);
|
|
848
|
+
},
|
|
849
|
+
ClassStatement: (classStmt) => {
|
|
850
|
+
this.validateNameCollision(file, classStmt, classStmt.name);
|
|
851
|
+
},
|
|
852
|
+
InterfaceStatement: (ifaceStmt) => {
|
|
853
|
+
this.validateNameCollision(file, ifaceStmt, ifaceStmt.tokens.name);
|
|
854
|
+
},
|
|
855
|
+
ConstStatement: (constStmt) => {
|
|
856
|
+
this.validateNameCollision(file, constStmt, constStmt.tokens.name);
|
|
857
|
+
},
|
|
858
|
+
EnumStatement: (enumStmt) => {
|
|
859
|
+
this.validateNameCollision(file, enumStmt, enumStmt.tokens.name);
|
|
882
860
|
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
861
|
+
}), {
|
|
862
|
+
walkMode: visitors_1.WalkMode.visitStatements
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
validateNameCollision(file, node, nameIdentifier) {
|
|
866
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
867
|
+
const name = nameIdentifier === null || nameIdentifier === void 0 ? void 0 : nameIdentifier.text;
|
|
868
|
+
if (!name || !node) {
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
const nameRange = nameIdentifier.range;
|
|
872
|
+
const containingNamespace = (_a = node.findAncestor(reflection_1.isNamespaceStatement)) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript);
|
|
873
|
+
const links = this.getAllFileLinks(name, containingNamespace);
|
|
874
|
+
for (let link of links) {
|
|
875
|
+
if (!link || link.item === node) {
|
|
876
|
+
// refers to same node
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
879
|
+
if ((0, reflection_1.isNamespaceStatement)(link.item) && (0, reflection_1.isNamespaceStatement)(node)) {
|
|
880
|
+
// namespace can be declared multiple times
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
const thisNodeKindName = util_1.util.getAstNodeFriendlyName(node);
|
|
884
|
+
const thatNodeKindName = link.file.srcPath === 'global' ? 'Global Function' : (_b = util_1.util.getAstNodeFriendlyName(link.item)) !== null && _b !== void 0 ? _b : '';
|
|
885
|
+
let thatNameRange = (_f = (_e = (_d = (_c = link.item) === null || _c === void 0 ? void 0 : _c.tokens) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.range) !== null && _f !== void 0 ? _f : (_g = link.item) === null || _g === void 0 ? void 0 : _g.range;
|
|
886
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
887
|
+
switch ((_h = link.item) === null || _h === void 0 ? void 0 : _h.kind) {
|
|
888
|
+
case AstNode_1.AstNodeKind.ClassStatement: {
|
|
889
|
+
thatNameRange = (_j = link.item.name) === null || _j === void 0 ? void 0 : _j.range;
|
|
890
|
+
break;
|
|
888
891
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
if (!this.hasClass(paramTypeName, currentNamespaceName) && !this.hasInterface(paramTypeName) && !this.hasEnum(paramTypeName)) {
|
|
893
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(param.name.text, paramTypeName)), { range: param.type.range, file: file }));
|
|
894
|
-
}
|
|
892
|
+
case AstNode_1.AstNodeKind.NamespaceStatement: {
|
|
893
|
+
thatNameRange = (_l = (_k = link.item.getNameParts()) === null || _k === void 0 ? void 0 : _k[0]) === null || _l === void 0 ? void 0 : _l.range;
|
|
894
|
+
break;
|
|
895
895
|
}
|
|
896
896
|
}
|
|
897
|
+
const relatedInformation = thatNameRange ? [{
|
|
898
|
+
message: `${thatNodeKindName} declared here`,
|
|
899
|
+
location: util_1.util.createLocation(vscode_uri_1.URI.file((_m = link.file) === null || _m === void 0 ? void 0 : _m.srcPath).toString(), thatNameRange)
|
|
900
|
+
}] : undefined;
|
|
901
|
+
this.diagnostics.push(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.nameCollision(thisNodeKindName, thatNodeKindName, name)), { origin: interfaces_1.DiagnosticOrigin.Scope, range: nameRange, relatedInformation: relatedInformation }));
|
|
897
902
|
}
|
|
898
903
|
}
|
|
899
904
|
getNewExpressions() {
|
|
900
905
|
let result = [];
|
|
901
906
|
this.enumerateBrsFiles((file) => {
|
|
902
|
-
let expressions = file.
|
|
907
|
+
let expressions = file['_cachedLookups'].newExpressions;
|
|
903
908
|
for (let expression of expressions) {
|
|
904
909
|
expression.file = file;
|
|
905
910
|
result.push(expression);
|
|
@@ -907,57 +912,54 @@ class Scope {
|
|
|
907
912
|
});
|
|
908
913
|
return result;
|
|
909
914
|
}
|
|
910
|
-
validateClasses(
|
|
911
|
-
let validator = new ClassValidator_1.BsClassValidator();
|
|
912
|
-
validator.validate(
|
|
913
|
-
this.diagnostics.push(...validator.diagnostics
|
|
915
|
+
validateClasses() {
|
|
916
|
+
let validator = new ClassValidator_1.BsClassValidator(this);
|
|
917
|
+
validator.validate();
|
|
918
|
+
this.diagnostics.push(...validator.diagnostics.map(diag => {
|
|
919
|
+
return Object.assign(Object.assign({}, diag), { origin: interfaces_1.DiagnosticOrigin.Scope });
|
|
920
|
+
}));
|
|
914
921
|
}
|
|
915
922
|
/**
|
|
916
|
-
* Detect local variables (
|
|
917
|
-
* @param file
|
|
918
|
-
* @param callableContainerMap
|
|
923
|
+
* Detect local variables (function scope) that have the same name as scope calls
|
|
919
924
|
*/
|
|
920
925
|
diagnosticDetectShadowedLocalVars(file, callableContainerMap) {
|
|
926
|
+
var _a;
|
|
921
927
|
const classMap = this.getClassMap();
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
+
//loop through every function scope
|
|
929
|
+
for (let funcScope of file.functionScopes) {
|
|
930
|
+
//every var declaration in this function scope
|
|
931
|
+
for (let varDeclaration of funcScope.variableDeclarations) {
|
|
932
|
+
const varName = varDeclaration.name;
|
|
933
|
+
const lowerVarName = varName.toLowerCase();
|
|
934
|
+
const varIsFunction = () => {
|
|
935
|
+
return (0, reflection_1.isCallableType)(varDeclaration.getType());
|
|
936
|
+
};
|
|
937
|
+
if (
|
|
938
|
+
//has same name as stdlib
|
|
939
|
+
globalCallables_1.globalCallableMap.has(lowerVarName)) {
|
|
928
940
|
//local var function with same name as stdlib function
|
|
929
|
-
if (
|
|
930
|
-
|
|
931
|
-
globalCallables_1.globalCallableMap.has(symbolNameLower)) {
|
|
932
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('stdlib')), { range: symbol.range, file: file }));
|
|
933
|
-
//this check needs to come after the stdlib one, because the stdlib functions are included
|
|
934
|
-
//in the scope function list
|
|
941
|
+
if (varIsFunction()) {
|
|
942
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('stdlib')), { range: varDeclaration.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
935
943
|
}
|
|
936
|
-
else if (
|
|
937
|
-
//has same name as scope function
|
|
938
|
-
callableContainerMap.has(symbolNameLower)) {
|
|
939
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('scope')), { range: symbol.range, file: file }));
|
|
940
|
-
}
|
|
941
|
-
//var is not a function
|
|
942
944
|
}
|
|
943
|
-
else if (
|
|
944
|
-
//is NOT a callable from stdlib (because non-function local vars can have same name as stdlib names)
|
|
945
|
-
!globalCallables_1.globalCallableMap.has(symbolNameLower)) {
|
|
945
|
+
else if (callableContainerMap.has(lowerVarName)) {
|
|
946
946
|
//is same name as a callable
|
|
947
|
-
if (
|
|
948
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
949
|
-
//has the same name as an in-scope class
|
|
947
|
+
if (varIsFunction()) {
|
|
948
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('scope')), { range: varDeclaration.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
950
949
|
}
|
|
951
|
-
else
|
|
952
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
950
|
+
else {
|
|
951
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarShadowedByScopedFunction()), { range: varDeclaration.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
953
952
|
}
|
|
953
|
+
//has the same name as an in-scope class
|
|
954
|
+
}
|
|
955
|
+
else if (classMap.has(lowerVarName)) {
|
|
956
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarSameNameAsClass((_a = classMap.get(lowerVarName)) === null || _a === void 0 ? void 0 : _a.item.getName(Parser_1.ParseMode.BrighterScript))), { range: varDeclaration.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
954
957
|
}
|
|
955
958
|
}
|
|
956
959
|
}
|
|
957
960
|
}
|
|
958
961
|
/**
|
|
959
962
|
* Create diagnostics for any duplicate function declarations
|
|
960
|
-
* @param callablesByLowerName
|
|
961
963
|
*/
|
|
962
964
|
diagnosticFindDuplicateFunctionDeclarations(callableContainersByLowerName) {
|
|
963
965
|
//for each list of callables with the same name
|
|
@@ -990,9 +992,9 @@ class Scope {
|
|
|
990
992
|
//same file: skip redundant imports
|
|
991
993
|
continue;
|
|
992
994
|
}
|
|
993
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.overridesAncestorFunction(container.callable.name, container.scope.name, shadowedCallable.callable.file.
|
|
995
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.overridesAncestorFunction(container.callable.name, container.scope.name, shadowedCallable.callable.file.destPath,
|
|
994
996
|
//grab the last item in the list, which should be the closest ancestor's version
|
|
995
|
-
shadowedCallable.scope.name)), { range: container.callable.nameRange, file: container.callable.file }));
|
|
997
|
+
shadowedCallable.scope.name)), { range: container.callable.nameRange, file: container.callable.file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
996
998
|
}
|
|
997
999
|
}
|
|
998
1000
|
}
|
|
@@ -1000,7 +1002,7 @@ class Scope {
|
|
|
1000
1002
|
if (ownCallables.length > 1) {
|
|
1001
1003
|
for (let callableContainer of ownCallables) {
|
|
1002
1004
|
let callable = callableContainer.callable;
|
|
1003
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateFunctionImplementation(callable.name, callableContainer.scope.name)), { range: util_1.util.createRange(callable.nameRange.start.line, callable.nameRange.start.character, callable.nameRange.start.line, callable.nameRange.end.character), file: callable.file }));
|
|
1005
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateFunctionImplementation(callable.name, callableContainer.scope.name)), { range: util_1.util.createRange(callable.nameRange.start.line, callable.nameRange.start.character, callable.nameRange.start.line, callable.nameRange.end.character), file: callable.file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
1004
1006
|
}
|
|
1005
1007
|
}
|
|
1006
1008
|
}
|
|
@@ -1027,11 +1029,11 @@ class Scope {
|
|
|
1027
1029
|
let scriptImports = this.getOwnScriptImports();
|
|
1028
1030
|
//verify every script import
|
|
1029
1031
|
for (let scriptImport of scriptImports) {
|
|
1030
|
-
let referencedFile = this.getFileByRelativePath(scriptImport.
|
|
1032
|
+
let referencedFile = this.getFileByRelativePath(scriptImport.destPath);
|
|
1031
1033
|
//if we can't find the file
|
|
1032
1034
|
if (!referencedFile) {
|
|
1033
1035
|
//skip the default bslib file, it will exist at transpile time but should not show up in the program during validation cycle
|
|
1034
|
-
if (scriptImport.
|
|
1036
|
+
if (scriptImport.destPath === this.program.bslibPkgPath) {
|
|
1035
1037
|
continue;
|
|
1036
1038
|
}
|
|
1037
1039
|
let dInfo;
|
|
@@ -1041,17 +1043,16 @@ class Scope {
|
|
|
1041
1043
|
else {
|
|
1042
1044
|
dInfo = DiagnosticMessages_1.DiagnosticMessages.referencedFileDoesNotExist();
|
|
1043
1045
|
}
|
|
1044
|
-
this.diagnostics.push(Object.assign(Object.assign({}, dInfo), { range: scriptImport.filePathRange, file: scriptImport.sourceFile }));
|
|
1046
|
+
this.diagnostics.push(Object.assign(Object.assign({}, dInfo), { range: scriptImport.filePathRange, file: scriptImport.sourceFile, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
1045
1047
|
//if the character casing of the script import path does not match that of the actual path
|
|
1046
1048
|
}
|
|
1047
|
-
else if (scriptImport.
|
|
1048
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.scriptImportCaseMismatch(referencedFile.
|
|
1049
|
+
else if (scriptImport.destPath !== referencedFile.destPath) {
|
|
1050
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.scriptImportCaseMismatch(referencedFile.destPath)), { range: scriptImport.filePathRange, file: scriptImport.sourceFile, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
1049
1051
|
}
|
|
1050
1052
|
}
|
|
1051
1053
|
}
|
|
1052
1054
|
/**
|
|
1053
1055
|
* Find the file with the specified relative path
|
|
1054
|
-
* @param relativePath
|
|
1055
1056
|
*/
|
|
1056
1057
|
getFileByRelativePath(relativePath) {
|
|
1057
1058
|
if (!relativePath) {
|
|
@@ -1059,49 +1060,19 @@ class Scope {
|
|
|
1059
1060
|
}
|
|
1060
1061
|
let files = this.getAllFiles();
|
|
1061
1062
|
for (let file of files) {
|
|
1062
|
-
if (file.
|
|
1063
|
+
if (file.destPath.toLowerCase() === relativePath.toLowerCase()) {
|
|
1063
1064
|
return file;
|
|
1064
1065
|
}
|
|
1065
1066
|
}
|
|
1066
1067
|
}
|
|
1067
1068
|
/**
|
|
1068
1069
|
* Determine if this file is included in this scope (excluding parent scopes)
|
|
1069
|
-
* @param file
|
|
1070
1070
|
*/
|
|
1071
1071
|
hasFile(file) {
|
|
1072
1072
|
let files = this.getOwnFiles();
|
|
1073
1073
|
let hasFile = files.includes(file);
|
|
1074
1074
|
return hasFile;
|
|
1075
1075
|
}
|
|
1076
|
-
/**
|
|
1077
|
-
* Get all callables as completionItems
|
|
1078
|
-
*/
|
|
1079
|
-
getCallablesAsCompletions(parseMode) {
|
|
1080
|
-
let completions = [];
|
|
1081
|
-
let callables = this.getAllCallables();
|
|
1082
|
-
if (parseMode === Parser_1.ParseMode.BrighterScript) {
|
|
1083
|
-
//throw out the namespaced callables (they will be handled by another method)
|
|
1084
|
-
callables = callables.filter(x => x.callable.hasNamespace === false);
|
|
1085
|
-
}
|
|
1086
|
-
for (let callableContainer of callables) {
|
|
1087
|
-
completions.push(this.createCompletionFromCallable(callableContainer));
|
|
1088
|
-
}
|
|
1089
|
-
return completions;
|
|
1090
|
-
}
|
|
1091
|
-
createCompletionFromCallable(callableContainer) {
|
|
1092
|
-
return {
|
|
1093
|
-
label: callableContainer.callable.getName(Parser_1.ParseMode.BrighterScript),
|
|
1094
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function,
|
|
1095
|
-
detail: callableContainer.callable.shortDescription,
|
|
1096
|
-
documentation: callableContainer.callable.documentation ? { kind: 'markdown', value: callableContainer.callable.documentation } : undefined
|
|
1097
|
-
};
|
|
1098
|
-
}
|
|
1099
|
-
createCompletionFromFunctionStatement(statement) {
|
|
1100
|
-
return {
|
|
1101
|
-
label: statement.getName(Parser_1.ParseMode.BrighterScript),
|
|
1102
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
1103
|
-
};
|
|
1104
|
-
}
|
|
1105
1076
|
/**
|
|
1106
1077
|
* Get the definition (where was this thing first defined) of the symbol under the position
|
|
1107
1078
|
*/
|
|
@@ -1109,41 +1080,10 @@ class Scope {
|
|
|
1109
1080
|
// Overridden in XMLScope. Brs files use implementation in BrsFile
|
|
1110
1081
|
return [];
|
|
1111
1082
|
}
|
|
1112
|
-
/**
|
|
1113
|
-
* Scan all files for property names, and return them as completions
|
|
1114
|
-
*/
|
|
1115
|
-
getPropertyNameCompletions() {
|
|
1116
|
-
let results = [];
|
|
1117
|
-
this.enumerateBrsFiles((file) => {
|
|
1118
|
-
results.push(...file.propertyNameCompletions);
|
|
1119
|
-
});
|
|
1120
|
-
return results;
|
|
1121
|
-
}
|
|
1122
|
-
getAllClassMemberCompletions() {
|
|
1123
|
-
let results = new Map();
|
|
1124
|
-
let filesSearched = new Set();
|
|
1125
|
-
for (const file of this.getAllFiles()) {
|
|
1126
|
-
if ((0, reflection_1.isXmlFile)(file) || filesSearched.has(file)) {
|
|
1127
|
-
continue;
|
|
1128
|
-
}
|
|
1129
|
-
filesSearched.add(file);
|
|
1130
|
-
for (let cs of file.parser.references.classStatements) {
|
|
1131
|
-
for (let s of [...cs.methods, ...cs.fields]) {
|
|
1132
|
-
if (!results.has(s.name.text) && s.name.text.toLowerCase() !== 'new') {
|
|
1133
|
-
results.set(s.name.text, {
|
|
1134
|
-
label: s.name.text,
|
|
1135
|
-
kind: (0, reflection_1.isMethodStatement)(s) ? vscode_languageserver_1.CompletionItemKind.Method : vscode_languageserver_1.CompletionItemKind.Field
|
|
1136
|
-
});
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
return results;
|
|
1142
|
-
}
|
|
1143
1083
|
/**
|
|
1144
1084
|
* @param className - The name of the class (including namespace if possible)
|
|
1145
1085
|
* @param callsiteNamespace - the name of the namespace where the call site resides (this is NOT the known namespace of the class).
|
|
1146
|
-
* This is used to help resolve non-namespaced class names that reside in the same
|
|
1086
|
+
* This is used to help resolve non-namespaced class names that reside in the same namespac as the call site.
|
|
1147
1087
|
*/
|
|
1148
1088
|
getClassHierarchy(className, callsiteNamespace) {
|
|
1149
1089
|
var _a, _b;
|
|
@@ -1151,7 +1091,7 @@ class Scope {
|
|
|
1151
1091
|
let link = this.getClassFileLink(className, callsiteNamespace);
|
|
1152
1092
|
while (link) {
|
|
1153
1093
|
items.push(link);
|
|
1154
|
-
link = this.getClassFileLink((_b = (_a = link.item.parentClassName) === null || _a === void 0 ? void 0 : _a.getName(
|
|
1094
|
+
link = this.getClassFileLink((_b = (_a = link.item.parentClassName) === null || _a === void 0 ? void 0 : _a.getName()) === null || _b === void 0 ? void 0 : _b.toLowerCase(), callsiteNamespace);
|
|
1155
1095
|
}
|
|
1156
1096
|
return items;
|
|
1157
1097
|
}
|