brighterscript 1.0.0-alpha.23 → 1.0.0-alpha.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +585 -218
- package/README.md +45 -139
- package/bsconfig.schema.json +41 -0
- package/dist/ActionPipeline.d.ts +10 -0
- package/dist/ActionPipeline.js +40 -0
- package/dist/ActionPipeline.js.map +1 -0
- package/dist/AstValidationSegmenter.d.ts +25 -0
- package/dist/AstValidationSegmenter.js +152 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +39 -4
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.js +3 -3
- package/dist/Cache.js.map +1 -1
- package/dist/CacheVerifier.d.ts +7 -0
- package/dist/CacheVerifier.js +20 -0
- package/dist/CacheVerifier.js.map +1 -0
- package/dist/CodeActionUtil.d.ts +3 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +3 -2
- package/dist/CommentFlagProcessor.js +5 -4
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +3 -2
- package/dist/DependencyGraph.js +11 -10
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.js +9 -5
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +1 -0
- package/dist/DiagnosticFilterer.js +5 -3
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +79 -15
- package/dist/DiagnosticMessages.js +134 -21
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
- package/dist/DiagnosticSeverityAdjuster.js +41 -0
- package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
- package/dist/FunctionScope.d.ts +28 -0
- package/dist/FunctionScope.js +52 -0
- package/dist/FunctionScope.js.map +1 -0
- package/dist/KeyedThrottler.d.ts +3 -3
- package/dist/KeyedThrottler.js +3 -3
- package/dist/KeyedThrottler.js.map +1 -1
- package/dist/LanguageServer.d.ts +23 -11
- package/dist/LanguageServer.js +222 -87
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +3 -2
- package/dist/Logger.js +11 -3
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +21 -3
- package/dist/PluginInterface.js +74 -6
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +162 -81
- package/dist/Program.js +903 -732
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +22 -12
- package/dist/ProgramBuilder.js +132 -104
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +95 -134
- package/dist/Scope.js +477 -551
- package/dist/Scope.js.map +1 -1
- package/dist/Stopwatch.js +1 -1
- package/dist/Stopwatch.js.map +1 -1
- package/dist/SymbolTable.d.ts +95 -29
- package/dist/SymbolTable.js +256 -102
- package/dist/SymbolTable.js.map +1 -1
- package/dist/Throttler.d.ts +12 -0
- package/dist/Throttler.js +39 -0
- package/dist/Throttler.js.map +1 -1
- package/dist/Watcher.d.ts +0 -3
- package/dist/Watcher.js +0 -3
- package/dist/Watcher.js.map +1 -1
- package/dist/XmlScope.d.ts +4 -6
- package/dist/XmlScope.js +74 -68
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +48 -0
- package/dist/astUtils/CachedLookups.js +323 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +9 -5
- package/dist/astUtils/{AstEditor.js → Editor.js} +10 -4
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +68 -64
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +10 -10
- package/dist/astUtils/creators.js +26 -16
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +5 -5
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +132 -100
- package/dist/astUtils/reflection.js +225 -166
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +208 -126
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +12 -12
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +54 -35
- package/dist/astUtils/visitors.js +29 -3
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +178 -33
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -9
- package/dist/astUtils/xml.js +9 -9
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +12 -2
- package/dist/bscPlugin/BscPlugin.js +41 -3
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
- package/dist/bscPlugin/CallExpressionInfo.js +131 -0
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
- package/dist/bscPlugin/FileWriter.d.ts +6 -0
- package/dist/bscPlugin/FileWriter.js +24 -0
- package/dist/bscPlugin/FileWriter.js.map +1 -0
- package/dist/bscPlugin/SignatureHelpUtil.d.ts +10 -0
- package/dist/bscPlugin/SignatureHelpUtil.js +135 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +21 -12
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +86 -12
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +57 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js +544 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1909 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +17 -0
- package/dist/bscPlugin/hover/HoverProcessor.js +188 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +513 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +3 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +102 -29
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +167 -6
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +1 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
- package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
- package/dist/bscPlugin/serialize/BslibManager.js +40 -0
- package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
- package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
- package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
- package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +16 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +123 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +12 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +22 -1
- package/dist/bscPlugin/validation/BrsFileValidator.js +316 -29
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +264 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/ProgramValidator.d.ts +10 -0
- package/dist/bscPlugin/validation/ProgramValidator.js +32 -0
- package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +56 -8
- package/dist/bscPlugin/validation/ScopeValidator.js +514 -116
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2454 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js +44 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
- package/dist/cli.js +107 -8
- package/dist/cli.js.map +1 -1
- package/dist/deferred.d.ts +3 -3
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +8 -2
- package/dist/diagnosticUtils.js +47 -17
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +8 -10
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +26 -0
- package/dist/files/AssetFile.js +26 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +529 -486
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +124 -112
- package/dist/files/BrsFile.js +819 -1131
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1869 -1277
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +104 -0
- package/dist/files/BscFile.js +16 -0
- package/dist/files/BscFile.js.map +1 -0
- package/dist/files/Factory.d.ts +25 -0
- package/dist/files/Factory.js +22 -0
- package/dist/files/Factory.js.map +1 -0
- package/dist/files/LazyFileData.d.ts +20 -0
- package/dist/files/LazyFileData.js +54 -0
- package/dist/files/LazyFileData.js.map +1 -0
- package/dist/files/LazyFileData.spec.d.ts +1 -0
- package/dist/files/LazyFileData.spec.js +27 -0
- package/dist/files/LazyFileData.spec.js.map +1 -0
- package/dist/files/XmlFile.d.ts +70 -32
- package/dist/files/XmlFile.js +106 -117
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +325 -262
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +49 -41
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.js +104 -40
- package/dist/files/tests/optionalChaning.spec.js.map +1 -1
- package/dist/globalCallables.js +16 -18
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +440 -150
- package/dist/interfaces.js +27 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Character.spec.js +5 -5
- package/dist/lexer/Character.spec.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +12 -5
- package/dist/lexer/Lexer.js +28 -13
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +187 -134
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +9 -1
- package/dist/lexer/Token.js +9 -1
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +9 -0
- package/dist/lexer/TokenKind.js +30 -5
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +162 -0
- package/dist/parser/AstNode.js +225 -0
- package/dist/parser/AstNode.js.map +1 -0
- package/dist/parser/AstNode.spec.d.ts +1 -0
- package/dist/parser/AstNode.spec.js +165 -0
- package/dist/parser/AstNode.spec.js.map +1 -0
- package/dist/parser/BrsTranspileState.d.ts +4 -7
- package/dist/parser/BrsTranspileState.js +4 -12
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +126 -167
- package/dist/parser/Expression.js +524 -394
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +152 -146
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +45 -196
- package/dist/parser/Parser.js +470 -926
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +1034 -805
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +9 -8
- package/dist/parser/SGParser.js +10 -8
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +27 -38
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +98 -35
- package/dist/parser/SGTypes.js +169 -99
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +208 -122
- package/dist/parser/Statement.js +599 -364
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +45 -21
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +1 -1
- package/dist/parser/TranspileState.js +7 -12
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.js +3 -2
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +33 -23
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +25 -20
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +96 -94
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +22 -16
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +8 -8
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +58 -21
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +61 -20
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +8 -8
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +129 -21
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +5 -5
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +36 -36
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +67 -22
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +9 -9
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +123 -81
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +12 -12
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +12 -12
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/Relational.spec.js +13 -13
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +221 -81
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +287 -105
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js +127 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +15 -15
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/ConstStatement.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js +262 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/Continue.spec.d.ts +1 -0
- package/dist/parser/tests/statement/Continue.spec.js +119 -0
- package/dist/parser/tests/statement/Continue.spec.js.map +1 -0
- package/dist/parser/tests/statement/Declaration.spec.js +19 -19
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +22 -22
- package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.js +111 -300
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
- package/dist/parser/tests/statement/For.spec.js +9 -10
- package/dist/parser/tests/statement/For.spec.js.map +1 -1
- package/dist/parser/tests/statement/ForEach.spec.js +8 -9
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/statement/Function.spec.js +44 -35
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +5 -5
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +20 -20
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +30 -196
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +11 -11
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +16 -78
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +107 -90
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +14 -12
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +48 -35
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +6 -6
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +6 -6
- package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +18 -16
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +1 -1
- package/dist/preprocessor/Manifest.js +3 -3
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/preprocessor/Manifest.spec.js +8 -8
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/preprocessor/Preprocessor.d.ts +5 -6
- package/dist/preprocessor/Preprocessor.js +15 -11
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/preprocessor/Preprocessor.spec.js +25 -25
- package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.d.ts +1 -1
- package/dist/preprocessor/PreprocessorParser.js +7 -1
- package/dist/preprocessor/PreprocessorParser.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +13 -13
- package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
- package/dist/roku-types/data.json +6544 -10519
- package/dist/roku-types/index.d.ts +662 -1934
- package/dist/types/ArrayType.d.ts +10 -9
- package/dist/types/ArrayType.js +65 -60
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +36 -68
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +11 -0
- package/dist/types/AssociativeArrayType.js +52 -0
- package/dist/types/AssociativeArrayType.js.map +1 -0
- package/dist/types/BaseFunctionType.d.ts +9 -0
- package/dist/types/BaseFunctionType.js +25 -0
- package/dist/types/BaseFunctionType.js.map +1 -0
- package/dist/types/BooleanType.d.ts +8 -5
- package/dist/types/BooleanType.js +14 -7
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +10 -6
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +32 -21
- package/dist/types/BscType.js +118 -21
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BscTypeKind.d.ts +25 -0
- package/dist/types/BscTypeKind.js +30 -0
- package/dist/types/BscTypeKind.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
- package/dist/types/BuiltInInterfaceAdder.js +164 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +116 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
- package/dist/types/ClassType.d.ts +17 -0
- package/dist/types/ClassType.js +58 -0
- package/dist/types/ClassType.js.map +1 -0
- package/dist/types/ClassType.spec.d.ts +1 -0
- package/dist/types/ClassType.spec.js +77 -0
- package/dist/types/ClassType.spec.js.map +1 -0
- package/dist/types/ComponentType.d.ts +26 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +8 -5
- package/dist/types/DoubleType.js +18 -16
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +12 -6
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +10 -5
- package/dist/types/DynamicType.js +16 -4
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/DynamicType.spec.js +16 -5
- package/dist/types/DynamicType.spec.js.map +1 -1
- package/dist/types/EnumType.d.ts +30 -12
- package/dist/types/EnumType.js +43 -17
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/EnumType.spec.d.ts +1 -0
- package/dist/types/EnumType.spec.js +33 -0
- package/dist/types/EnumType.spec.js.map +1 -0
- package/dist/types/FloatType.d.ts +8 -5
- package/dist/types/FloatType.js +18 -16
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -6
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +13 -8
- package/dist/types/FunctionType.js +30 -14
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +28 -0
- package/dist/types/InheritableType.js +152 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +8 -5
- package/dist/types/IntegerType.js +18 -16
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +8 -6
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +12 -13
- package/dist/types/InterfaceType.js +20 -48
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +90 -56
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/InvalidType.d.ts +7 -5
- package/dist/types/InvalidType.js +13 -7
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +8 -6
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +8 -5
- package/dist/types/LongIntegerType.js +17 -15
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +10 -6
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/NamespaceType.d.ts +12 -0
- package/dist/types/NamespaceType.js +28 -0
- package/dist/types/NamespaceType.js.map +1 -0
- package/dist/types/ObjectType.d.ts +9 -8
- package/dist/types/ObjectType.js +21 -11
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ObjectType.spec.js +3 -3
- package/dist/types/ObjectType.spec.js.map +1 -1
- package/dist/types/ReferenceType.d.ts +63 -0
- package/dist/types/ReferenceType.js +423 -0
- package/dist/types/ReferenceType.js.map +1 -0
- package/dist/types/ReferenceType.spec.d.ts +1 -0
- package/dist/types/ReferenceType.spec.js +137 -0
- package/dist/types/ReferenceType.spec.js.map +1 -0
- package/dist/types/StringType.d.ts +11 -5
- package/dist/types/StringType.js +18 -7
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +3 -5
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +22 -17
- package/dist/types/TypedFunctionType.js +78 -60
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/TypedFunctionType.spec.js +105 -20
- package/dist/types/TypedFunctionType.spec.js.map +1 -1
- package/dist/types/UninitializedType.d.ts +8 -6
- package/dist/types/UninitializedType.js +13 -7
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +20 -0
- package/dist/types/UnionType.js +123 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +130 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +8 -5
- package/dist/types/VoidType.js +14 -7
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/VoidType.spec.js +3 -3
- package/dist/types/VoidType.spec.js.map +1 -1
- package/dist/types/helper.spec.d.ts +1 -0
- package/dist/types/helper.spec.js +145 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +19 -37
- package/dist/types/helpers.js +159 -99
- package/dist/types/helpers.js.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.js +39 -0
- package/dist/types/index.js.map +1 -0
- package/dist/util.d.ts +167 -131
- package/dist/util.js +890 -350
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +7 -25
- package/dist/validators/ClassValidator.js +103 -194
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +165 -149
- package/dist/astUtils/AstEditor.js.map +0 -1
- package/dist/astUtils/AstEditor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +0 -8
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +0 -40
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -32
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
- package/dist/parser/SGTypes.spec.js +0 -351
- package/dist/parser/SGTypes.spec.js.map +0 -1
- package/dist/types/CustomType.d.ts +0 -12
- package/dist/types/CustomType.js +0 -44
- package/dist/types/CustomType.js.map +0 -1
- package/dist/types/LazyType.d.ts +0 -16
- package/dist/types/LazyType.js +0 -44
- package/dist/types/LazyType.js.map +0 -1
- /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
- /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{parser/SGTypes.spec.d.ts → bscPlugin/hover/HoverProcessor.spec.d.ts} +0 -0
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,10 +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
|
|
19
|
-
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;
|
|
20
29
|
/**
|
|
21
30
|
* A class to keep track of all declarations within a given scope (like source scope, component scope)
|
|
22
31
|
*/
|
|
@@ -30,6 +39,11 @@ class Scope {
|
|
|
30
39
|
* The list of diagnostics found specifically for this scope. Individual file diagnostics are stored on the files themselves.
|
|
31
40
|
*/
|
|
32
41
|
this.diagnostics = [];
|
|
42
|
+
/**
|
|
43
|
+
* A list of functions that will be called whenever `unlinkSymbolTable` is called
|
|
44
|
+
*/
|
|
45
|
+
this.linkSymbolTableDisposables = [];
|
|
46
|
+
this.symbolsAddedDuringLinking = [];
|
|
33
47
|
this.isValidated = false;
|
|
34
48
|
//used for improved logging performance
|
|
35
49
|
this._debugLogComponentName = `Scope '${chalk_1.default.redBright(this.name)}'`;
|
|
@@ -43,8 +57,52 @@ class Scope {
|
|
|
43
57
|
* "namea", "namea.nameb", "namea.nameb.namec"
|
|
44
58
|
*/
|
|
45
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
|
+
}
|
|
46
74
|
return this.cache.getOrAdd('namespaceLookup', () => this.buildNamespaceLookup());
|
|
47
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
|
+
}
|
|
48
106
|
/**
|
|
49
107
|
* Get the class with the specified name.
|
|
50
108
|
* @param className - The class name, including the namespace of the class if possible
|
|
@@ -63,23 +121,6 @@ class Scope {
|
|
|
63
121
|
var _a;
|
|
64
122
|
return (_a = this.getInterfaceFileLink(ifaceName, containingNamespace)) === null || _a === void 0 ? void 0 : _a.item;
|
|
65
123
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Get either the class or interface, etc. with a given name
|
|
68
|
-
* @param name - The name, including the namespace of the interface if possible
|
|
69
|
-
* @param containingNamespace - The namespace used to resolve relative names. (i.e. the namespace around the current statement trying to find the interface or class)
|
|
70
|
-
*/
|
|
71
|
-
getNamedTypeStatement(name, containingNamespace) {
|
|
72
|
-
var _a;
|
|
73
|
-
return (_a = this.getNamedTypeFileLink(name, containingNamespace)) === null || _a === void 0 ? void 0 : _a.item;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* A cache of a map of tokens -> TokenSymbolLookups, which are the result of getSymbolTypeFromToken()
|
|
77
|
-
* Sometimes the lookup of symbols may take a while if there are lazyTypes or multiple tokens in a chain
|
|
78
|
-
* By caching the result of this lookup, subsequent lookups of the same tokens are quicker
|
|
79
|
-
*/
|
|
80
|
-
get symbolCache() {
|
|
81
|
-
return this.cache.getOrAdd('symbolCache', () => new Map());
|
|
82
|
-
}
|
|
83
124
|
/**
|
|
84
125
|
* Get the enum with the specified name.
|
|
85
126
|
* @param enumName - The enum name, including the namespace if possible
|
|
@@ -105,10 +146,10 @@ class Scope {
|
|
|
105
146
|
return cls;
|
|
106
147
|
}
|
|
107
148
|
/**
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
+
*/
|
|
112
153
|
getInterfaceFileLink(ifaceName, containingNamespace) {
|
|
113
154
|
const lowerName = ifaceName === null || ifaceName === void 0 ? void 0 : ifaceName.toLowerCase();
|
|
114
155
|
const ifaceMap = this.getInterfaceMap();
|
|
@@ -135,68 +176,68 @@ class Scope {
|
|
|
135
176
|
return enumeration;
|
|
136
177
|
}
|
|
137
178
|
/**
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
*/
|
|
142
|
-
getNamedTypeFileLink(name, containingNamespace) {
|
|
143
|
-
return this.getInheritableFileLink(name, containingNamespace) || this.getEnumFileLink(name, containingNamespace);
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Get a InheritableStatement and its containing file by the name of the interface or class
|
|
147
|
-
* @param name - The name of the interface or class, including the namespace of the class if possible
|
|
148
|
-
* @param containingNamespace - The namespace used to resolve relative names. (i.e. the namespace around the current statement trying to find a class)
|
|
149
|
-
*/
|
|
150
|
-
getInheritableFileLink(name, containingNamespace) {
|
|
151
|
-
return this.getClassFileLink(name, containingNamespace) || this.getInterfaceFileLink(name, containingNamespace);
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Gets the parent class of the given class
|
|
155
|
-
* @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)
|
|
156
182
|
*/
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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;
|
|
166
197
|
}
|
|
167
198
|
}
|
|
168
199
|
/**
|
|
169
|
-
*
|
|
170
|
-
* @param
|
|
200
|
+
* Get a constant and its containing file by the constant name
|
|
201
|
+
* @param constName - The constant name, including the namespace of the constant if possible
|
|
202
|
+
* @param containingNamespace - The namespace used to resolve relative constant names. (i.e. the namespace around the current statement trying to find a constant)
|
|
171
203
|
*/
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
}
|
|
204
|
+
getConstFileLink(constName, containingNamespace) {
|
|
205
|
+
const lowerName = constName === null || constName === void 0 ? void 0 : constName.toLowerCase();
|
|
206
|
+
const constMap = this.getConstMap();
|
|
207
|
+
let result = constMap.get(util_1.util.getFullyQualifiedClassName(lowerName, containingNamespace === null || containingNamespace === void 0 ? void 0 : containingNamespace.toLowerCase()));
|
|
208
|
+
//if we couldn't find the constant by its full namespaced name, look for a global constant with that name
|
|
209
|
+
if (!result) {
|
|
210
|
+
result = constMap.get(lowerName);
|
|
181
211
|
}
|
|
212
|
+
return result;
|
|
182
213
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if ((0
|
|
189
|
-
return
|
|
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 });
|
|
223
|
+
}
|
|
190
224
|
}
|
|
191
|
-
|
|
192
|
-
|
|
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
|
+
}
|
|
193
232
|
}
|
|
233
|
+
// remove empty links
|
|
234
|
+
return links.filter(link => link);
|
|
194
235
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
+
*/
|
|
200
241
|
getEnumMemberMap() {
|
|
201
242
|
return this.cache.getOrAdd('enumMemberMap', () => {
|
|
202
243
|
const result = new Map();
|
|
@@ -209,36 +250,28 @@ class Scope {
|
|
|
209
250
|
});
|
|
210
251
|
}
|
|
211
252
|
/**
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
+
*/
|
|
216
257
|
hasClass(className, namespaceName) {
|
|
217
258
|
return !!this.getClass(className, namespaceName);
|
|
218
259
|
}
|
|
219
260
|
/**
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
+
*/
|
|
224
265
|
hasInterface(ifaceName, namespaceName) {
|
|
225
266
|
return !!this.getInterface(ifaceName, namespaceName);
|
|
226
267
|
}
|
|
227
268
|
/**
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
* @param namespaceName - the current namespace name
|
|
231
|
-
*/
|
|
232
|
-
hasEnum(enumName, namespaceName) {
|
|
233
|
-
return !!this.getEnum(enumName, namespaceName);
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Tests if a class OR an interface, etc. exists with the specified name
|
|
237
|
-
* @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
|
|
238
271
|
* @param namespaceName - the current namespace name
|
|
239
272
|
*/
|
|
240
|
-
|
|
241
|
-
return !!this.
|
|
273
|
+
hasEnum(enumName, namespaceName) {
|
|
274
|
+
return !!this.getEnum(enumName, namespaceName);
|
|
242
275
|
}
|
|
243
276
|
/**
|
|
244
277
|
* A dictionary of all classes in this scope. This includes namespaced classes always with their full name.
|
|
@@ -248,13 +281,12 @@ class Scope {
|
|
|
248
281
|
return this.cache.getOrAdd('classMap', () => {
|
|
249
282
|
const map = new Map();
|
|
250
283
|
this.enumerateBrsFiles((file) => {
|
|
251
|
-
var _a;
|
|
252
284
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
253
|
-
for (let cls of file.
|
|
254
|
-
const
|
|
285
|
+
for (let cls of file['_cachedLookups'].classStatements) {
|
|
286
|
+
const className = cls.getName(Parser_1.ParseMode.BrighterScript);
|
|
255
287
|
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
256
|
-
if (
|
|
257
|
-
map.set(
|
|
288
|
+
if (className) {
|
|
289
|
+
map.set(className.toLowerCase(), { item: cls, file: file });
|
|
258
290
|
}
|
|
259
291
|
}
|
|
260
292
|
}
|
|
@@ -262,29 +294,20 @@ class Scope {
|
|
|
262
294
|
return map;
|
|
263
295
|
});
|
|
264
296
|
}
|
|
265
|
-
getAncestorTypeListByContext(thisType, context) {
|
|
266
|
-
var _a;
|
|
267
|
-
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);
|
|
268
|
-
if ((0, reflection_1.isCustomType)(thisType) || (0, reflection_1.isInterfaceType)(thisType)) {
|
|
269
|
-
return this.getAncestorTypeList(thisType.name, funcExpr);
|
|
270
|
-
}
|
|
271
|
-
return [];
|
|
272
|
-
}
|
|
273
297
|
/**
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
+
*/
|
|
277
301
|
getInterfaceMap() {
|
|
278
302
|
return this.cache.getOrAdd('interfaceMap', () => {
|
|
279
303
|
const map = new Map();
|
|
280
304
|
this.enumerateBrsFiles((file) => {
|
|
281
|
-
var _a;
|
|
282
305
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
283
|
-
for (let iface of file.
|
|
284
|
-
const
|
|
306
|
+
for (let iface of file['_cachedLookups'].interfaceStatements) {
|
|
307
|
+
const ifaceName = iface.getName(Parser_1.ParseMode.BrighterScript);
|
|
285
308
|
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
286
|
-
if (
|
|
287
|
-
map.set(
|
|
309
|
+
if (ifaceName) {
|
|
310
|
+
map.set(ifaceName.toLowerCase(), { item: iface, file: file });
|
|
288
311
|
}
|
|
289
312
|
}
|
|
290
313
|
}
|
|
@@ -292,21 +315,6 @@ class Scope {
|
|
|
292
315
|
return map;
|
|
293
316
|
});
|
|
294
317
|
}
|
|
295
|
-
getAncestorTypeList(className, functionExpression) {
|
|
296
|
-
var _a, _b;
|
|
297
|
-
const lowerNamespaceName = (_a = functionExpression.namespaceName) === null || _a === void 0 ? void 0 : _a.getName().toLowerCase();
|
|
298
|
-
const ancestors = [];
|
|
299
|
-
let currentClassOrIFace = (_b = this.getInheritableFileLink(className, lowerNamespaceName)) === null || _b === void 0 ? void 0 : _b.item;
|
|
300
|
-
if (currentClassOrIFace) {
|
|
301
|
-
ancestors.push(currentClassOrIFace === null || currentClassOrIFace === void 0 ? void 0 : currentClassOrIFace.getThisBscType());
|
|
302
|
-
}
|
|
303
|
-
while (currentClassOrIFace === null || currentClassOrIFace === void 0 ? void 0 : currentClassOrIFace.hasParent()) {
|
|
304
|
-
currentClassOrIFace = this.getParentStatement(currentClassOrIFace);
|
|
305
|
-
ancestors.push(currentClassOrIFace === null || currentClassOrIFace === void 0 ? void 0 : currentClassOrIFace.getThisBscType());
|
|
306
|
-
}
|
|
307
|
-
// TODO TYPES: this should probably be cached
|
|
308
|
-
return ancestors;
|
|
309
|
-
}
|
|
310
318
|
/**
|
|
311
319
|
* A dictionary of all enums in this scope. This includes namespaced enums always with their full name.
|
|
312
320
|
* The key is stored in lower case
|
|
@@ -315,11 +323,28 @@ class Scope {
|
|
|
315
323
|
return this.cache.getOrAdd('enumMap', () => {
|
|
316
324
|
const map = new Map();
|
|
317
325
|
this.enumerateBrsFiles((file) => {
|
|
318
|
-
for (let enumStmt of file.
|
|
319
|
-
|
|
326
|
+
for (let enumStmt of file['_cachedLookups'].enumStatements) {
|
|
327
|
+
//only track enums with a defined name (i.e. exclude nameless malformed enums)
|
|
328
|
+
if (enumStmt.fullName) {
|
|
329
|
+
map.set(enumStmt.fullName.toLowerCase(), { item: enumStmt, file: file });
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
return map;
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* A dictionary of all constants in this scope. This includes namespaced constants always with their full name.
|
|
338
|
+
* The key is stored in lower case
|
|
339
|
+
*/
|
|
340
|
+
getConstMap() {
|
|
341
|
+
return this.cache.getOrAdd('constMap', () => {
|
|
342
|
+
const map = new Map();
|
|
343
|
+
this.enumerateBrsFiles((file) => {
|
|
344
|
+
for (let stmt of file['_cachedLookups'].constStatements) {
|
|
320
345
|
//only track enums with a defined name (i.e. exclude nameless malformed enums)
|
|
321
|
-
if (
|
|
322
|
-
map.set(
|
|
346
|
+
if (stmt.fullName) {
|
|
347
|
+
map.set(stmt.fullName.toLowerCase(), { item: stmt, file: file });
|
|
323
348
|
}
|
|
324
349
|
}
|
|
325
350
|
});
|
|
@@ -344,7 +369,7 @@ class Scope {
|
|
|
344
369
|
isKnownNamespace(namespaceName) {
|
|
345
370
|
let namespaceNameLower = namespaceName.toLowerCase();
|
|
346
371
|
this.enumerateBrsFiles((file) => {
|
|
347
|
-
for (let namespace of file.
|
|
372
|
+
for (let namespace of file['_cachedLookups'].namespaceStatements) {
|
|
348
373
|
let loopNamespaceNameLower = namespace.name.toLowerCase();
|
|
349
374
|
if (loopNamespaceNameLower === namespaceNameLower || loopNamespaceNameLower.startsWith(namespaceNameLower + '.')) {
|
|
350
375
|
return true;
|
|
@@ -360,7 +385,7 @@ class Scope {
|
|
|
360
385
|
*/
|
|
361
386
|
getParentScope() {
|
|
362
387
|
let scope;
|
|
363
|
-
//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
|
|
364
389
|
if (this.program.globalScope !== this) {
|
|
365
390
|
scope = this.program.globalScope;
|
|
366
391
|
}
|
|
@@ -383,20 +408,23 @@ class Scope {
|
|
|
383
408
|
this.invalidate();
|
|
384
409
|
}
|
|
385
410
|
/**
|
|
386
|
-
* Get the file with the
|
|
387
|
-
* @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
|
|
388
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
|
|
389
414
|
*/
|
|
390
|
-
getFile(
|
|
391
|
-
if (
|
|
392
|
-
|
|
415
|
+
getFile(filePath, normalizePath = true) {
|
|
416
|
+
if (typeof filePath !== 'string') {
|
|
417
|
+
return undefined;
|
|
393
418
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
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);
|
|
398
424
|
}
|
|
399
|
-
|
|
425
|
+
return result;
|
|
426
|
+
});
|
|
427
|
+
return map.get((normalizePath ? util_1.util.standardizePath(filePath) : filePath).toLowerCase());
|
|
400
428
|
}
|
|
401
429
|
/**
|
|
402
430
|
* Get the list of files referenced by this scope that are actually loaded in the program.
|
|
@@ -423,32 +451,32 @@ class Scope {
|
|
|
423
451
|
}
|
|
424
452
|
}
|
|
425
453
|
else {
|
|
426
|
-
let file = this.program.getFile(dependency
|
|
454
|
+
let file = this.program.getFile(dependency);
|
|
427
455
|
if (file) {
|
|
428
456
|
result.push(file);
|
|
429
457
|
}
|
|
430
458
|
}
|
|
431
459
|
}
|
|
432
|
-
this.logDebug('getAllFiles', () => result.map(x => x.
|
|
460
|
+
this.logDebug('getAllFiles', () => result.map(x => x.destPath));
|
|
433
461
|
return result;
|
|
434
462
|
});
|
|
435
463
|
}
|
|
436
464
|
/**
|
|
437
|
-
* Get the list of errors for this scope. It's calculated on the fly, so
|
|
438
|
-
* call this sparingly.
|
|
465
|
+
* Get the list of errors for this scope. It's calculated on the fly, so call this sparingly.
|
|
439
466
|
*/
|
|
440
467
|
getDiagnostics() {
|
|
441
|
-
let diagnosticLists = [this.diagnostics];
|
|
442
468
|
//add diagnostics from every referenced file
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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) => {
|
|
448
477
|
return !util_1.util.diagnosticIsSuppressed(x);
|
|
449
478
|
});
|
|
450
|
-
|
|
451
|
-
return filteredDiagnostics;
|
|
479
|
+
return diagnostics;
|
|
452
480
|
}
|
|
453
481
|
addDiagnostics(diagnostics) {
|
|
454
482
|
this.diagnostics.push(...diagnostics);
|
|
@@ -469,27 +497,23 @@ class Scope {
|
|
|
469
497
|
/**
|
|
470
498
|
* Get the callable with the specified name.
|
|
471
499
|
* If there are overridden callables with the same name, the closest callable to this scope is returned
|
|
472
|
-
* @param name
|
|
473
500
|
*/
|
|
474
501
|
getCallableByName(name) {
|
|
475
|
-
|
|
476
|
-
let lowerName = name.toLowerCase();
|
|
477
|
-
let callables = this.getAllCallables();
|
|
478
|
-
for (let callable of callables) {
|
|
479
|
-
const callableName = callable.callable.getName(Parser_1.ParseMode.BrighterScript);
|
|
480
|
-
// Split by `.` and check the last term to consider namespaces.
|
|
481
|
-
if (callableName.toLowerCase() === lowerName || ((_a = callableName.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === lowerName) {
|
|
482
|
-
return callable.callable;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
502
|
+
return this.getCallableMap().get(name.toLowerCase());
|
|
485
503
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
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
|
+
});
|
|
493
517
|
}
|
|
494
518
|
/**
|
|
495
519
|
* Iterate over Brs files not shadowed by typedefs
|
|
@@ -510,7 +534,7 @@ class Scope {
|
|
|
510
534
|
const files = this.getOwnFiles();
|
|
511
535
|
for (const file of files) {
|
|
512
536
|
//either XML components or files without a typedef
|
|
513
|
-
if ((0, reflection_1.isXmlFile)(file) || !file.hasTypedef) {
|
|
537
|
+
if ((0, reflection_1.isXmlFile)(file) || ((0, reflection_1.isBrsFile)(file) && !file.hasTypedef)) {
|
|
514
538
|
callback(file);
|
|
515
539
|
}
|
|
516
540
|
}
|
|
@@ -521,14 +545,16 @@ class Scope {
|
|
|
521
545
|
*/
|
|
522
546
|
getOwnCallables() {
|
|
523
547
|
let result = [];
|
|
524
|
-
this.logDebug('getOwnCallables() files: ', () => this.getOwnFiles().map(x => x.
|
|
548
|
+
this.logDebug('getOwnCallables() files: ', () => this.getOwnFiles().map(x => x.destPath));
|
|
525
549
|
//get callables from own files
|
|
526
550
|
this.enumerateOwnFiles((file) => {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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
|
+
}
|
|
532
558
|
}
|
|
533
559
|
});
|
|
534
560
|
return result;
|
|
@@ -536,60 +562,27 @@ class Scope {
|
|
|
536
562
|
/**
|
|
537
563
|
* Builds a tree of namespace objects
|
|
538
564
|
*/
|
|
539
|
-
buildNamespaceLookup() {
|
|
565
|
+
buildNamespaceLookup(options = { okToCache: true }) {
|
|
540
566
|
let namespaceLookup = new Map();
|
|
567
|
+
options.okToCache = true;
|
|
541
568
|
this.enumerateBrsFiles((file) => {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
for (let part of nameParts) {
|
|
550
|
-
loopName = loopName === null ? part : `${loopName}.${part}`;
|
|
551
|
-
let lowerLoopName = loopName.toLowerCase();
|
|
552
|
-
if (!namespaceLookup.has(lowerLoopName)) {
|
|
553
|
-
namespaceLookup.set(lowerLoopName, {
|
|
554
|
-
file: file,
|
|
555
|
-
fullName: loopName,
|
|
556
|
-
nameRange: namespace.nameExpression.range,
|
|
557
|
-
lastPartName: part,
|
|
558
|
-
namespaces: new Map(),
|
|
559
|
-
classStatements: {},
|
|
560
|
-
functionStatements: {},
|
|
561
|
-
enumStatements: new Map(),
|
|
562
|
-
statements: [],
|
|
563
|
-
symbolTable: new SymbolTable_1.SymbolTable(this.symbolTable)
|
|
564
|
-
});
|
|
565
|
-
}
|
|
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);
|
|
566
576
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
else if ((0, reflection_1.isEnumStatement)(statement) && statement.fullName) {
|
|
577
|
-
ns.enumStatements.set(statement.fullName.toLowerCase(), statement);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
// Merges all the symbol tables of the namespace statements into the new symbol table created above.
|
|
581
|
-
// Set those symbol tables to have this new merged table as a parent
|
|
582
|
-
ns.symbolTable.mergeSymbolTable(namespace.symbolTable);
|
|
583
|
-
}
|
|
584
|
-
//associate child namespaces with their parents
|
|
585
|
-
for (let [, ns] of namespaceLookup) {
|
|
586
|
-
let parts = ns.fullName.split('.');
|
|
587
|
-
if (parts.length > 1) {
|
|
588
|
-
//remove the last part
|
|
589
|
-
parts.pop();
|
|
590
|
-
let parentName = parts.join('.');
|
|
591
|
-
const parent = namespaceLookup.get(parentName.toLowerCase());
|
|
592
|
-
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);
|
|
593
586
|
}
|
|
594
587
|
}
|
|
595
588
|
});
|
|
@@ -598,43 +591,69 @@ class Scope {
|
|
|
598
591
|
getAllNamespaceStatements() {
|
|
599
592
|
let result = [];
|
|
600
593
|
this.enumerateBrsFiles((file) => {
|
|
601
|
-
result.push(...file.
|
|
594
|
+
result.push(...file['_cachedLookups'].namespaceStatements);
|
|
602
595
|
});
|
|
603
596
|
return result;
|
|
604
597
|
}
|
|
605
598
|
logDebug(...args) {
|
|
606
599
|
this.program.logger.debug(this._debugLogComponentName, ...args);
|
|
607
600
|
}
|
|
608
|
-
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
|
+
}
|
|
609
607
|
this.program.logger.time(Logger_1.LogLevel.debug, [this._debugLogComponentName, 'validate()'], () => {
|
|
610
608
|
let parentScope = this.getParentScope();
|
|
611
609
|
//validate our parent before we validate ourself
|
|
612
|
-
if (
|
|
610
|
+
if (parentScope && parentScope.isValidated === false) {
|
|
613
611
|
this.logDebug('validate(): validating parent first');
|
|
614
|
-
parentScope.validate();
|
|
612
|
+
parentScope.validate(validationOptions);
|
|
615
613
|
}
|
|
616
614
|
//clear the scope's errors list (we will populate them from this method)
|
|
617
|
-
this.
|
|
618
|
-
// link the symbol table
|
|
619
|
-
this.linkSymbolTable();
|
|
615
|
+
this.clearScopeLevelDiagnostics();
|
|
620
616
|
let callables = this.getAllCallables();
|
|
621
617
|
//sort the callables by filepath and then method name, so the errors will be consistent
|
|
618
|
+
// eslint-disable-next-line prefer-arrow-callback
|
|
622
619
|
callables = callables.sort((a, b) => {
|
|
623
|
-
|
|
620
|
+
const pathA = a.callable.file.srcPath;
|
|
621
|
+
const pathB = b.callable.file.srcPath;
|
|
624
622
|
//sort by path
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
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;
|
|
628
639
|
});
|
|
629
640
|
//get a list of all callables, indexed by their lower case names
|
|
630
641
|
let callableContainerMap = util_1.util.getCallableContainersByLowerName(callables);
|
|
631
|
-
|
|
642
|
+
//Since statements from files are shared across multiple scopes, we need to link those statements to the current scope
|
|
643
|
+
this.linkSymbolTable();
|
|
644
|
+
const scopeValidateEvent = {
|
|
632
645
|
program: this.program,
|
|
633
|
-
scope: this
|
|
634
|
-
|
|
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);
|
|
635
652
|
this._validate(callableContainerMap);
|
|
636
|
-
|
|
653
|
+
this.program.plugins.emit('afterScopeValidate', scopeValidateEvent);
|
|
654
|
+
//unlink all symbol tables from this scope (so they don't accidentally stick around)
|
|
637
655
|
this.unlinkSymbolTable();
|
|
656
|
+
this.isValidated = true;
|
|
638
657
|
});
|
|
639
658
|
}
|
|
640
659
|
_validate(callableContainerMap) {
|
|
@@ -642,17 +661,26 @@ class Scope {
|
|
|
642
661
|
this.diagnosticFindDuplicateFunctionDeclarations(callableContainerMap);
|
|
643
662
|
//detect missing and incorrect-case script imports
|
|
644
663
|
this.diagnosticValidateScriptImportPaths();
|
|
664
|
+
//enforce a series of checks on the bodies of class methods
|
|
665
|
+
this.validateClasses();
|
|
645
666
|
//do many per-file checks
|
|
646
667
|
this.enumerateBrsFiles((file) => {
|
|
647
|
-
//enforce a series of checks on the bodies of class methods
|
|
648
|
-
this.validateClasses(file);
|
|
649
668
|
this.diagnosticDetectShadowedLocalVars(file, callableContainerMap);
|
|
650
669
|
this.diagnosticDetectFunctionCollisions(file);
|
|
651
670
|
this.detectVariableNamespaceCollisions(file);
|
|
652
|
-
this.
|
|
653
|
-
this.diagnosticDetectInvalidFunctionCalls(file, callableContainerMap);
|
|
671
|
+
this.detectNameCollisions(file);
|
|
654
672
|
});
|
|
655
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
|
+
}
|
|
656
684
|
/**
|
|
657
685
|
* Mark this scope as invalid, which means its `validate()` function needs to be called again before use.
|
|
658
686
|
*/
|
|
@@ -660,120 +688,131 @@ class Scope {
|
|
|
660
688
|
this.isValidated = false;
|
|
661
689
|
//clear out various lookups (they'll get regenerated on demand the next time they're requested)
|
|
662
690
|
this.cache.clear();
|
|
663
|
-
this.clearSymbolTable();
|
|
664
|
-
this.symbolCache.clear();
|
|
665
691
|
}
|
|
666
692
|
get symbolTable() {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
693
|
+
return this.cache.getOrAdd('symbolTable', () => {
|
|
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);
|
|
671
697
|
for (let file of this.getOwnFiles()) {
|
|
672
698
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
673
|
-
|
|
699
|
+
result.mergeSymbolTable((_a = file.parser) === null || _a === void 0 ? void 0 : _a.symbolTable);
|
|
674
700
|
}
|
|
675
701
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
}
|
|
679
|
-
get memberTable() {
|
|
680
|
-
var _a;
|
|
681
|
-
if (!this._memberTable) {
|
|
682
|
-
this._memberTable = new SymbolTable_1.SymbolTable((_a = this.getParentScope()) === null || _a === void 0 ? void 0 : _a.memberTable);
|
|
683
|
-
if (!this.getParentScope()) {
|
|
684
|
-
this._memberTable.addSymbol('global', null, new ObjectType_1.ObjectType());
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
return this._memberTable;
|
|
688
|
-
}
|
|
689
|
-
clearSymbolTable() {
|
|
690
|
-
this._symbolTable = null;
|
|
691
|
-
this._memberTable = null;
|
|
702
|
+
return result;
|
|
703
|
+
});
|
|
692
704
|
}
|
|
693
705
|
/**
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
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
|
+
*/
|
|
698
724
|
linkSymbolTable() {
|
|
699
|
-
var _a
|
|
725
|
+
var _a;
|
|
726
|
+
SymbolTable_1.SymbolTable.cacheVerifier.generateToken();
|
|
700
727
|
for (const file of this.getAllFiles()) {
|
|
701
728
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
702
|
-
file.parser.symbolTable.
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
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;
|
|
707
745
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
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 });
|
|
717
760
|
}
|
|
718
761
|
else {
|
|
719
|
-
|
|
762
|
+
this.symbolTable.addSymbol(nsContainer.lastPartName, { definingNode: existingNsStmt }, currentNSType, getTypeOptions.flags);
|
|
763
|
+
this.symbolsAddedDuringLinking.push({ symbolTable: this.symbolTable, name: nsContainer.lastPartName, flags: getTypeOptions.flags });
|
|
720
764
|
}
|
|
721
765
|
}
|
|
766
|
+
else {
|
|
767
|
+
break;
|
|
768
|
+
}
|
|
722
769
|
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
const ifaceStmt = (_b = pair[1]) === null || _b === void 0 ? void 0 : _b.item;
|
|
734
|
-
ifaceStmt === null || ifaceStmt === void 0 ? void 0 : ifaceStmt.buildSymbolTable(this.getParentInterface(ifaceStmt));
|
|
735
|
-
}
|
|
736
|
-
//also link enums
|
|
737
|
-
const enumMap = this.getEnumMap();
|
|
738
|
-
for (const pair of enumMap) {
|
|
739
|
-
const enumStmt = (_c = pair[1]) === null || _c === void 0 ? void 0 : _c.item;
|
|
740
|
-
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));
|
|
741
780
|
}
|
|
742
781
|
}
|
|
743
782
|
unlinkSymbolTable() {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
if ((0, reflection_1.isBrsFile)(file)) {
|
|
747
|
-
(_a = file.parser) === null || _a === void 0 ? void 0 : _a.symbolTable.setParent(null);
|
|
748
|
-
for (const namespace of file.parser.references.namespaceStatements) {
|
|
749
|
-
namespace.symbolTable.setParent(null);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
783
|
+
for (const symbolToRemove of this.symbolsAddedDuringLinking) {
|
|
784
|
+
this.symbolTable.removeSymbol(symbolToRemove.name);
|
|
752
785
|
}
|
|
786
|
+
this.symbolsAddedDuringLinking = [];
|
|
787
|
+
for (const dispose of this.linkSymbolTableDisposables) {
|
|
788
|
+
dispose();
|
|
789
|
+
}
|
|
790
|
+
this.linkSymbolTableDisposables = [];
|
|
753
791
|
}
|
|
754
792
|
detectVariableNamespaceCollisions(file) {
|
|
793
|
+
var _a, _b;
|
|
755
794
|
//find all function parameters
|
|
756
|
-
for (let func of file.
|
|
795
|
+
for (let func of file['_cachedLookups'].functionExpressions) {
|
|
757
796
|
for (let param of func.parameters) {
|
|
758
797
|
let lowerParamName = param.name.text.toLowerCase();
|
|
759
|
-
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());
|
|
760
799
|
//see if the param matches any starting namespace part
|
|
761
800
|
if (namespace) {
|
|
762
|
-
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: [{
|
|
763
802
|
message: 'Namespace declared here',
|
|
764
|
-
location:
|
|
803
|
+
location: util_1.util.createLocation(vscode_uri_1.URI.file(namespace.file.srcPath).toString(), namespace.nameRange)
|
|
765
804
|
}] }));
|
|
766
805
|
}
|
|
767
806
|
}
|
|
768
807
|
}
|
|
769
|
-
for (let assignment of file.
|
|
808
|
+
for (let assignment of file['_cachedLookups'].assignmentStatements) {
|
|
770
809
|
let lowerAssignmentName = assignment.name.text.toLowerCase();
|
|
771
|
-
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());
|
|
772
811
|
//see if the param matches any starting namespace part
|
|
773
812
|
if (namespace) {
|
|
774
|
-
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: [{
|
|
775
814
|
message: 'Namespace declared here',
|
|
776
|
-
location:
|
|
815
|
+
location: util_1.util.createLocation(vscode_uri_1.URI.file(namespace.file.srcPath).toString(), namespace.nameRange)
|
|
777
816
|
}] }));
|
|
778
817
|
}
|
|
779
818
|
}
|
|
@@ -788,132 +827,84 @@ class Scope {
|
|
|
788
827
|
if (lowerFuncName) {
|
|
789
828
|
//find function declarations with the same name as a stdlib function
|
|
790
829
|
if (globalCallables_1.globalCallableMap.has(lowerFuncName)) {
|
|
791
|
-
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 }));
|
|
792
831
|
}
|
|
793
832
|
//find any functions that have the same name as a class
|
|
794
|
-
|
|
795
|
-
|
|
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
|
+
}] }));
|
|
796
839
|
}
|
|
797
840
|
}
|
|
798
841
|
}
|
|
799
842
|
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
let paramType = (0, BscType_1.getTypeFromContext)(param.getType(), typeContext);
|
|
818
|
-
while ((0, reflection_1.isArrayType)(paramType)) {
|
|
819
|
-
paramType = (0, BscType_1.getTypeFromContext)(paramType.getDefaultType(typeContext), typeContext);
|
|
820
|
-
}
|
|
821
|
-
if (!paramType && param.type) {
|
|
822
|
-
const paramTypeName = param.type.getText();
|
|
823
|
-
const currentNamespaceName = (_d = func.namespaceName) === null || _d === void 0 ? void 0 : _d.getName(Parser_1.ParseMode.BrighterScript);
|
|
824
|
-
if (!this.hasClass(paramTypeName, currentNamespaceName) && !this.hasInterface(paramTypeName) && !this.hasEnum(paramTypeName)) {
|
|
825
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(param.name.text, paramTypeName)), { range: param.type.range, file: file }));
|
|
826
|
-
}
|
|
827
|
-
}
|
|
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);
|
|
828
860
|
}
|
|
829
|
-
}
|
|
861
|
+
}), {
|
|
862
|
+
walkMode: visitors_1.WalkMode.visitStatements
|
|
863
|
+
});
|
|
830
864
|
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
// This is a generic function, and it is callable
|
|
858
|
-
}
|
|
859
|
-
else if ((0, reflection_1.isTypedFunctionType)(funcType)) {
|
|
860
|
-
// Check for Argument count mismatch.
|
|
861
|
-
//get min/max parameter count for callable
|
|
862
|
-
let paramCount = util_1.util.getMinMaxParamCount(funcType.params);
|
|
863
|
-
if (expCall.args.length > paramCount.max || expCall.args.length < paramCount.min) {
|
|
864
|
-
this.addMismatchParamCountDiagnostic(paramCount, expCall, file);
|
|
865
|
-
}
|
|
866
|
-
// Check for Argument type mismatch.
|
|
867
|
-
const paramTypeContext = { file: file, scope: this, position: (_b = expCall.functionExpression.range) === null || _b === void 0 ? void 0 : _b.start };
|
|
868
|
-
const argTypeContext = { file: file, scope: this, position: (_c = expCall.range) === null || _c === void 0 ? void 0 : _c.start };
|
|
869
|
-
for (let index = 0; index < funcType.params.length; index++) {
|
|
870
|
-
const param = funcType.params[index];
|
|
871
|
-
const arg = expCall.args[index];
|
|
872
|
-
if (!arg) {
|
|
873
|
-
// not enough args
|
|
874
|
-
break;
|
|
875
|
-
}
|
|
876
|
-
let argType = (_d = arg.type) !== null && _d !== void 0 ? _d : new UninitializedType_1.UninitializedType();
|
|
877
|
-
const paramType = (0, BscType_1.getTypeFromContext)(param.type, paramTypeContext);
|
|
878
|
-
if (!paramType) {
|
|
879
|
-
// other error - can not determine what type this parameter should be
|
|
880
|
-
continue;
|
|
881
|
-
}
|
|
882
|
-
argType = (0, BscType_1.getTypeFromContext)(argType, argTypeContext);
|
|
883
|
-
let assignable = argType === null || argType === void 0 ? void 0 : argType.isAssignableTo(paramType, argTypeContext);
|
|
884
|
-
if (!assignable) {
|
|
885
|
-
// TODO TYPES: perhaps this should be a strict mode setting?
|
|
886
|
-
assignable = argType === null || argType === void 0 ? void 0 : argType.isConvertibleTo(paramType, argTypeContext);
|
|
887
|
-
}
|
|
888
|
-
if (!assignable) {
|
|
889
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch(argType === null || argType === void 0 ? void 0 : argType.toString(argTypeContext), paramType.toString(paramTypeContext))), { range: arg === null || arg === void 0 ? void 0 : arg.range, file: file }));
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
else if ((0, reflection_1.isInvalidType)(symbolTypeInfo.type)) {
|
|
894
|
-
// TODO TYPES: standard member functions like integer.ToStr() are not detectable yet.
|
|
895
|
-
}
|
|
896
|
-
else if ((0, reflection_1.isDynamicType)(symbolTypeInfo.type)) {
|
|
897
|
-
// maybe this is a function? who knows
|
|
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;
|
|
898
891
|
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
//TODO detect end of expression call
|
|
903
|
-
file: file }));
|
|
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;
|
|
904
895
|
}
|
|
905
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 }));
|
|
906
902
|
}
|
|
907
903
|
}
|
|
908
|
-
addMismatchParamCountDiagnostic(paramCount, expCall, file) {
|
|
909
|
-
const minMaxParamsText = paramCount.min === paramCount.max ? paramCount.max : `${paramCount.min}-${paramCount.max}`;
|
|
910
|
-
const expCallArgCount = expCall.args.length;
|
|
911
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(minMaxParamsText, expCallArgCount)), { range: expCall.nameRange, file: file }));
|
|
912
|
-
}
|
|
913
904
|
getNewExpressions() {
|
|
914
905
|
let result = [];
|
|
915
906
|
this.enumerateBrsFiles((file) => {
|
|
916
|
-
let expressions = file.
|
|
907
|
+
let expressions = file['_cachedLookups'].newExpressions;
|
|
917
908
|
for (let expression of expressions) {
|
|
918
909
|
expression.file = file;
|
|
919
910
|
result.push(expression);
|
|
@@ -921,57 +912,54 @@ class Scope {
|
|
|
921
912
|
});
|
|
922
913
|
return result;
|
|
923
914
|
}
|
|
924
|
-
validateClasses(
|
|
925
|
-
let validator = new ClassValidator_1.BsClassValidator();
|
|
926
|
-
validator.validate(
|
|
927
|
-
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
|
+
}));
|
|
928
921
|
}
|
|
929
922
|
/**
|
|
930
|
-
* Detect local variables (
|
|
931
|
-
* @param file
|
|
932
|
-
* @param callableContainerMap
|
|
923
|
+
* Detect local variables (function scope) that have the same name as scope calls
|
|
933
924
|
*/
|
|
934
925
|
diagnosticDetectShadowedLocalVars(file, callableContainerMap) {
|
|
926
|
+
var _a;
|
|
935
927
|
const classMap = this.getClassMap();
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
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)) {
|
|
942
940
|
//local var function with same name as stdlib function
|
|
943
|
-
if (
|
|
944
|
-
|
|
945
|
-
globalCallables_1.globalCallableMap.has(symbolNameLower)) {
|
|
946
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('stdlib')), { range: symbol.range, file: file }));
|
|
947
|
-
//this check needs to come after the stdlib one, because the stdlib functions are included
|
|
948
|
-
//in the scope function list
|
|
949
|
-
}
|
|
950
|
-
else if (
|
|
951
|
-
//has same name as scope function
|
|
952
|
-
callableContainerMap.has(symbolNameLower)) {
|
|
953
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('scope')), { range: symbol.range, file: file }));
|
|
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 }));
|
|
954
943
|
}
|
|
955
|
-
//var is not a function
|
|
956
944
|
}
|
|
957
|
-
else if (
|
|
958
|
-
//is NOT a callable from stdlib (because non-function local vars can have same name as stdlib names)
|
|
959
|
-
!globalCallables_1.globalCallableMap.has(symbolNameLower)) {
|
|
945
|
+
else if (callableContainerMap.has(lowerVarName)) {
|
|
960
946
|
//is same name as a callable
|
|
961
|
-
if (
|
|
962
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
963
|
-
//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 }));
|
|
964
949
|
}
|
|
965
|
-
else
|
|
966
|
-
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 }));
|
|
967
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 }));
|
|
968
957
|
}
|
|
969
958
|
}
|
|
970
959
|
}
|
|
971
960
|
}
|
|
972
961
|
/**
|
|
973
962
|
* Create diagnostics for any duplicate function declarations
|
|
974
|
-
* @param callablesByLowerName
|
|
975
963
|
*/
|
|
976
964
|
diagnosticFindDuplicateFunctionDeclarations(callableContainersByLowerName) {
|
|
977
965
|
//for each list of callables with the same name
|
|
@@ -1004,9 +992,9 @@ class Scope {
|
|
|
1004
992
|
//same file: skip redundant imports
|
|
1005
993
|
continue;
|
|
1006
994
|
}
|
|
1007
|
-
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,
|
|
1008
996
|
//grab the last item in the list, which should be the closest ancestor's version
|
|
1009
|
-
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 }));
|
|
1010
998
|
}
|
|
1011
999
|
}
|
|
1012
1000
|
}
|
|
@@ -1014,7 +1002,7 @@ class Scope {
|
|
|
1014
1002
|
if (ownCallables.length > 1) {
|
|
1015
1003
|
for (let callableContainer of ownCallables) {
|
|
1016
1004
|
let callable = callableContainer.callable;
|
|
1017
|
-
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 }));
|
|
1018
1006
|
}
|
|
1019
1007
|
}
|
|
1020
1008
|
}
|
|
@@ -1041,11 +1029,11 @@ class Scope {
|
|
|
1041
1029
|
let scriptImports = this.getOwnScriptImports();
|
|
1042
1030
|
//verify every script import
|
|
1043
1031
|
for (let scriptImport of scriptImports) {
|
|
1044
|
-
let referencedFile = this.getFileByRelativePath(scriptImport.
|
|
1032
|
+
let referencedFile = this.getFileByRelativePath(scriptImport.destPath);
|
|
1045
1033
|
//if we can't find the file
|
|
1046
1034
|
if (!referencedFile) {
|
|
1047
1035
|
//skip the default bslib file, it will exist at transpile time but should not show up in the program during validation cycle
|
|
1048
|
-
if (scriptImport.
|
|
1036
|
+
if (scriptImport.destPath === this.program.bslibPkgPath) {
|
|
1049
1037
|
continue;
|
|
1050
1038
|
}
|
|
1051
1039
|
let dInfo;
|
|
@@ -1055,17 +1043,16 @@ class Scope {
|
|
|
1055
1043
|
else {
|
|
1056
1044
|
dInfo = DiagnosticMessages_1.DiagnosticMessages.referencedFileDoesNotExist();
|
|
1057
1045
|
}
|
|
1058
|
-
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 }));
|
|
1059
1047
|
//if the character casing of the script import path does not match that of the actual path
|
|
1060
1048
|
}
|
|
1061
|
-
else if (scriptImport.
|
|
1062
|
-
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 }));
|
|
1063
1051
|
}
|
|
1064
1052
|
}
|
|
1065
1053
|
}
|
|
1066
1054
|
/**
|
|
1067
1055
|
* Find the file with the specified relative path
|
|
1068
|
-
* @param relativePath
|
|
1069
1056
|
*/
|
|
1070
1057
|
getFileByRelativePath(relativePath) {
|
|
1071
1058
|
if (!relativePath) {
|
|
@@ -1073,49 +1060,19 @@ class Scope {
|
|
|
1073
1060
|
}
|
|
1074
1061
|
let files = this.getAllFiles();
|
|
1075
1062
|
for (let file of files) {
|
|
1076
|
-
if (file.
|
|
1063
|
+
if (file.destPath.toLowerCase() === relativePath.toLowerCase()) {
|
|
1077
1064
|
return file;
|
|
1078
1065
|
}
|
|
1079
1066
|
}
|
|
1080
1067
|
}
|
|
1081
1068
|
/**
|
|
1082
1069
|
* Determine if this file is included in this scope (excluding parent scopes)
|
|
1083
|
-
* @param file
|
|
1084
1070
|
*/
|
|
1085
1071
|
hasFile(file) {
|
|
1086
1072
|
let files = this.getOwnFiles();
|
|
1087
1073
|
let hasFile = files.includes(file);
|
|
1088
1074
|
return hasFile;
|
|
1089
1075
|
}
|
|
1090
|
-
/**
|
|
1091
|
-
* Get all callables as completionItems
|
|
1092
|
-
*/
|
|
1093
|
-
getCallablesAsCompletions(parseMode) {
|
|
1094
|
-
let completions = [];
|
|
1095
|
-
let callables = this.getAllCallables();
|
|
1096
|
-
if (parseMode === Parser_1.ParseMode.BrighterScript) {
|
|
1097
|
-
//throw out the namespaced callables (they will be handled by another method)
|
|
1098
|
-
callables = callables.filter(x => x.callable.hasNamespace === false);
|
|
1099
|
-
}
|
|
1100
|
-
for (let callableContainer of callables) {
|
|
1101
|
-
completions.push(this.createCompletionFromCallable(callableContainer));
|
|
1102
|
-
}
|
|
1103
|
-
return completions;
|
|
1104
|
-
}
|
|
1105
|
-
createCompletionFromCallable(callableContainer) {
|
|
1106
|
-
return {
|
|
1107
|
-
label: callableContainer.callable.getName(Parser_1.ParseMode.BrighterScript),
|
|
1108
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function,
|
|
1109
|
-
detail: callableContainer.callable.shortDescription,
|
|
1110
|
-
documentation: callableContainer.callable.documentation ? { kind: 'markdown', value: callableContainer.callable.documentation } : undefined
|
|
1111
|
-
};
|
|
1112
|
-
}
|
|
1113
|
-
createCompletionFromFunctionStatement(statement) {
|
|
1114
|
-
return {
|
|
1115
|
-
label: statement.getName(Parser_1.ParseMode.BrighterScript),
|
|
1116
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
1117
|
-
};
|
|
1118
|
-
}
|
|
1119
1076
|
/**
|
|
1120
1077
|
* Get the definition (where was this thing first defined) of the symbol under the position
|
|
1121
1078
|
*/
|
|
@@ -1123,41 +1080,10 @@ class Scope {
|
|
|
1123
1080
|
// Overridden in XMLScope. Brs files use implementation in BrsFile
|
|
1124
1081
|
return [];
|
|
1125
1082
|
}
|
|
1126
|
-
/**
|
|
1127
|
-
* Scan all files for property names, and return them as completions
|
|
1128
|
-
*/
|
|
1129
|
-
getPropertyNameCompletions() {
|
|
1130
|
-
let results = [];
|
|
1131
|
-
this.enumerateBrsFiles((file) => {
|
|
1132
|
-
results.push(...file.propertyNameCompletions);
|
|
1133
|
-
});
|
|
1134
|
-
return results;
|
|
1135
|
-
}
|
|
1136
|
-
getAllClassMemberCompletions() {
|
|
1137
|
-
let results = new Map();
|
|
1138
|
-
let filesSearched = new Set();
|
|
1139
|
-
for (const file of this.getAllFiles()) {
|
|
1140
|
-
if ((0, reflection_1.isXmlFile)(file) || filesSearched.has(file)) {
|
|
1141
|
-
continue;
|
|
1142
|
-
}
|
|
1143
|
-
filesSearched.add(file);
|
|
1144
|
-
for (let cs of file.parser.references.classStatements) {
|
|
1145
|
-
for (let s of [...cs.methods, ...cs.fields]) {
|
|
1146
|
-
if (!results.has(s.name.text) && s.name.text.toLowerCase() !== 'new') {
|
|
1147
|
-
results.set(s.name.text, {
|
|
1148
|
-
label: s.name.text,
|
|
1149
|
-
kind: (0, reflection_1.isMethodStatement)(s) ? vscode_languageserver_1.CompletionItemKind.Method : vscode_languageserver_1.CompletionItemKind.Field
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
return results;
|
|
1156
|
-
}
|
|
1157
1083
|
/**
|
|
1158
1084
|
* @param className - The name of the class (including namespace if possible)
|
|
1159
1085
|
* @param callsiteNamespace - the name of the namespace where the call site resides (this is NOT the known namespace of the class).
|
|
1160
|
-
* 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.
|
|
1161
1087
|
*/
|
|
1162
1088
|
getClassHierarchy(className, callsiteNamespace) {
|
|
1163
1089
|
var _a, _b;
|
|
@@ -1165,7 +1091,7 @@ class Scope {
|
|
|
1165
1091
|
let link = this.getClassFileLink(className, callsiteNamespace);
|
|
1166
1092
|
while (link) {
|
|
1167
1093
|
items.push(link);
|
|
1168
|
-
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);
|
|
1169
1095
|
}
|
|
1170
1096
|
return items;
|
|
1171
1097
|
}
|