brighterscript 1.0.0-alpha.3 → 1.0.0-alpha.30
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 +1230 -285
- package/README.md +61 -131
- package/bsconfig.schema.json +68 -2
- 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 +35 -0
- package/dist/AstValidationSegmenter.js +209 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +51 -6
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.d.ts +5 -6
- package/dist/Cache.js +12 -11
- 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 +11 -2
- package/dist/CodeActionUtil.js +17 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +7 -6
- package/dist/CommentFlagProcessor.js +10 -7
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +8 -3
- package/dist/DependencyGraph.js +49 -16
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.d.ts +5 -3
- package/dist/DiagnosticCollection.js +18 -16
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +8 -4
- package/dist/DiagnosticFilterer.js +77 -44
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticManager.d.ts +55 -0
- package/dist/DiagnosticManager.js +214 -0
- package/dist/DiagnosticManager.js.map +1 -0
- package/dist/DiagnosticMessages.d.ts +184 -17
- package/dist/DiagnosticMessages.js +242 -24
- 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 +72 -47
- package/dist/LanguageServer.js +544 -312
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +9 -10
- package/dist/Logger.js +36 -30
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +29 -7
- package/dist/PluginInterface.js +90 -7
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +204 -99
- package/dist/Program.js +1060 -699
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +29 -18
- package/dist/ProgramBuilder.js +170 -132
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +144 -109
- package/dist/Scope.js +538 -551
- package/dist/Scope.js.map +1 -1
- package/dist/SemanticTokenUtils.d.ts +14 -0
- package/dist/SemanticTokenUtils.js +81 -0
- package/dist/SemanticTokenUtils.js.map +1 -0
- package/dist/Stopwatch.d.ts +4 -0
- package/dist/Stopwatch.js +8 -1
- package/dist/Stopwatch.js.map +1 -1
- package/dist/SymbolTable.d.ts +91 -24
- package/dist/SymbolTable.js +286 -63
- package/dist/SymbolTable.js.map +1 -1
- package/dist/SymbolTypeFlag.d.ts +8 -0
- package/dist/SymbolTypeFlag.js +13 -0
- package/dist/SymbolTypeFlag.js.map +1 -0
- 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 +5 -15
- package/dist/XmlScope.js +35 -87
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +49 -0
- package/dist/astUtils/CachedLookups.js +324 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/Editor.d.ts +69 -0
- package/dist/astUtils/Editor.js +245 -0
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/Editor.spec.js +258 -0
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +33 -10
- package/dist/astUtils/creators.js +224 -30
- 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 +145 -82
- package/dist/astUtils/reflection.js +304 -132
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +267 -162
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +14 -14
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +114 -53
- package/dist/astUtils/visitors.js +70 -13
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +465 -51
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -8
- package/dist/astUtils/xml.js +10 -5
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +22 -1
- package/dist/bscPlugin/BscPlugin.js +88 -0
- 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 +137 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +26 -17
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +94 -20
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +60 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js +601 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +2139 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js +210 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js +88 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
- package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +18 -0
- package/dist/bscPlugin/hover/HoverProcessor.js +218 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +737 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
- package/dist/bscPlugin/references/ReferencesProvider.js +56 -0
- package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +14 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +138 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +491 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
- 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/symbols/DocumentSymbolProcessor.d.ts +7 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js +22 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js.map +1 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +291 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.d.ts +7 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js +26 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js.map +1 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +245 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/symbols/symbolUtils.d.ts +5 -0
- package/dist/bscPlugin/symbols/symbolUtils.js +140 -0
- package/dist/bscPlugin/symbols/symbolUtils.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +21 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +202 -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/BrsFileAfterValidatior.d.ts +7 -0
- package/dist/bscPlugin/validation/BrsFileAfterValidatior.js +18 -0
- package/dist/bscPlugin/validation/BrsFileAfterValidatior.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +34 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +462 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +758 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/ProgramValidator.d.ts +11 -0
- package/dist/bscPlugin/validation/ProgramValidator.js +33 -0
- package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +131 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +1097 -0
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2796 -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 +117 -11
- 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 +10 -3
- package/dist/diagnosticUtils.js +58 -21
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +8 -12
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +24 -0
- package/dist/files/AssetFile.js +25 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +858 -153
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +144 -82
- package/dist/files/BrsFile.js +847 -911
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +2928 -834
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +101 -0
- package/dist/files/BscFile.js +15 -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 +73 -41
- package/dist/files/XmlFile.js +126 -138
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +450 -318
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +62 -52
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.d.ts +1 -0
- package/dist/files/tests/optionalChaning.spec.js +152 -0
- package/dist/files/tests/optionalChaning.spec.js.map +1 -0
- package/dist/globalCallables.d.ts +3 -1
- package/dist/globalCallables.js +416 -162
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +25 -3
- package/dist/index.js +42 -5
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +722 -119
- package/dist/interfaces.js +31 -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 +40 -9
- package/dist/lexer/Lexer.js +191 -49
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +775 -563
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +11 -3
- package/dist/lexer/Token.js +10 -2
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +27 -1
- package/dist/lexer/TokenKind.js +112 -5
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/logging.d.ts +9 -0
- package/dist/logging.js +16 -0
- package/dist/logging.js.map +1 -0
- package/dist/parser/AstNode.d.ts +180 -0
- package/dist/parser/AstNode.js +245 -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 +12 -2
- package/dist/parser/BrsTranspileState.js +6 -0
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +454 -210
- package/dist/parser/Expression.js +953 -498
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +200 -95
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +105 -120
- package/dist/parser/Parser.js +1406 -912
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +1383 -456
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +44 -6
- package/dist/parser/SGParser.js +212 -185
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +30 -28
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +293 -50
- package/dist/parser/SGTypes.js +540 -187
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +734 -244
- package/dist/parser/Statement.js +1758 -611
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +45 -34
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +17 -8
- package/dist/parser/TranspileState.js +73 -11
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.d.ts +10 -9
- package/dist/parser/tests/Parser.spec.js +18 -14
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +79 -69
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +53 -47
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +217 -196
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +48 -42
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +31 -31
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +157 -120
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +202 -139
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +25 -25
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +150 -41
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +18 -18
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +257 -257
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +160 -90
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +38 -38
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +196 -98
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +42 -42
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +42 -42
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +171 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/Relational.spec.js +44 -44
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +31 -31
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +230 -90
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +377 -148
- 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 +126 -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 +37 -37
- 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 +45 -45
- 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.d.ts +1 -0
- package/dist/parser/tests/statement/Enum.spec.js +684 -0
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
- package/dist/parser/tests/statement/For.spec.d.ts +1 -0
- package/dist/parser/tests/statement/For.spec.js +45 -0
- package/dist/parser/tests/statement/For.spec.js.map +1 -0
- package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ForEach.spec.js +36 -0
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
- package/dist/parser/tests/statement/Function.spec.js +208 -198
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +16 -15
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +51 -51
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +109 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/LibraryStatement.spec.js +18 -18
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +123 -163
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +125 -108
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +51 -49
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +110 -97
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +13 -12
- 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 +26 -15
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +6 -6
- package/dist/preprocessor/Manifest.js +17 -38
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/preprocessor/Manifest.spec.d.ts +1 -0
- package/dist/preprocessor/Manifest.spec.js +78 -103
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/roku-types/data.json +19351 -0
- package/dist/roku-types/index.d.ts +5483 -0
- package/dist/roku-types/index.js +11 -0
- package/dist/roku-types/index.js.map +1 -0
- package/dist/types/ArrayType.d.ts +9 -5
- package/dist/types/ArrayType.js +68 -24
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +39 -11
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +14 -0
- package/dist/types/AssociativeArrayType.js +60 -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 +10 -5
- package/dist/types/BooleanType.js +21 -9
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +10 -4
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +29 -3
- package/dist/types/BscType.js +121 -0
- 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 +174 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +115 -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 +76 -0
- package/dist/types/ClassType.spec.js.map +1 -0
- package/dist/types/ComponentType.d.ts +27 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +10 -5
- package/dist/types/DoubleType.js +25 -18
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +12 -4
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +12 -5
- package/dist/types/DynamicType.js +22 -6
- 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 +40 -0
- package/dist/types/EnumType.js +80 -0
- package/dist/types/EnumType.js.map +1 -0
- 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 +10 -5
- package/dist/types/FloatType.js +25 -18
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -4
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +10 -22
- package/dist/types/FunctionType.js +26 -63
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +28 -0
- package/dist/types/InheritableType.js +157 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +10 -5
- package/dist/types/IntegerType.js +25 -18
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +8 -4
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +14 -6
- package/dist/types/InterfaceType.js +26 -15
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.d.ts +1 -0
- package/dist/types/InterfaceType.spec.js +227 -0
- package/dist/types/InterfaceType.spec.js.map +1 -0
- package/dist/types/InvalidType.d.ts +9 -5
- package/dist/types/InvalidType.js +20 -9
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +8 -4
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +10 -5
- package/dist/types/LongIntegerType.js +25 -18
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +10 -4
- 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 +10 -5
- package/dist/types/ObjectType.js +23 -9
- 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 +71 -0
- package/dist/types/ReferenceType.js +467 -0
- package/dist/types/ReferenceType.js.map +1 -0
- package/dist/types/ReferenceType.spec.d.ts +1 -0
- package/dist/types/ReferenceType.spec.js +151 -0
- package/dist/types/ReferenceType.spec.js.map +1 -0
- package/dist/types/StringType.d.ts +13 -5
- package/dist/types/StringType.js +25 -9
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +3 -3
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +33 -0
- package/dist/types/TypedFunctionType.js +106 -0
- package/dist/types/TypedFunctionType.js.map +1 -0
- package/dist/types/TypedFunctionType.spec.d.ts +1 -0
- package/dist/types/TypedFunctionType.spec.js +122 -0
- package/dist/types/TypedFunctionType.spec.js.map +1 -0
- package/dist/types/UninitializedType.d.ts +8 -6
- package/dist/types/UninitializedType.js +15 -9
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +20 -0
- package/dist/types/UnionType.js +127 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +129 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +10 -5
- package/dist/types/VoidType.js +20 -9
- 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 +144 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +24 -0
- package/dist/types/helpers.js +178 -0
- package/dist/types/helpers.js.map +1 -0
- 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 +216 -106
- package/dist/util.js +1289 -319
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +9 -15
- package/dist/validators/ClassValidator.js +81 -134
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +169 -138
- package/dist/astUtils/index.d.ts +0 -7
- package/dist/astUtils/index.js +0 -26
- package/dist/astUtils/index.js.map +0 -1
- package/dist/lexer/index.d.ts +0 -3
- package/dist/lexer/index.js +0 -17
- package/dist/lexer/index.js.map +0 -1
- package/dist/parser/index.d.ts +0 -3
- package/dist/parser/index.js +0 -16
- package/dist/parser/index.js.map +0 -1
- package/dist/preprocessor/Chunk.d.ts +0 -82
- package/dist/preprocessor/Chunk.js +0 -77
- package/dist/preprocessor/Chunk.js.map +0 -1
- package/dist/preprocessor/Preprocessor.d.ts +0 -60
- package/dist/preprocessor/Preprocessor.js +0 -156
- package/dist/preprocessor/Preprocessor.js.map +0 -1
- package/dist/preprocessor/Preprocessor.spec.js +0 -152
- package/dist/preprocessor/Preprocessor.spec.js.map +0 -1
- package/dist/preprocessor/PreprocessorParser.d.ts +0 -61
- package/dist/preprocessor/PreprocessorParser.js +0 -194
- package/dist/preprocessor/PreprocessorParser.js.map +0 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +0 -116
- package/dist/preprocessor/PreprocessorParser.spec.js.map +0 -1
- package/dist/preprocessor/index.d.ts +0 -3
- package/dist/preprocessor/index.js +0 -16
- package/dist/preprocessor/index.js.map +0 -1
- package/dist/types/CustomType.d.ts +0 -10
- package/dist/types/CustomType.js +0 -35
- package/dist/types/CustomType.js.map +0 -1
- package/dist/types/FunctionType.spec.js +0 -29
- package/dist/types/FunctionType.spec.js.map +0 -1
- package/dist/types/LazyType.d.ts +0 -15
- package/dist/types/LazyType.js +0 -32
- package/dist/types/LazyType.js.map +0 -1
- /package/dist/{preprocessor/Preprocessor.spec.d.ts → astUtils/Editor.spec.d.ts} +0 -0
- /package/dist/{preprocessor/PreprocessorParser.spec.d.ts → bscPlugin/completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{types/FunctionType.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
package/dist/files/BrsFile.js
CHANGED
|
@@ -1,86 +1,199 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.BrsFile = void 0;
|
|
4
4
|
const source_map_1 = require("source-map");
|
|
5
5
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
6
|
+
const vscode_languageserver_2 = require("vscode-languageserver");
|
|
6
7
|
const chalk_1 = require("chalk");
|
|
7
8
|
const path = require("path");
|
|
8
9
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
9
|
-
const
|
|
10
|
-
const
|
|
10
|
+
const FunctionScope_1 = require("../FunctionScope");
|
|
11
|
+
const Lexer_1 = require("../lexer/Lexer");
|
|
12
|
+
const TokenKind_1 = require("../lexer/TokenKind");
|
|
13
|
+
const Parser_1 = require("../parser/Parser");
|
|
14
|
+
const DynamicType_1 = require("../types/DynamicType");
|
|
11
15
|
const util_1 = require("../util");
|
|
12
16
|
const BrsTranspileState_1 = require("../parser/BrsTranspileState");
|
|
13
|
-
const Preprocessor_1 = require("../preprocessor/Preprocessor");
|
|
14
|
-
const Logger_1 = require("../Logger");
|
|
15
17
|
const serialize_error_1 = require("serialize-error");
|
|
16
18
|
const reflection_1 = require("../astUtils/reflection");
|
|
17
19
|
const visitors_1 = require("../astUtils/visitors");
|
|
18
20
|
const CommentFlagProcessor_1 = require("../CommentFlagProcessor");
|
|
21
|
+
const ReferencesProvider_1 = require("../bscPlugin/references/ReferencesProvider");
|
|
22
|
+
const DocumentSymbolProcessor_1 = require("../bscPlugin/symbols/DocumentSymbolProcessor");
|
|
23
|
+
const WorkspaceSymbolProcessor_1 = require("../bscPlugin/symbols/WorkspaceSymbolProcessor");
|
|
24
|
+
const AstValidationSegmenter_1 = require("../AstValidationSegmenter");
|
|
25
|
+
const Logger_1 = require("../Logger");
|
|
26
|
+
const SymbolTable_1 = require("../SymbolTable");
|
|
27
|
+
const CachedLookups_1 = require("../astUtils/CachedLookups");
|
|
28
|
+
const Editor_1 = require("../astUtils/Editor");
|
|
29
|
+
const Manifest_1 = require("../preprocessor/Manifest");
|
|
30
|
+
const types_1 = require("../types");
|
|
31
|
+
const DefinitionProvider_1 = require("../bscPlugin/definition/DefinitionProvider");
|
|
19
32
|
/**
|
|
20
33
|
* Holds all details about this file within the scope of the whole program
|
|
21
34
|
*/
|
|
22
35
|
class BrsFile {
|
|
23
|
-
constructor(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
*/
|
|
27
|
-
srcPath,
|
|
28
|
-
/**
|
|
29
|
-
* The full pkg path (i.e. `pkg:/path/to/file.brs`)
|
|
30
|
-
*/
|
|
31
|
-
pkgPath, program) {
|
|
32
|
-
var _a;
|
|
33
|
-
this.srcPath = srcPath;
|
|
34
|
-
this.pkgPath = pkgPath;
|
|
35
|
-
this.program = program;
|
|
36
|
+
constructor(options) {
|
|
37
|
+
var _a, _b, _c;
|
|
38
|
+
this.type = 'BrsFile';
|
|
36
39
|
/**
|
|
37
40
|
* The parseMode used for the parser for this file
|
|
38
41
|
*/
|
|
39
|
-
this.parseMode =
|
|
42
|
+
this.parseMode = Parser_1.ParseMode.BrightScript;
|
|
40
43
|
/**
|
|
41
44
|
* Indicates whether this file needs to be validated.
|
|
45
|
+
* Files are only ever validated a single time
|
|
42
46
|
*/
|
|
43
47
|
this.isValidated = false;
|
|
44
|
-
this.diagnostics = [];
|
|
45
48
|
this.commentFlags = [];
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
this.scopesByFunc = new Map();
|
|
50
|
+
this.validationSegmenter = new AstValidationSegmenter_1.AstValidationSegmenter();
|
|
51
|
+
this.linkSymbolTableDisposables = [];
|
|
52
|
+
if (options) {
|
|
53
|
+
this.srcPath = (0, util_1.standardizePath) `${options.srcPath}`;
|
|
54
|
+
this.destPath = (0, util_1.standardizePath) `${options.destPath}`;
|
|
55
|
+
this.program = options.program;
|
|
56
|
+
this._cachedLookups = new CachedLookups_1.CachedLookups(this);
|
|
57
|
+
this.extension = util_1.util.getExtension(this.srcPath);
|
|
58
|
+
if (options.pkgPath) {
|
|
59
|
+
this.pkgPath = options.pkgPath;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
//don't rename .d.bs files to .d.brs
|
|
63
|
+
if (this.extension === '.d.bs') {
|
|
64
|
+
this.pkgPath = this.destPath;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
this.pkgPath = this.destPath.replace(/\.bs$/i, '.brs');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//all BrighterScript files need to be transpiled
|
|
71
|
+
if (((_a = this.extension) === null || _a === void 0 ? void 0 : _a.endsWith('.bs')) || ((_c = (_b = this.program) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.allowBrighterScriptInBrightScript)) {
|
|
72
|
+
this.parseMode = Parser_1.ParseMode.BrighterScript;
|
|
73
|
+
}
|
|
74
|
+
this.isTypedef = this.extension === '.d.bs';
|
|
75
|
+
if (!this.isTypedef) {
|
|
76
|
+
this.typedefKey = util_1.util.getTypedefPath(this.srcPath);
|
|
77
|
+
}
|
|
78
|
+
//global file doesn't have a program, so only resolve typedef info if we have a program
|
|
79
|
+
if (this.program) {
|
|
80
|
+
this.resolveTypedef();
|
|
81
|
+
}
|
|
67
82
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Will this file result in only comment or whitespace output? If so, it can be excluded from the output if that bsconfig setting is enabled.
|
|
86
|
+
*/
|
|
87
|
+
get canBePruned() {
|
|
88
|
+
let canPrune = true;
|
|
89
|
+
this.ast.walk((0, visitors_1.createVisitor)({
|
|
90
|
+
FunctionStatement: () => {
|
|
91
|
+
canPrune = false;
|
|
92
|
+
},
|
|
93
|
+
ClassStatement: () => {
|
|
94
|
+
canPrune = false;
|
|
95
|
+
}
|
|
96
|
+
}), {
|
|
97
|
+
walkMode: visitors_1.WalkMode.visitStatements
|
|
98
|
+
});
|
|
99
|
+
return canPrune;
|
|
100
|
+
}
|
|
101
|
+
get functionScopes() {
|
|
102
|
+
if (!this._functionScopes) {
|
|
103
|
+
this.createFunctionScopes();
|
|
71
104
|
}
|
|
105
|
+
return this._functionScopes;
|
|
106
|
+
}
|
|
107
|
+
get cache() {
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
109
|
+
return this._cachedLookups['cache'];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* files referenced by import statements
|
|
113
|
+
*/
|
|
114
|
+
get ownScriptImports() {
|
|
115
|
+
var _a, _b;
|
|
116
|
+
const result = (_b = (_a = this.cache) === null || _a === void 0 ? void 0 : _a.getOrAdd('BrsFile_ownScriptImports', () => {
|
|
117
|
+
var _a, _b;
|
|
118
|
+
const result = [];
|
|
119
|
+
for (const statement of (_b = (_a = this._cachedLookups) === null || _a === void 0 ? void 0 : _a.importStatements) !== null && _b !== void 0 ? _b : []) {
|
|
120
|
+
//register import statements
|
|
121
|
+
if ((0, reflection_1.isImportStatement)(statement) && statement.tokens.path) {
|
|
122
|
+
result.push({
|
|
123
|
+
filePathRange: statement.tokens.path.range,
|
|
124
|
+
destPath: util_1.util.getPkgPathFromTarget(this.destPath, statement.filePath),
|
|
125
|
+
sourceFile: this,
|
|
126
|
+
text: statement.tokens.path.text
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
})) !== null && _b !== void 0 ? _b : [];
|
|
132
|
+
return result;
|
|
72
133
|
}
|
|
73
|
-
|
|
74
|
-
|
|
134
|
+
/**
|
|
135
|
+
* Does this file need to be transpiled?
|
|
136
|
+
* @deprecated use the `.editor` property to push changes to the file, which will force transpilation
|
|
137
|
+
*/
|
|
138
|
+
get needsTranspiled() {
|
|
139
|
+
var _a, _b, _c, _d;
|
|
140
|
+
if (this._needsTranspiled !== undefined) {
|
|
141
|
+
return this._needsTranspiled;
|
|
142
|
+
}
|
|
143
|
+
return !!(((_a = this.extension) === null || _a === void 0 ? void 0 : _a.endsWith('.bs')) || ((_c = (_b = this.program) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.allowBrighterScriptInBrightScript) || ((_d = this.editor) === null || _d === void 0 ? void 0 : _d.hasChanges));
|
|
75
144
|
}
|
|
76
|
-
|
|
77
|
-
this.
|
|
145
|
+
set needsTranspiled(value) {
|
|
146
|
+
this._needsTranspiled = value;
|
|
78
147
|
}
|
|
79
148
|
/**
|
|
80
149
|
* The AST for this file
|
|
81
150
|
*/
|
|
82
151
|
get ast() {
|
|
83
|
-
|
|
152
|
+
var _a;
|
|
153
|
+
return (_a = this.parser) === null || _a === void 0 ? void 0 : _a.ast;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get the token at the specified position
|
|
157
|
+
*/
|
|
158
|
+
getTokenAt(position) {
|
|
159
|
+
for (let token of this.parser.tokens) {
|
|
160
|
+
if (util_1.util.rangeContains(token.range, position)) {
|
|
161
|
+
return token;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get the token at the specified position, or the next token
|
|
167
|
+
*/
|
|
168
|
+
getCurrentOrNextTokenAt(position) {
|
|
169
|
+
for (let token of this.parser.tokens) {
|
|
170
|
+
if (util_1.util.comparePositionToRange(position, token.range) < 0) {
|
|
171
|
+
return token;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Walk the AST and find the expression that this token is most specifically contained within
|
|
177
|
+
*/
|
|
178
|
+
getClosestExpression(position) {
|
|
179
|
+
const handle = new vscode_languageserver_1.CancellationTokenSource();
|
|
180
|
+
let containingNode;
|
|
181
|
+
this.ast.walk((node) => {
|
|
182
|
+
const latestContainer = containingNode;
|
|
183
|
+
//bsc walks depth-first
|
|
184
|
+
if (util_1.util.rangeContains(node.range, position)) {
|
|
185
|
+
containingNode = node;
|
|
186
|
+
}
|
|
187
|
+
//we had a match before, and don't now. this means we've finished walking down the whole way, and found our match
|
|
188
|
+
if (latestContainer && !containingNode) {
|
|
189
|
+
containingNode = latestContainer;
|
|
190
|
+
handle.cancel();
|
|
191
|
+
}
|
|
192
|
+
}, {
|
|
193
|
+
walkMode: visitors_1.WalkMode.visitAllRecursive,
|
|
194
|
+
cancel: handle.token
|
|
195
|
+
});
|
|
196
|
+
return containingNode;
|
|
84
197
|
}
|
|
85
198
|
get parser() {
|
|
86
199
|
if (!this._parser) {
|
|
@@ -98,130 +211,75 @@ class BrsFile {
|
|
|
98
211
|
* Find and set the typedef variables (if a matching typedef file exists)
|
|
99
212
|
*/
|
|
100
213
|
resolveTypedef() {
|
|
101
|
-
this.typedefFile = this.program.getFile(this.
|
|
214
|
+
this.typedefFile = this.program.getFile(this.typedefKey);
|
|
102
215
|
this.hasTypedef = !!this.typedefFile;
|
|
103
216
|
}
|
|
217
|
+
onDependenciesChanged(event) {
|
|
218
|
+
var _a, _b;
|
|
219
|
+
this.resolveTypedef();
|
|
220
|
+
this.unlinkNamespaceSymbolTables();
|
|
221
|
+
(_a = this.cache) === null || _a === void 0 ? void 0 : _a.delete('namespaceSymbolTable');
|
|
222
|
+
(_b = this.cache) === null || _b === void 0 ? void 0 : _b.delete('requiredSymbols');
|
|
223
|
+
this.validationSegmenter.unValidateAllSegments();
|
|
224
|
+
}
|
|
104
225
|
/**
|
|
105
226
|
* Attach the file to the dependency graph so it can monitor changes.
|
|
106
227
|
* Also notify the dependency graph of our current dependencies so other dependents can be notified.
|
|
228
|
+
* @deprecated this does nothing. This functionality is now handled by the file api and will be deleted in v1
|
|
107
229
|
*/
|
|
108
|
-
attachDependencyGraph(dependencyGraph) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
this.resolveTypedef();
|
|
115
|
-
});
|
|
116
|
-
const dependencies = this.ownScriptImports.filter(x => !!x.pkgPath).map(x => x.pkgPath.toLowerCase());
|
|
230
|
+
attachDependencyGraph(dependencyGraph) { }
|
|
231
|
+
/**
|
|
232
|
+
* The list of files that this file depends on
|
|
233
|
+
*/
|
|
234
|
+
get dependencies() {
|
|
235
|
+
const result = this.ownScriptImports.filter(x => !!x.destPath).map(x => x.destPath.toLowerCase());
|
|
117
236
|
//if this is a .brs file, watch for typedef changes
|
|
118
237
|
if (this.extension === '.brs') {
|
|
119
|
-
|
|
238
|
+
result.push(util_1.util.getTypedefPath(this.destPath));
|
|
120
239
|
}
|
|
121
|
-
|
|
240
|
+
return result;
|
|
122
241
|
}
|
|
123
242
|
/**
|
|
124
243
|
* Calculate the AST for this file
|
|
125
|
-
* @param fileContents
|
|
244
|
+
* @param fileContents the raw source code to parse
|
|
126
245
|
*/
|
|
127
246
|
parse(fileContents) {
|
|
247
|
+
var _a;
|
|
248
|
+
const diagnostics = [];
|
|
128
249
|
try {
|
|
129
250
|
this.fileContents = fileContents;
|
|
130
|
-
this.diagnostics = [];
|
|
131
251
|
//if we have a typedef file, skip parsing this file
|
|
132
252
|
if (this.hasTypedef) {
|
|
253
|
+
//skip validation since the typedef is shadowing this file
|
|
254
|
+
this.isValidated = true;
|
|
133
255
|
return;
|
|
134
256
|
}
|
|
135
257
|
//tokenize the input file
|
|
136
|
-
let lexer = this.program.logger.time(
|
|
137
|
-
return
|
|
258
|
+
let lexer = this.program.logger.time('debug', ['lexer.lex', chalk_1.default.green(this.srcPath)], () => {
|
|
259
|
+
return Lexer_1.Lexer.scan(fileContents, {
|
|
138
260
|
includeWhitespace: false
|
|
139
261
|
});
|
|
140
262
|
});
|
|
141
263
|
this.getCommentFlags(lexer.tokens);
|
|
142
|
-
let preprocessor = new Preprocessor_1.Preprocessor();
|
|
143
|
-
//remove all code inside false-resolved conditional compilation statements.
|
|
144
|
-
//TODO preprocessor should go away in favor of the AST handling this internally (because it affects transpile)
|
|
145
|
-
//currently the preprocessor throws exceptions on syntax errors...so we need to catch it
|
|
146
|
-
try {
|
|
147
|
-
this.program.logger.time(Logger_1.LogLevel.debug, ['preprocessor.process', chalk_1.default.green(this.srcPath)], () => {
|
|
148
|
-
preprocessor.process(lexer.tokens, this.program.getManifest());
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
//if the thrown error is DIFFERENT than any errors from the preprocessor, add that error to the list as well
|
|
153
|
-
if (this.diagnostics.find((x) => x === error) === undefined) {
|
|
154
|
-
this.diagnostics.push(error);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
//if the preprocessor generated tokens, use them.
|
|
158
|
-
let tokens = preprocessor.processedTokens.length > 0 ? preprocessor.processedTokens : lexer.tokens;
|
|
159
264
|
this.program.logger.time(Logger_1.LogLevel.debug, ['parser.parse', chalk_1.default.green(this.srcPath)], () => {
|
|
160
|
-
this._parser =
|
|
265
|
+
this._parser = Parser_1.Parser.parse(lexer.tokens, {
|
|
161
266
|
mode: this.parseMode,
|
|
162
|
-
logger: this.program.logger
|
|
267
|
+
logger: this.program.logger,
|
|
268
|
+
bsConsts: (0, Manifest_1.getBsConst)(this.program.getManifest())
|
|
163
269
|
});
|
|
164
270
|
});
|
|
165
271
|
//absorb all lexing/preprocessing/parsing diagnostics
|
|
166
|
-
|
|
167
|
-
//extract all callables from this file
|
|
168
|
-
this.findCallables();
|
|
169
|
-
//find all places where a sub/function is being called
|
|
170
|
-
this.findFunctionCalls();
|
|
171
|
-
this.findAndValidateImportAndImportStatements();
|
|
272
|
+
diagnostics.push(...lexer.diagnostics, ...this._parser.diagnostics);
|
|
172
273
|
//attach this file to every diagnostic
|
|
173
|
-
for (let diagnostic of
|
|
274
|
+
for (let diagnostic of diagnostics) {
|
|
174
275
|
diagnostic.file = this;
|
|
175
276
|
}
|
|
176
277
|
}
|
|
177
278
|
catch (e) {
|
|
178
|
-
this._parser = new
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
validate() { }
|
|
183
|
-
findAndValidateImportAndImportStatements() {
|
|
184
|
-
var _a;
|
|
185
|
-
let topOfFileIncludeStatements = [];
|
|
186
|
-
for (let stmt of this.ast.statements) {
|
|
187
|
-
//skip comments
|
|
188
|
-
if (reflection_1.isCommentStatement(stmt)) {
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
//if we found a non-library statement, this statement is not at the top of the file
|
|
192
|
-
if (reflection_1.isLibraryStatement(stmt) || reflection_1.isImportStatement(stmt)) {
|
|
193
|
-
topOfFileIncludeStatements.push(stmt);
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
//break out of the loop, we found all of our library statements
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
let statements = [
|
|
201
|
-
...this._parser.references.libraryStatements,
|
|
202
|
-
...this._parser.references.importStatements
|
|
203
|
-
];
|
|
204
|
-
for (let result of statements) {
|
|
205
|
-
//register import statements
|
|
206
|
-
if (reflection_1.isImportStatement(result) && result.filePathToken) {
|
|
207
|
-
this.ownScriptImports.push({
|
|
208
|
-
filePathRange: result.filePathToken.range,
|
|
209
|
-
pkgPath: util_1.util.getPkgPathFromTarget(this.pkgPath, result.filePath),
|
|
210
|
-
sourceFile: this,
|
|
211
|
-
text: (_a = result.filePathToken) === null || _a === void 0 ? void 0 : _a.text
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
//if this statement is not one of the top-of-file statements,
|
|
215
|
-
//then add a diagnostic explaining that it is invalid
|
|
216
|
-
if (!topOfFileIncludeStatements.includes(result)) {
|
|
217
|
-
if (reflection_1.isLibraryStatement(result)) {
|
|
218
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.libraryStatementMustBeDeclaredAtTopOfFile()), { range: result.range, file: this }));
|
|
219
|
-
}
|
|
220
|
-
else if (reflection_1.isImportStatement(result)) {
|
|
221
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.importStatementMustBeDeclaredAtTopOfFile()), { range: result.range, file: this }));
|
|
222
|
-
}
|
|
223
|
-
}
|
|
279
|
+
this._parser = new Parser_1.Parser();
|
|
280
|
+
diagnostics.push(Object.assign({ file: this, range: util_1.util.createRange(0, 0, 0, Number.MAX_VALUE) }, DiagnosticMessages_1.DiagnosticMessages.genericParserMessage('Critical error parsing file: ' + JSON.stringify((0, serialize_error_1.serializeError)(e)))));
|
|
224
281
|
}
|
|
282
|
+
(_a = this.program) === null || _a === void 0 ? void 0 : _a.diagnostics.register(diagnostics);
|
|
225
283
|
}
|
|
226
284
|
/**
|
|
227
285
|
* Find a class. This scans all scopes for this file, and returns the first matching class that is found.
|
|
@@ -244,12 +302,12 @@ class BrsFile {
|
|
|
244
302
|
}
|
|
245
303
|
findPropertyNameCompletions() {
|
|
246
304
|
//Build completion items from all the "properties" found in the file
|
|
247
|
-
const { propertyHints } = this.
|
|
305
|
+
const { propertyHints } = this._cachedLookups;
|
|
248
306
|
const results = [];
|
|
249
307
|
for (const key of Object.keys(propertyHints)) {
|
|
250
308
|
results.push({
|
|
251
309
|
label: propertyHints[key],
|
|
252
|
-
kind:
|
|
310
|
+
kind: vscode_languageserver_2.CompletionItemKind.Text
|
|
253
311
|
});
|
|
254
312
|
}
|
|
255
313
|
return results;
|
|
@@ -262,415 +320,183 @@ class BrsFile {
|
|
|
262
320
|
}
|
|
263
321
|
/**
|
|
264
322
|
* Find all comment flags in the source code. These enable or disable diagnostic messages.
|
|
265
|
-
* @param
|
|
323
|
+
* @param tokens - an array of tokens of which to find `TokenKind.Comment` from
|
|
266
324
|
*/
|
|
267
325
|
getCommentFlags(tokens) {
|
|
326
|
+
var _a, _b;
|
|
268
327
|
const processor = new CommentFlagProcessor_1.CommentFlagProcessor(this, ['rem', `'`], DiagnosticMessages_1.diagnosticCodes, [DiagnosticMessages_1.DiagnosticCodeMap.unknownDiagnosticCode]);
|
|
269
328
|
this.commentFlags = [];
|
|
270
|
-
for (let
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
this.commentFlags.push(...processor.commentFlags);
|
|
276
|
-
this.diagnostics.push(...processor.diagnostics);
|
|
277
|
-
}
|
|
278
|
-
findCallables() {
|
|
279
|
-
var _a;
|
|
280
|
-
for (let statement of (_a = this.parser.references.functionStatements) !== null && _a !== void 0 ? _a : []) {
|
|
281
|
-
let functionType = statement.func.getFunctionType();
|
|
282
|
-
functionType.setName(statement.name.text);
|
|
283
|
-
this.callables.push({
|
|
284
|
-
isSub: statement.func.functionType.text.toLowerCase() === 'sub',
|
|
285
|
-
name: statement.name.text,
|
|
286
|
-
nameRange: statement.name.range,
|
|
287
|
-
file: this,
|
|
288
|
-
params: functionType.params,
|
|
289
|
-
range: statement.func.range,
|
|
290
|
-
type: functionType,
|
|
291
|
-
getName: statement.getName.bind(statement),
|
|
292
|
-
hasNamespace: !!statement.namespaceName,
|
|
293
|
-
functionStatement: statement
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
findFunctionCalls() {
|
|
298
|
-
this.functionCalls = [];
|
|
299
|
-
//for every function in the file
|
|
300
|
-
for (let func of this._parser.references.functionExpressions) {
|
|
301
|
-
//for all function calls in this function
|
|
302
|
-
for (let expression of func.callExpressions) {
|
|
303
|
-
if (
|
|
304
|
-
//filter out dotted function invocations (i.e. object.doSomething()) (not currently supported. TODO support it)
|
|
305
|
-
expression.callee.obj ||
|
|
306
|
-
//filter out method calls on method calls for now (i.e. getSomething().getSomethingElse())
|
|
307
|
-
expression.callee.callee ||
|
|
308
|
-
//filter out callees without a name (immediately-invoked function expressions)
|
|
309
|
-
!expression.callee.name) {
|
|
310
|
-
continue;
|
|
311
|
-
}
|
|
312
|
-
let functionName = expression.callee.name.text;
|
|
313
|
-
//callee is the name of the function being called
|
|
314
|
-
let callee = expression.callee;
|
|
315
|
-
let columnIndexBegin = callee.range.start.character;
|
|
316
|
-
let columnIndexEnd = callee.range.end.character;
|
|
317
|
-
let args = [];
|
|
318
|
-
//TODO convert if stmts to use instanceof instead
|
|
319
|
-
for (let arg of expression.args) {
|
|
320
|
-
let impliedType = parser_1.getBscTypeFromExpression(arg, func);
|
|
321
|
-
let argText = '';
|
|
322
|
-
// Get the text to display for the arg
|
|
323
|
-
if (arg.token) {
|
|
324
|
-
argText = arg.token.text;
|
|
325
|
-
//is a function call being passed into argument
|
|
326
|
-
}
|
|
327
|
-
else if (arg.name) {
|
|
328
|
-
if (lexer_1.isToken(arg.name)) {
|
|
329
|
-
argText = arg.name.text;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
else if (arg.value) {
|
|
333
|
-
/* istanbul ignore next: TODO figure out why value is undefined sometimes */
|
|
334
|
-
if (arg.value.value) {
|
|
335
|
-
argText = arg.value.value.toString();
|
|
336
|
-
}
|
|
337
|
-
//wrap the value in quotes because that's how it appears in the code
|
|
338
|
-
if (reflection_1.isStringType(impliedType)) {
|
|
339
|
-
argText = '"' + argText + '"';
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
args.push({
|
|
343
|
-
range: arg.range,
|
|
344
|
-
type: impliedType,
|
|
345
|
-
text: argText
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
let functionCall = {
|
|
349
|
-
range: util_1.util.createRangeFromPositions(expression.range.start, expression.closingParen.range.end),
|
|
350
|
-
functionExpression: this.getFunctionExpressionAtPosition(callee.range.start),
|
|
351
|
-
file: this,
|
|
352
|
-
name: functionName,
|
|
353
|
-
nameRange: util_1.util.createRange(callee.range.start.line, columnIndexBegin, callee.range.start.line, columnIndexEnd),
|
|
354
|
-
//TODO keep track of parameters
|
|
355
|
-
args: args
|
|
356
|
-
};
|
|
357
|
-
this.functionCalls.push(functionCall);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Find the function expression at the given position.
|
|
363
|
-
*/
|
|
364
|
-
getFunctionExpressionAtPosition(position, functionExpressions) {
|
|
365
|
-
if (!functionExpressions) {
|
|
366
|
-
functionExpressions = this.parser.references.functionExpressions;
|
|
367
|
-
}
|
|
368
|
-
for (let functionExpression of functionExpressions) {
|
|
369
|
-
if (util_1.util.rangeContains(functionExpression.range, position)) {
|
|
370
|
-
//see if any of that scope's children match the position also, and give them priority
|
|
371
|
-
let childFunc = this.getFunctionExpressionAtPosition(position, functionExpression.childFunctionExpressions);
|
|
372
|
-
if (childFunc) {
|
|
373
|
-
return childFunc;
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
return functionExpression;
|
|
329
|
+
for (let lexerToken of tokens) {
|
|
330
|
+
for (let triviaToken of (_a = lexerToken.leadingTrivia) !== null && _a !== void 0 ? _a : []) {
|
|
331
|
+
if (triviaToken.kind === TokenKind_1.TokenKind.Comment) {
|
|
332
|
+
processor.tryAdd(triviaToken.text, triviaToken.range);
|
|
377
333
|
}
|
|
378
334
|
}
|
|
379
335
|
}
|
|
336
|
+
this.commentFlags.push(...processor.commentFlags);
|
|
337
|
+
(_b = this.program) === null || _b === void 0 ? void 0 : _b.diagnostics.register(processor.diagnostics);
|
|
380
338
|
}
|
|
381
339
|
/**
|
|
382
|
-
*
|
|
340
|
+
* Create a scope for every function in this file
|
|
383
341
|
*/
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
//
|
|
387
|
-
let
|
|
388
|
-
//
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
else if (tokenKind === lexer_1.TokenKind.StringLiteral || tokenKind === lexer_1.TokenKind.TemplateStringQuasi) {
|
|
400
|
-
const match = /^("?)(pkg|libpkg):/.exec(currentToken.text);
|
|
401
|
-
if (match) {
|
|
402
|
-
const [, openingQuote, fileProtocol] = match;
|
|
403
|
-
//include every pkgPath from this scope
|
|
404
|
-
for (const file of scope.getAllFiles()) {
|
|
405
|
-
const pkgPath = `${fileProtocol}:/${file.pkgPath.replace('pkg:/', '')}`;
|
|
406
|
-
result.push({
|
|
407
|
-
label: pkgPath,
|
|
408
|
-
textEdit: vscode_languageserver_1.TextEdit.replace(util_1.util.createRange(currentToken.range.start.line,
|
|
409
|
-
//+1 to step past the opening quote
|
|
410
|
-
currentToken.range.start.character + (openingQuote ? 1 : 0), currentToken.range.end.line,
|
|
411
|
-
//-1 to exclude the closing quotemark (or the end character if there is no closing quotemark)
|
|
412
|
-
currentToken.range.end.character + (currentToken.text.endsWith('"') ? -1 : 0)), pkgPath),
|
|
413
|
-
kind: vscode_languageserver_1.CompletionItemKind.File
|
|
414
|
-
});
|
|
342
|
+
createFunctionScopes() {
|
|
343
|
+
var _a, _b, _c;
|
|
344
|
+
//find every function
|
|
345
|
+
let functions = this._cachedLookups.functionExpressions;
|
|
346
|
+
//create a functionScope for every function
|
|
347
|
+
this._functionScopes = [];
|
|
348
|
+
for (let func of functions) {
|
|
349
|
+
let scope = new FunctionScope_1.FunctionScope(func);
|
|
350
|
+
//find parent function, and add this scope to it if found
|
|
351
|
+
{
|
|
352
|
+
let parentScope = this.scopesByFunc.get(func.findAncestor(reflection_1.isFunctionExpression));
|
|
353
|
+
//add this child scope to its parent
|
|
354
|
+
if (parentScope) {
|
|
355
|
+
parentScope.childrenScopes.push(scope);
|
|
415
356
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
else {
|
|
419
|
-
//do nothing. we don't want to show completions inside of strings...
|
|
420
|
-
return [];
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
let namespaceCompletions = this.getNamespaceCompletions(currentToken, this.parseMode, scope);
|
|
424
|
-
if (namespaceCompletions.length > 0) {
|
|
425
|
-
return namespaceCompletions;
|
|
426
|
-
}
|
|
427
|
-
//determine if cursor is inside a function
|
|
428
|
-
let functionExpression = this.getFunctionExpressionAtPosition(position);
|
|
429
|
-
if (!functionExpression) {
|
|
430
|
-
//we aren't in any function scope, so return the keyword completions and namespaces
|
|
431
|
-
if (this.parser.getTokenBefore(currentToken, lexer_1.TokenKind.New)) {
|
|
432
|
-
// there's a new keyword, so only class types are viable here
|
|
433
|
-
return [...this.getGlobalClassStatementCompletions(currentToken, this.parseMode)];
|
|
434
|
-
}
|
|
435
|
-
else {
|
|
436
|
-
return [...exports.KeywordCompletions, ...this.getGlobalClassStatementCompletions(currentToken, this.parseMode), ...namespaceCompletions];
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
const classNameCompletions = this.getGlobalClassStatementCompletions(currentToken, this.parseMode);
|
|
440
|
-
const newToken = this.parser.getTokenBefore(currentToken, lexer_1.TokenKind.New);
|
|
441
|
-
if (newToken) {
|
|
442
|
-
//we are after a new keyword; so we can only be namespaces or classes at this point
|
|
443
|
-
result.push(...classNameCompletions);
|
|
444
|
-
result.push(...namespaceCompletions);
|
|
445
|
-
return result;
|
|
446
|
-
}
|
|
447
|
-
if (this.parser.tokenFollows(currentToken, lexer_1.TokenKind.Goto)) {
|
|
448
|
-
return this.getLabelCompletion(functionExpression);
|
|
449
|
-
}
|
|
450
|
-
if (this.parser.isPositionNextToTokenKind(position, lexer_1.TokenKind.Dot)) {
|
|
451
|
-
if (namespaceCompletions.length > 0) {
|
|
452
|
-
//if we matched a namespace, after a dot, it can't be anything else but something from our namespace completions
|
|
453
|
-
return namespaceCompletions;
|
|
454
|
-
}
|
|
455
|
-
const selfClassMemberCompletions = this.getClassMemberCompletions(position, currentToken, functionExpression, scope);
|
|
456
|
-
if (selfClassMemberCompletions.size > 0) {
|
|
457
|
-
return [...selfClassMemberCompletions.values()].filter((i) => i.label !== 'new');
|
|
357
|
+
//store the parent scope for this scope
|
|
358
|
+
scope.parentScope = parentScope;
|
|
458
359
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}
|
|
469
|
-
else {
|
|
470
|
-
//include namespaces
|
|
471
|
-
result.push(...namespaceCompletions);
|
|
472
|
-
//include class names
|
|
473
|
-
result.push(...classNameCompletions);
|
|
474
|
-
//include the global callables
|
|
475
|
-
result.push(...scope.getCallablesAsCompletions(this.parseMode));
|
|
476
|
-
//add `m` because that's always valid within a function
|
|
477
|
-
result.push({
|
|
478
|
-
label: 'm',
|
|
479
|
-
kind: vscode_languageserver_1.CompletionItemKind.Variable
|
|
480
|
-
});
|
|
481
|
-
names.m = true;
|
|
482
|
-
result.push(...exports.KeywordCompletions);
|
|
483
|
-
//include local variables
|
|
484
|
-
for (let symbol of functionExpression.symbolTable.ownSymbols) {
|
|
485
|
-
const symbolNameLower = symbol.name.toLowerCase();
|
|
486
|
-
//skip duplicate variable names
|
|
487
|
-
if (names[symbolNameLower]) {
|
|
488
|
-
continue;
|
|
489
|
-
}
|
|
490
|
-
names[symbolNameLower] = true;
|
|
491
|
-
result.push({
|
|
492
|
-
//TODO does this work?
|
|
493
|
-
label: symbol.name,
|
|
494
|
-
//TODO find type for local vars
|
|
495
|
-
kind: vscode_languageserver_1.CompletionItemKind.Variable
|
|
496
|
-
// kind: isFunctionType(variable.type) ? CompletionItemKind.Function : CompletionItemKind.Variable
|
|
360
|
+
//add every parameter
|
|
361
|
+
for (let param of func.parameters) {
|
|
362
|
+
scope.variableDeclarations.push({
|
|
363
|
+
nameRange: param.tokens.name.range,
|
|
364
|
+
lineIndex: (_a = param.tokens.name.range) === null || _a === void 0 ? void 0 : _a.start.line,
|
|
365
|
+
name: param.tokens.name.text,
|
|
366
|
+
getType: () => {
|
|
367
|
+
return param.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
368
|
+
}
|
|
497
369
|
});
|
|
498
370
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
371
|
+
//add all of ForEachStatement loop varibales
|
|
372
|
+
(_b = func.body) === null || _b === void 0 ? void 0 : _b.walk((0, visitors_1.createVisitor)({
|
|
373
|
+
ForEachStatement: (stmt) => {
|
|
374
|
+
var _a;
|
|
375
|
+
scope.variableDeclarations.push({
|
|
376
|
+
nameRange: stmt.tokens.item.range,
|
|
377
|
+
lineIndex: (_a = stmt.tokens.item.range) === null || _a === void 0 ? void 0 : _a.start.line,
|
|
378
|
+
name: stmt.tokens.item.text,
|
|
379
|
+
getType: () => DynamicType_1.DynamicType.instance //TODO: Infer types from array
|
|
380
|
+
});
|
|
381
|
+
},
|
|
382
|
+
LabelStatement: (stmt) => {
|
|
383
|
+
var _a;
|
|
384
|
+
const { name: identifier } = stmt.tokens;
|
|
385
|
+
scope.labelStatements.push({
|
|
386
|
+
nameRange: identifier.range,
|
|
387
|
+
lineIndex: (_a = identifier.range) === null || _a === void 0 ? void 0 : _a.start.line,
|
|
388
|
+
name: identifier.text
|
|
512
389
|
});
|
|
513
390
|
}
|
|
391
|
+
}), {
|
|
392
|
+
walkMode: visitors_1.WalkMode.visitStatements
|
|
393
|
+
});
|
|
394
|
+
this.scopesByFunc.set(func, scope);
|
|
395
|
+
//find every statement in the scope
|
|
396
|
+
this._functionScopes.push(scope);
|
|
397
|
+
}
|
|
398
|
+
//find every variable assignment in the whole file
|
|
399
|
+
let assignmentStatements = this._cachedLookups.assignmentStatements;
|
|
400
|
+
for (let statement of assignmentStatements) {
|
|
401
|
+
//find this statement's function scope
|
|
402
|
+
let scope = this.scopesByFunc.get(statement.findAncestor(reflection_1.isFunctionExpression));
|
|
403
|
+
//skip variable declarations that are outside of any scope
|
|
404
|
+
if (scope) {
|
|
405
|
+
const variableName = statement.tokens.name;
|
|
406
|
+
scope.variableDeclarations.push({
|
|
407
|
+
nameRange: variableName.range,
|
|
408
|
+
lineIndex: (_c = variableName.range) === null || _c === void 0 ? void 0 : _c.start.line,
|
|
409
|
+
name: variableName.text,
|
|
410
|
+
getType: () => {
|
|
411
|
+
return statement.getType({ flags: 1 /* SymbolTypeFlag.runtime */ });
|
|
412
|
+
}
|
|
413
|
+
});
|
|
514
414
|
}
|
|
515
415
|
}
|
|
516
|
-
return result;
|
|
517
|
-
}
|
|
518
|
-
getLabelCompletion(func) {
|
|
519
|
-
return func.labelStatements.map(label => ({
|
|
520
|
-
label: label.tokens.identifier.text,
|
|
521
|
-
kind: vscode_languageserver_1.CompletionItemKind.Reference
|
|
522
|
-
}));
|
|
523
416
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
417
|
+
get callables() {
|
|
418
|
+
if (this.staticCallables) {
|
|
419
|
+
// globalFile can statically set the callables
|
|
420
|
+
return this.staticCallables;
|
|
421
|
+
}
|
|
422
|
+
return this.cache.getOrAdd(`BrsFile_callables`, () => {
|
|
423
|
+
var _a, _b, _c, _d, _e;
|
|
424
|
+
const callables = [];
|
|
425
|
+
for (let statement of (_a = this._cachedLookups.functionStatements) !== null && _a !== void 0 ? _a : []) {
|
|
426
|
+
//extract the parameters
|
|
427
|
+
let params = [];
|
|
428
|
+
for (let param of statement.func.parameters) {
|
|
429
|
+
const paramType = param.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
430
|
+
let callableParam = {
|
|
431
|
+
name: (_b = param.tokens.name) === null || _b === void 0 ? void 0 : _b.text,
|
|
432
|
+
type: paramType,
|
|
433
|
+
isOptional: !!param.defaultValue,
|
|
434
|
+
isRestArgument: false
|
|
435
|
+
};
|
|
436
|
+
params.push(callableParam);
|
|
538
437
|
}
|
|
438
|
+
const funcType = statement.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
439
|
+
callables.push({
|
|
440
|
+
isSub: ((_c = statement.func.tokens.functionType) === null || _c === void 0 ? void 0 : _c.text.toLowerCase()) === 'sub',
|
|
441
|
+
name: (_d = statement.tokens.name) === null || _d === void 0 ? void 0 : _d.text,
|
|
442
|
+
nameRange: (_e = statement.tokens.name) === null || _e === void 0 ? void 0 : _e.range,
|
|
443
|
+
file: this,
|
|
444
|
+
params: params,
|
|
445
|
+
range: statement.func.range,
|
|
446
|
+
type: funcType,
|
|
447
|
+
getName: statement.getName.bind(statement),
|
|
448
|
+
hasNamespace: !!statement.findAncestor(reflection_1.isNamespaceStatement),
|
|
449
|
+
functionStatement: statement
|
|
450
|
+
});
|
|
539
451
|
}
|
|
540
|
-
|
|
541
|
-
|
|
452
|
+
return callables;
|
|
453
|
+
});
|
|
542
454
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
return
|
|
550
|
-
}
|
|
551
|
-
return undefined;
|
|
455
|
+
/**
|
|
456
|
+
* Find the function scope at the given position.
|
|
457
|
+
* @param position the position used to find the deepest scope that contains it
|
|
458
|
+
*/
|
|
459
|
+
getFunctionScopeAtPosition(position) {
|
|
460
|
+
return this.cache.getOrAdd(`functionScope-${position.line}:${position.character}`, () => {
|
|
461
|
+
return this._getFunctionScopeAtPosition(position, this.functionScopes);
|
|
462
|
+
});
|
|
552
463
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
return [];
|
|
464
|
+
_getFunctionScopeAtPosition(position, functionScopes) {
|
|
465
|
+
if (!functionScopes) {
|
|
466
|
+
functionScopes = this.functionScopes;
|
|
557
467
|
}
|
|
558
|
-
let
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
for (const key of [...classMap.keys()]) {
|
|
568
|
-
let cs = classMap.get(key).item;
|
|
569
|
-
if (!results.has(cs.name.text)) {
|
|
570
|
-
results.set(cs.name.text, {
|
|
571
|
-
label: cs.name.text,
|
|
572
|
-
kind: vscode_languageserver_1.CompletionItemKind.Class
|
|
573
|
-
});
|
|
468
|
+
for (let scope of functionScopes) {
|
|
469
|
+
if (util_1.util.rangeContains(scope.range, position)) {
|
|
470
|
+
//see if any of that scope's children match the position also, and give them priority
|
|
471
|
+
let childScope = this._getFunctionScopeAtPosition(position, scope.childrenScopes);
|
|
472
|
+
if (childScope) {
|
|
473
|
+
return childScope;
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
return scope;
|
|
574
477
|
}
|
|
575
478
|
}
|
|
576
479
|
}
|
|
577
|
-
return [...results.values()];
|
|
578
480
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
//remove any trailing identifer and then any trailing dot, to give us the
|
|
589
|
-
//name of its immediate parent namespace
|
|
590
|
-
let closestParentNamespaceName = completionName.replace(/\.([a-z0-9_]*)?$/gi, '');
|
|
591
|
-
let newToken = this.parser.getTokenBefore(currentToken, lexer_1.TokenKind.New);
|
|
592
|
-
let namespaceLookup = scope.namespaceLookup;
|
|
593
|
-
let result = new Map();
|
|
594
|
-
for (let key in namespaceLookup) {
|
|
595
|
-
let namespace = namespaceLookup[key.toLowerCase()];
|
|
596
|
-
//completionName = "NameA."
|
|
597
|
-
//completionName = "NameA.Na
|
|
598
|
-
//NameA
|
|
599
|
-
//NameA.NameB
|
|
600
|
-
//NameA.NameB.NameC
|
|
601
|
-
if (namespace.fullName.toLowerCase() === closestParentNamespaceName.toLowerCase()) {
|
|
602
|
-
//add all of this namespace's immediate child namespaces, bearing in mind if we are after a new keyword
|
|
603
|
-
for (let childKey in namespace.namespaces) {
|
|
604
|
-
const ns = namespace.namespaces[childKey];
|
|
605
|
-
if (!newToken || ns.statements.find((s) => reflection_1.isClassStatement(s))) {
|
|
606
|
-
if (!result.has(ns.lastPartName)) {
|
|
607
|
-
result.set(ns.lastPartName, {
|
|
608
|
-
label: ns.lastPartName,
|
|
609
|
-
kind: vscode_languageserver_1.CompletionItemKind.Module
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
//add function and class statement completions
|
|
615
|
-
for (let stmt of namespace.statements) {
|
|
616
|
-
if (reflection_1.isClassStatement(stmt)) {
|
|
617
|
-
if (!result.has(stmt.name.text)) {
|
|
618
|
-
result.set(stmt.name.text, {
|
|
619
|
-
label: stmt.name.text,
|
|
620
|
-
kind: vscode_languageserver_1.CompletionItemKind.Class
|
|
621
|
-
});
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
else if (reflection_1.isFunctionStatement(stmt) && !newToken) {
|
|
625
|
-
if (!result.has(stmt.name.text)) {
|
|
626
|
-
result.set(stmt.name.text, {
|
|
627
|
-
label: stmt.name.text,
|
|
628
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
629
|
-
});
|
|
630
|
-
}
|
|
481
|
+
/**
|
|
482
|
+
* Find the NamespaceStatement enclosing the given position
|
|
483
|
+
*/
|
|
484
|
+
getNamespaceStatementForPosition(position) {
|
|
485
|
+
if (position) {
|
|
486
|
+
return this.cache.getOrAdd(`namespaceStatementForPosition-${position.line}:${position.character}`, () => {
|
|
487
|
+
for (const statement of this._cachedLookups.namespaceStatements) {
|
|
488
|
+
if (util_1.util.rangeContains(statement.range, position)) {
|
|
489
|
+
return statement;
|
|
631
490
|
}
|
|
632
491
|
}
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
return [...result.values()];
|
|
636
|
-
}
|
|
637
|
-
getNamespaceDefinitions(token, file) {
|
|
638
|
-
//BrightScript does not support namespaces, so return an empty list in that case
|
|
639
|
-
if (!token) {
|
|
640
|
-
return undefined;
|
|
492
|
+
});
|
|
641
493
|
}
|
|
642
|
-
let location;
|
|
643
|
-
const nameParts = this.getPartialVariableName(token, [lexer_1.TokenKind.New]).split('.');
|
|
644
|
-
const endName = nameParts[nameParts.length - 1].toLowerCase();
|
|
645
|
-
const namespaceName = nameParts.slice(0, -1).join('.').toLowerCase();
|
|
646
|
-
const statementHandler = (statement) => {
|
|
647
|
-
if (!location && statement.getName(parser_1.ParseMode.BrighterScript).toLowerCase() === namespaceName) {
|
|
648
|
-
const namespaceItemStatementHandler = (statement) => {
|
|
649
|
-
if (!location && statement.name.text.toLowerCase() === endName) {
|
|
650
|
-
const uri = util_1.util.pathToUri(file.srcPath);
|
|
651
|
-
location = vscode_languageserver_1.Location.create(uri, statement.range);
|
|
652
|
-
}
|
|
653
|
-
};
|
|
654
|
-
file.parser.ast.walk(visitors_1.createVisitor({
|
|
655
|
-
ClassStatement: namespaceItemStatementHandler,
|
|
656
|
-
FunctionStatement: namespaceItemStatementHandler
|
|
657
|
-
}), {
|
|
658
|
-
walkMode: visitors_1.WalkMode.visitStatements
|
|
659
|
-
});
|
|
660
|
-
}
|
|
661
|
-
};
|
|
662
|
-
file.parser.ast.walk(visitors_1.createVisitor({
|
|
663
|
-
NamespaceStatement: statementHandler
|
|
664
|
-
}), {
|
|
665
|
-
walkMode: visitors_1.WalkMode.visitStatements
|
|
666
|
-
});
|
|
667
|
-
return location;
|
|
668
494
|
}
|
|
669
495
|
/**
|
|
670
496
|
* Given a current token, walk
|
|
671
497
|
*/
|
|
672
498
|
getPartialVariableName(currentToken, excludeTokens = null) {
|
|
673
|
-
let identifierAndDotKinds = [
|
|
499
|
+
let identifierAndDotKinds = [TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedLocalIdentifiers, TokenKind_1.TokenKind.Dot];
|
|
674
500
|
//consume tokens backwards until we find something other than a dot or an identifier
|
|
675
501
|
let tokens = [];
|
|
676
502
|
const parser = this.parser;
|
|
@@ -691,21 +517,94 @@ class BrsFile {
|
|
|
691
517
|
return undefined;
|
|
692
518
|
}
|
|
693
519
|
}
|
|
520
|
+
isPositionNextToTokenKind(position, tokenKind) {
|
|
521
|
+
const closestToken = this.getClosestToken(position);
|
|
522
|
+
return this.isTokenNextToTokenKind(closestToken, tokenKind);
|
|
523
|
+
}
|
|
524
|
+
isTokenNextToTokenKind(closestToken, tokenKind) {
|
|
525
|
+
const previousToken = this.getPreviousToken(closestToken);
|
|
526
|
+
const previousTokenKind = previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind;
|
|
527
|
+
//next to matched token
|
|
528
|
+
if (!closestToken || closestToken.kind === TokenKind_1.TokenKind.Eof) {
|
|
529
|
+
return false;
|
|
530
|
+
}
|
|
531
|
+
else if (closestToken.kind === tokenKind) {
|
|
532
|
+
return true;
|
|
533
|
+
}
|
|
534
|
+
else if (closestToken.kind === TokenKind_1.TokenKind.Newline || previousTokenKind === TokenKind_1.TokenKind.Newline) {
|
|
535
|
+
return false;
|
|
536
|
+
//next to an identifier, which is next to token kind
|
|
537
|
+
}
|
|
538
|
+
else if (closestToken.kind === TokenKind_1.TokenKind.Identifier && previousTokenKind === tokenKind) {
|
|
539
|
+
return true;
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
getTokenBefore(currentToken, tokenKind) {
|
|
546
|
+
const index = this.parser.tokens.indexOf(currentToken);
|
|
547
|
+
if (!tokenKind) {
|
|
548
|
+
return this.parser.tokens[index - 1];
|
|
549
|
+
}
|
|
550
|
+
for (let i = index - 1; i >= 0; i--) {
|
|
551
|
+
currentToken = this.parser.tokens[i];
|
|
552
|
+
if (currentToken.kind === TokenKind_1.TokenKind.Newline) {
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
else if (currentToken.kind === tokenKind) {
|
|
556
|
+
return currentToken;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return undefined;
|
|
560
|
+
}
|
|
561
|
+
tokenFollows(currentToken, tokenKind) {
|
|
562
|
+
const index = this.parser.tokens.indexOf(currentToken);
|
|
563
|
+
if (index > 0) {
|
|
564
|
+
return this.parser.tokens[index - 1].kind === tokenKind;
|
|
565
|
+
}
|
|
566
|
+
return false;
|
|
567
|
+
}
|
|
568
|
+
getTokensUntil(currentToken, tokenKind, direction = 1) {
|
|
569
|
+
let tokens = [];
|
|
570
|
+
for (let i = this.parser.tokens.indexOf(currentToken); direction === -1 ? i >= 0 : i < this.parser.tokens.length; i += direction) {
|
|
571
|
+
currentToken = this.parser.tokens[i];
|
|
572
|
+
if (currentToken.kind === TokenKind_1.TokenKind.Newline || currentToken.kind === tokenKind) {
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
tokens.push(currentToken);
|
|
576
|
+
}
|
|
577
|
+
return tokens;
|
|
578
|
+
}
|
|
579
|
+
getNextTokenByPredicate(currentToken, test, direction = 1) {
|
|
580
|
+
for (let i = this.parser.tokens.indexOf(currentToken); direction === -1 ? i >= 0 : i < this.parser.tokens.length; i += direction) {
|
|
581
|
+
currentToken = this.parser.tokens[i];
|
|
582
|
+
if (test(currentToken)) {
|
|
583
|
+
return currentToken;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return undefined;
|
|
587
|
+
}
|
|
588
|
+
getPreviousToken(token) {
|
|
589
|
+
const parser = this.parser;
|
|
590
|
+
let idx = parser.tokens.indexOf(token);
|
|
591
|
+
return parser.tokens[idx - 1];
|
|
592
|
+
}
|
|
694
593
|
/**
|
|
695
594
|
* Find the first scope that has a namespace with this name.
|
|
696
595
|
* Returns false if no namespace was found with that name
|
|
697
596
|
*/
|
|
698
597
|
calleeStartsWithNamespace(callee) {
|
|
699
598
|
let left = callee;
|
|
700
|
-
while (reflection_1.isDottedGetExpression(left)) {
|
|
599
|
+
while ((0, reflection_1.isDottedGetExpression)(left)) {
|
|
701
600
|
left = left.obj;
|
|
702
601
|
}
|
|
703
|
-
if (reflection_1.isVariableExpression(left)) {
|
|
704
|
-
let lowerName = left.name.text.toLowerCase();
|
|
602
|
+
if ((0, reflection_1.isVariableExpression)(left)) {
|
|
603
|
+
let lowerName = left.tokens.name.text.toLowerCase();
|
|
705
604
|
//find the first scope that contains this namespace
|
|
706
605
|
let scopes = this.program.getScopesForFile(this);
|
|
707
606
|
for (let scope of scopes) {
|
|
708
|
-
if (scope.namespaceLookup
|
|
607
|
+
if (scope.namespaceLookup.has(lowerName)) {
|
|
709
608
|
return true;
|
|
710
609
|
}
|
|
711
610
|
}
|
|
@@ -718,13 +617,16 @@ class BrsFile {
|
|
|
718
617
|
calleeIsKnownNamespaceFunction(callee, namespaceName) {
|
|
719
618
|
var _a, _b;
|
|
720
619
|
//if we have a variable and a namespace
|
|
721
|
-
if (reflection_1.isVariableExpression(callee) && namespaceName) {
|
|
722
|
-
let lowerCalleeName = (_b = (_a = callee === null || callee === void 0 ? void 0 : callee.name) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.toLowerCase();
|
|
620
|
+
if ((0, reflection_1.isVariableExpression)(callee) && namespaceName) {
|
|
621
|
+
let lowerCalleeName = (_b = (_a = callee === null || callee === void 0 ? void 0 : callee.tokens.name) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.toLowerCase();
|
|
723
622
|
if (lowerCalleeName) {
|
|
724
623
|
let scopes = this.program.getScopesForFile(this);
|
|
725
624
|
for (let scope of scopes) {
|
|
726
|
-
let namespace = scope.namespaceLookup
|
|
727
|
-
if (namespace.functionStatements
|
|
625
|
+
let namespace = scope.namespaceLookup.get(namespaceName.toLowerCase());
|
|
626
|
+
if (namespace.functionStatements.has(lowerCalleeName)) {
|
|
627
|
+
return true;
|
|
628
|
+
}
|
|
629
|
+
if (namespace.classStatements.has(lowerCalleeName)) {
|
|
728
630
|
return true;
|
|
729
631
|
}
|
|
730
632
|
}
|
|
@@ -733,392 +635,114 @@ class BrsFile {
|
|
|
733
635
|
return false;
|
|
734
636
|
}
|
|
735
637
|
/**
|
|
736
|
-
*
|
|
638
|
+
* Determine if the callee (i.e. function name) is a known function
|
|
737
639
|
*/
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
640
|
+
calleeIsKnownFunction(callee, namespaceName) {
|
|
641
|
+
var _a, _b;
|
|
642
|
+
//if we have a variable and a namespace
|
|
643
|
+
if ((0, reflection_1.isVariableExpression)(callee)) {
|
|
644
|
+
if (namespaceName) {
|
|
645
|
+
return this.calleeIsKnownNamespaceFunction(callee, namespaceName);
|
|
646
|
+
}
|
|
647
|
+
let scopes = this.program.getScopesForFile(this);
|
|
648
|
+
let lowerCalleeName = (_b = (_a = callee === null || callee === void 0 ? void 0 : callee.tokens.name) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.toLowerCase();
|
|
649
|
+
for (let scope of scopes) {
|
|
650
|
+
if (scope.getCallableByName(lowerCalleeName)) {
|
|
651
|
+
return true;
|
|
652
|
+
}
|
|
653
|
+
if (scope.getClass(lowerCalleeName)) {
|
|
654
|
+
return true;
|
|
655
|
+
}
|
|
747
656
|
}
|
|
748
657
|
}
|
|
749
|
-
|
|
750
|
-
return symbols;
|
|
658
|
+
return false;
|
|
751
659
|
}
|
|
752
660
|
/**
|
|
753
|
-
*
|
|
661
|
+
* Get the token closest to the position. if no token is found, the previous token is returned
|
|
754
662
|
*/
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
663
|
+
getClosestToken(position) {
|
|
664
|
+
let tokens = this.parser.tokens;
|
|
665
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
666
|
+
let token = tokens[i];
|
|
667
|
+
if (util_1.util.rangeContains(token.range, position)) {
|
|
668
|
+
return token;
|
|
669
|
+
}
|
|
670
|
+
//if the position less than this token range, then this position touches no token,
|
|
671
|
+
if (util_1.util.positionIsGreaterThanRange(position, token.range) === false) {
|
|
672
|
+
let t = tokens[i - 1];
|
|
673
|
+
//return the token or the first token
|
|
674
|
+
return t ? t : tokens[0];
|
|
763
675
|
}
|
|
764
676
|
}
|
|
765
|
-
|
|
766
|
-
return
|
|
677
|
+
//return the last token
|
|
678
|
+
return tokens[tokens.length - 1];
|
|
767
679
|
}
|
|
768
680
|
/**
|
|
769
|
-
* Builds a
|
|
681
|
+
* Builds a list of document symbols for this file. Used by LanguageServer's onDocumentSymbol functionality
|
|
682
|
+
* @deprecated use `DocumentSymbolProvider.process()` instead
|
|
770
683
|
*/
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
}
|
|
777
|
-
else if (reflection_1.isClassMethodStatement(statement)) {
|
|
778
|
-
symbolKind = vscode_languageserver_1.SymbolKind.Method;
|
|
779
|
-
}
|
|
780
|
-
else if (reflection_1.isClassFieldStatement(statement)) {
|
|
781
|
-
symbolKind = vscode_languageserver_1.SymbolKind.Field;
|
|
782
|
-
}
|
|
783
|
-
else if (reflection_1.isNamespaceStatement(statement)) {
|
|
784
|
-
symbolKind = vscode_languageserver_1.SymbolKind.Namespace;
|
|
785
|
-
for (const childStatement of statement.body.statements) {
|
|
786
|
-
const symbol = this.getDocumentSymbol(childStatement);
|
|
787
|
-
if (symbol) {
|
|
788
|
-
children.push(symbol);
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
else if (reflection_1.isClassStatement(statement)) {
|
|
793
|
-
symbolKind = vscode_languageserver_1.SymbolKind.Class;
|
|
794
|
-
for (const childStatement of statement.body) {
|
|
795
|
-
const symbol = this.getDocumentSymbol(childStatement);
|
|
796
|
-
if (symbol) {
|
|
797
|
-
children.push(symbol);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
else {
|
|
802
|
-
return;
|
|
803
|
-
}
|
|
804
|
-
const name = reflection_1.isClassFieldStatement(statement) ? statement.name.text : statement.getName(parser_1.ParseMode.BrighterScript);
|
|
805
|
-
return vscode_languageserver_1.DocumentSymbol.create(name, '', symbolKind, statement.range, statement.range, children);
|
|
684
|
+
getDocumentSymbols() {
|
|
685
|
+
return new DocumentSymbolProcessor_1.DocumentSymbolProcessor({
|
|
686
|
+
documentSymbols: [],
|
|
687
|
+
file: this,
|
|
688
|
+
program: this.program
|
|
689
|
+
}).process();
|
|
806
690
|
}
|
|
807
691
|
/**
|
|
808
|
-
* Builds a
|
|
692
|
+
* Builds a list of workspace symbols for this file. Used by LanguageServer's onWorkspaceSymbol functionality
|
|
809
693
|
*/
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
}
|
|
816
|
-
else if (reflection_1.isClassMethodStatement(statement)) {
|
|
817
|
-
symbolKind = vscode_languageserver_1.SymbolKind.Method;
|
|
818
|
-
}
|
|
819
|
-
else if (reflection_1.isNamespaceStatement(statement)) {
|
|
820
|
-
symbolKind = vscode_languageserver_1.SymbolKind.Namespace;
|
|
821
|
-
for (const childStatement of statement.body.statements) {
|
|
822
|
-
for (const symbol of this.generateWorkspaceSymbols(childStatement, statement)) {
|
|
823
|
-
symbols.push(symbol);
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
else if (reflection_1.isClassStatement(statement)) {
|
|
828
|
-
symbolKind = vscode_languageserver_1.SymbolKind.Class;
|
|
829
|
-
for (const childStatement of statement.body) {
|
|
830
|
-
for (const symbol of this.generateWorkspaceSymbols(childStatement, statement)) {
|
|
831
|
-
symbols.push(symbol);
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
else {
|
|
836
|
-
return symbols;
|
|
837
|
-
}
|
|
838
|
-
const name = statement.getName(parser_1.ParseMode.BrighterScript);
|
|
839
|
-
const uri = util_1.util.pathToUri(this.srcPath);
|
|
840
|
-
const symbol = vscode_languageserver_1.SymbolInformation.create(name, symbolKind, statement.range, uri, containerStatement === null || containerStatement === void 0 ? void 0 : containerStatement.getName(parser_1.ParseMode.BrighterScript));
|
|
841
|
-
symbols.push(symbol);
|
|
842
|
-
return symbols;
|
|
694
|
+
getWorkspaceSymbols() {
|
|
695
|
+
return new WorkspaceSymbolProcessor_1.WorkspaceSymbolProcessor({
|
|
696
|
+
program: this.program,
|
|
697
|
+
workspaceSymbols: []
|
|
698
|
+
}).process();
|
|
843
699
|
}
|
|
844
700
|
/**
|
|
845
701
|
* Given a position in a file, if the position is sitting on some type of identifier,
|
|
846
702
|
* go to the definition of that identifier (where this thing was first defined)
|
|
703
|
+
* @deprecated use `DefinitionProvider.process()` instead
|
|
847
704
|
*/
|
|
848
705
|
getDefinition(position) {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
lexer_1.TokenKind.StringLiteral
|
|
856
|
-
];
|
|
857
|
-
//throw out invalid tokens and the wrong kind of tokens
|
|
858
|
-
if (!token || !definitionTokenTypes.includes(token.kind)) {
|
|
859
|
-
return results;
|
|
860
|
-
}
|
|
861
|
-
let textToSearchFor = token.text.toLowerCase();
|
|
862
|
-
const previousToken = this.parser.getTokenAt({ line: token.range.start.line, character: token.range.start.character });
|
|
863
|
-
if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === lexer_1.TokenKind.Callfunc) {
|
|
864
|
-
for (const scope of this.program.getScopes()) {
|
|
865
|
-
//to only get functions defined in interface methods
|
|
866
|
-
const callable = scope.getAllCallables().find((c) => c.callable.name.toLowerCase() === textToSearchFor); // eslint-disable-line @typescript-eslint/no-loop-func
|
|
867
|
-
if (callable) {
|
|
868
|
-
results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(callable.callable.file.srcPath), callable.callable.functionStatement.range));
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
return results;
|
|
872
|
-
}
|
|
873
|
-
let classToken = this.parser.getTokenBefore(token, lexer_1.TokenKind.Class);
|
|
874
|
-
if (classToken) {
|
|
875
|
-
let cs = this.parser.references.classStatements.find((cs) => cs.classKeyword.range === classToken.range);
|
|
876
|
-
if (cs === null || cs === void 0 ? void 0 : cs.parentClassName) {
|
|
877
|
-
const nameParts = cs.parentClassName.getNameParts();
|
|
878
|
-
let extendedClass = this.getClassFileLink(nameParts[nameParts.length - 1], nameParts.slice(0, -1).join('.'));
|
|
879
|
-
if (extendedClass) {
|
|
880
|
-
results.push(vscode_languageserver_1.Location.create(util_1.util.pathToUri(extendedClass.file.srcPath), extendedClass.item.range));
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
return results;
|
|
884
|
-
}
|
|
885
|
-
if (token.kind === lexer_1.TokenKind.StringLiteral) {
|
|
886
|
-
// We need to strip off the quotes but only if present
|
|
887
|
-
const startIndex = textToSearchFor.startsWith('"') ? 1 : 0;
|
|
888
|
-
let endIndex = textToSearchFor.length;
|
|
889
|
-
if (textToSearchFor.endsWith('"')) {
|
|
890
|
-
endIndex--;
|
|
891
|
-
}
|
|
892
|
-
textToSearchFor = textToSearchFor.substring(startIndex, endIndex);
|
|
893
|
-
}
|
|
894
|
-
const func = this.getFunctionExpressionAtPosition(position);
|
|
895
|
-
//look through local variables first
|
|
896
|
-
//find any variable with this name
|
|
897
|
-
for (const symbol of func.symbolTable.ownSymbols) {
|
|
898
|
-
//we found a variable declaration with this token text
|
|
899
|
-
if (symbol.name.toLowerCase() === textToSearchFor) {
|
|
900
|
-
const uri = util_1.util.pathToUri(this.srcPath);
|
|
901
|
-
results.push(vscode_languageserver_1.Location.create(uri, symbol.range));
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
if (this.parser.tokenFollows(token, lexer_1.TokenKind.Goto)) {
|
|
905
|
-
for (const label of func.labelStatements) {
|
|
906
|
-
if (label.tokens.identifier.text.toLocaleLowerCase() === textToSearchFor) {
|
|
907
|
-
const uri = util_1.util.pathToUri(this.srcPath);
|
|
908
|
-
results.push(vscode_languageserver_1.Location.create(uri, label.tokens.identifier.range));
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
const filesSearched = new Set();
|
|
913
|
-
//look through all files in scope for matches
|
|
914
|
-
for (const scope of this.program.getScopesForFile(this)) {
|
|
915
|
-
for (const file of scope.getAllFiles()) {
|
|
916
|
-
if (reflection_1.isXmlFile(file) || filesSearched.has(file)) {
|
|
917
|
-
continue;
|
|
918
|
-
}
|
|
919
|
-
filesSearched.add(file);
|
|
920
|
-
if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === lexer_1.TokenKind.Dot && file.parseMode === parser_1.ParseMode.BrighterScript) {
|
|
921
|
-
results.push(...this.getClassMemberDefinitions(textToSearchFor, file));
|
|
922
|
-
const namespaceDefinition = this.getNamespaceDefinitions(token, file);
|
|
923
|
-
if (namespaceDefinition) {
|
|
924
|
-
results.push(namespaceDefinition);
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
const statementHandler = (statement) => {
|
|
928
|
-
if (statement.getName(this.parseMode).toLowerCase() === textToSearchFor) {
|
|
929
|
-
const uri = util_1.util.pathToUri(file.srcPath);
|
|
930
|
-
results.push(vscode_languageserver_1.Location.create(uri, statement.range));
|
|
931
|
-
}
|
|
932
|
-
};
|
|
933
|
-
file.parser.ast.walk(visitors_1.createVisitor({
|
|
934
|
-
FunctionStatement: statementHandler
|
|
935
|
-
}), {
|
|
936
|
-
walkMode: visitors_1.WalkMode.visitStatements
|
|
937
|
-
});
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
return results;
|
|
706
|
+
return new DefinitionProvider_1.DefinitionProvider({
|
|
707
|
+
program: this.program,
|
|
708
|
+
file: this,
|
|
709
|
+
position: position,
|
|
710
|
+
definitions: []
|
|
711
|
+
}).process();
|
|
941
712
|
}
|
|
942
713
|
getClassMemberDefinitions(textToSearchFor, file) {
|
|
943
714
|
let results = [];
|
|
944
715
|
//get class fields and members
|
|
945
716
|
const statementHandler = (statement) => {
|
|
946
717
|
if (statement.getName(file.parseMode).toLowerCase() === textToSearchFor) {
|
|
947
|
-
results.push(
|
|
718
|
+
results.push(util_1.util.createLocation(util_1.util.pathToUri(file.srcPath), statement.range));
|
|
948
719
|
}
|
|
949
720
|
};
|
|
950
721
|
const fieldStatementHandler = (statement) => {
|
|
951
|
-
if (statement.name.text.toLowerCase() === textToSearchFor) {
|
|
952
|
-
results.push(
|
|
722
|
+
if (statement.tokens.name.text.toLowerCase() === textToSearchFor) {
|
|
723
|
+
results.push(util_1.util.createLocation(util_1.util.pathToUri(file.srcPath), statement.range));
|
|
953
724
|
}
|
|
954
725
|
};
|
|
955
|
-
file.parser.ast.walk(visitors_1.createVisitor({
|
|
956
|
-
|
|
957
|
-
|
|
726
|
+
file.parser.ast.walk((0, visitors_1.createVisitor)({
|
|
727
|
+
MethodStatement: statementHandler,
|
|
728
|
+
FieldStatement: fieldStatementHandler
|
|
958
729
|
}), {
|
|
959
730
|
walkMode: visitors_1.WalkMode.visitStatements
|
|
960
731
|
});
|
|
961
732
|
return results;
|
|
962
733
|
}
|
|
963
|
-
getHover(position) {
|
|
964
|
-
var _a;
|
|
965
|
-
//get the token at the position
|
|
966
|
-
let token = this.parser.getTokenAt(position);
|
|
967
|
-
let hoverTokenTypes = [
|
|
968
|
-
lexer_1.TokenKind.Identifier,
|
|
969
|
-
lexer_1.TokenKind.Function,
|
|
970
|
-
lexer_1.TokenKind.EndFunction,
|
|
971
|
-
lexer_1.TokenKind.Sub,
|
|
972
|
-
lexer_1.TokenKind.EndSub
|
|
973
|
-
];
|
|
974
|
-
//throw out invalid tokens and the wrong kind of tokens
|
|
975
|
-
if (!token || !hoverTokenTypes.includes(token.kind)) {
|
|
976
|
-
return null;
|
|
977
|
-
}
|
|
978
|
-
let lowerTokenText = token.text.toLowerCase();
|
|
979
|
-
//look through local variables first
|
|
980
|
-
{
|
|
981
|
-
const func = this.getFunctionExpressionAtPosition(position);
|
|
982
|
-
for (const labelStatement of func.labelStatements) {
|
|
983
|
-
if (labelStatement.tokens.identifier.text.toLocaleLowerCase() === lowerTokenText) {
|
|
984
|
-
return {
|
|
985
|
-
range: token.range,
|
|
986
|
-
contents: `${labelStatement.tokens.identifier.text}: label`
|
|
987
|
-
};
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
const typeTexts = [];
|
|
991
|
-
for (const scope of this.program.getScopesForFile(this)) {
|
|
992
|
-
scope.linkSymbolTable();
|
|
993
|
-
if (func.symbolTable.hasSymbol(lowerTokenText)) {
|
|
994
|
-
const type = (_a = func.symbolTable) === null || _a === void 0 ? void 0 : _a.getSymbolType(lowerTokenText);
|
|
995
|
-
let scopeTypeText = '';
|
|
996
|
-
if (reflection_1.isFunctionType(type)) {
|
|
997
|
-
scopeTypeText = type.toString();
|
|
998
|
-
}
|
|
999
|
-
else {
|
|
1000
|
-
scopeTypeText = `${token.text} as ${type.toString()}`;
|
|
1001
|
-
}
|
|
1002
|
-
if (!typeTexts.includes(scopeTypeText)) {
|
|
1003
|
-
typeTexts.push(scopeTypeText);
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
scope.unlinkSymbolTable();
|
|
1007
|
-
}
|
|
1008
|
-
const typeText = typeTexts.join(' | ');
|
|
1009
|
-
if (typeText) {
|
|
1010
|
-
return {
|
|
1011
|
-
range: token.range,
|
|
1012
|
-
contents: typeText
|
|
1013
|
-
};
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
//look through all callables in relevant scopes
|
|
1017
|
-
{
|
|
1018
|
-
let scopes = this.program.getScopesForFile(this);
|
|
1019
|
-
for (let scope of scopes) {
|
|
1020
|
-
let callable = scope.getCallableByName(lowerTokenText);
|
|
1021
|
-
if (callable) {
|
|
1022
|
-
return {
|
|
1023
|
-
range: token.range,
|
|
1024
|
-
contents: callable.type.toString()
|
|
1025
|
-
};
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
getSignatureHelpForNamespaceMethods(callableName, dottedGetText, scope) {
|
|
1031
|
-
var _a;
|
|
1032
|
-
if (!dottedGetText) {
|
|
1033
|
-
return [];
|
|
1034
|
-
}
|
|
1035
|
-
let namespaceLookup = scope.namespaceLookup;
|
|
1036
|
-
let resultsMap = new Map();
|
|
1037
|
-
for (let key in namespaceLookup) {
|
|
1038
|
-
let namespace = namespaceLookup[key.toLowerCase()];
|
|
1039
|
-
//completionName = "NameA."
|
|
1040
|
-
//completionName = "NameA.Na
|
|
1041
|
-
//NameA
|
|
1042
|
-
//NameA.NameB
|
|
1043
|
-
//NameA.NameB.NameC
|
|
1044
|
-
if (namespace.fullName.toLowerCase() === dottedGetText.toLowerCase()) {
|
|
1045
|
-
//add function and class statement completions
|
|
1046
|
-
for (let stmt of namespace.statements) {
|
|
1047
|
-
if (reflection_1.isFunctionStatement(stmt) && stmt.name.text.toLowerCase() === callableName.toLowerCase()) {
|
|
1048
|
-
const result = (_a = namespace.file) === null || _a === void 0 ? void 0 : _a.getSignatureHelpForStatement(stmt);
|
|
1049
|
-
if (!resultsMap.has(result.key)) {
|
|
1050
|
-
resultsMap.set(result.key, result);
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
return [...resultsMap.values()];
|
|
1057
|
-
}
|
|
1058
|
-
getSignatureHelpForStatement(statement) {
|
|
1059
|
-
if (!reflection_1.isFunctionStatement(statement) && !reflection_1.isClassMethodStatement(statement)) {
|
|
1060
|
-
return undefined;
|
|
1061
|
-
}
|
|
1062
|
-
const func = statement.func;
|
|
1063
|
-
const funcStartPosition = func.range.start;
|
|
1064
|
-
// Get function comments in reverse order
|
|
1065
|
-
let currentToken = this.parser.getTokenAt(funcStartPosition);
|
|
1066
|
-
let functionComments = [];
|
|
1067
|
-
while (currentToken) {
|
|
1068
|
-
currentToken = this.parser.getPreviousToken(currentToken);
|
|
1069
|
-
if (!currentToken) {
|
|
1070
|
-
break;
|
|
1071
|
-
}
|
|
1072
|
-
if (currentToken.range.start.line + 1 < funcStartPosition.line) {
|
|
1073
|
-
if (functionComments.length === 0) {
|
|
1074
|
-
break;
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
const kind = currentToken.kind;
|
|
1078
|
-
if (kind === lexer_1.TokenKind.Comment) {
|
|
1079
|
-
// Strip off common leading characters to make it easier to read
|
|
1080
|
-
const commentText = currentToken.text.replace(/^[' *\/]+/, '');
|
|
1081
|
-
functionComments.unshift(commentText);
|
|
1082
|
-
}
|
|
1083
|
-
else if (kind === lexer_1.TokenKind.Newline) {
|
|
1084
|
-
if (functionComments.length === 0) {
|
|
1085
|
-
continue;
|
|
1086
|
-
}
|
|
1087
|
-
// if we already had a new line as the last token then exit out
|
|
1088
|
-
if (functionComments[0] === currentToken.text) {
|
|
1089
|
-
break;
|
|
1090
|
-
}
|
|
1091
|
-
functionComments.unshift(currentToken.text);
|
|
1092
|
-
}
|
|
1093
|
-
else {
|
|
1094
|
-
break;
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
const documentation = functionComments.join('').trim();
|
|
1098
|
-
const lines = util_1.util.splitIntoLines(this.fileContents);
|
|
1099
|
-
let key = statement.name.text + documentation;
|
|
1100
|
-
const params = [];
|
|
1101
|
-
for (const param of func.parameters) {
|
|
1102
|
-
params.push(vscode_languageserver_1.ParameterInformation.create(param.name.text));
|
|
1103
|
-
key += param.name.text;
|
|
1104
|
-
}
|
|
1105
|
-
const label = util_1.util.getTextForRange(lines, util_1.util.createRangeFromPositions(func.functionType.range.start, func.body.range.start)).trim();
|
|
1106
|
-
const signature = vscode_languageserver_1.SignatureInformation.create(label, documentation, ...params);
|
|
1107
|
-
const index = 1;
|
|
1108
|
-
return { key: key, signature: signature, index: index };
|
|
1109
|
-
}
|
|
1110
734
|
getClassMethod(classStatement, name, walkParents = true) {
|
|
1111
735
|
var _a;
|
|
1112
736
|
//TODO - would like to write this with getClassHieararchy; but got stuck on working out the scopes to use... :(
|
|
1113
737
|
let statement;
|
|
1114
738
|
const statementHandler = (e) => {
|
|
1115
|
-
if (!statement && e.name.text.toLowerCase() === name.toLowerCase()) {
|
|
739
|
+
if (!statement && e.tokens.name.text.toLowerCase() === name.toLowerCase()) {
|
|
1116
740
|
statement = e;
|
|
1117
741
|
}
|
|
1118
742
|
};
|
|
1119
743
|
while (classStatement) {
|
|
1120
|
-
classStatement.walk(visitors_1.createVisitor({
|
|
1121
|
-
|
|
744
|
+
classStatement.walk((0, visitors_1.createVisitor)({
|
|
745
|
+
MethodStatement: statementHandler
|
|
1122
746
|
}), {
|
|
1123
747
|
walkMode: visitors_1.WalkMode.visitStatements
|
|
1124
748
|
});
|
|
@@ -1135,48 +759,58 @@ class BrsFile {
|
|
|
1135
759
|
}
|
|
1136
760
|
return statement;
|
|
1137
761
|
}
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
sigHelp.signature.label = sigHelp.signature.label.replace(/(function|sub) new/, sigHelp.key);
|
|
1144
|
-
}
|
|
1145
|
-
return sigHelp;
|
|
1146
|
-
}
|
|
762
|
+
/**
|
|
763
|
+
* Given a position in a file, if the position is sitting on some type of identifier,
|
|
764
|
+
* look up all references of that identifier (every place that identifier is used across the whole app)
|
|
765
|
+
* @deprecated use `ReferencesProvider.process()` instead
|
|
766
|
+
*/
|
|
1147
767
|
getReferences(position) {
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
}), {
|
|
1166
|
-
walkMode: visitors_1.WalkMode.visitExpressionsRecursive
|
|
1167
|
-
});
|
|
1168
|
-
}
|
|
768
|
+
return new ReferencesProvider_1.ReferencesProvider({
|
|
769
|
+
program: this.program,
|
|
770
|
+
file: this,
|
|
771
|
+
position: position,
|
|
772
|
+
references: []
|
|
773
|
+
}).process();
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Generate the code, map, and typedef for this file
|
|
777
|
+
*/
|
|
778
|
+
serialize() {
|
|
779
|
+
const result = {};
|
|
780
|
+
const transpiled = this.transpile();
|
|
781
|
+
if (typeof transpiled.code === 'string') {
|
|
782
|
+
result.code = transpiled.code;
|
|
1169
783
|
}
|
|
1170
|
-
|
|
784
|
+
if (transpiled.map) {
|
|
785
|
+
result.map = transpiled.map.toString();
|
|
786
|
+
}
|
|
787
|
+
//generate the typedef (if this is not a typedef itself, and if enabled)
|
|
788
|
+
if (!this.isTypedef && this.program.options.emitDefinitions) {
|
|
789
|
+
result.typedef = this.getTypedef();
|
|
790
|
+
}
|
|
791
|
+
return result;
|
|
1171
792
|
}
|
|
1172
793
|
/**
|
|
1173
794
|
* Convert the brightscript/brighterscript source code into valid brightscript
|
|
1174
795
|
*/
|
|
1175
796
|
transpile() {
|
|
797
|
+
var _a;
|
|
1176
798
|
const state = new BrsTranspileState_1.BrsTranspileState(this);
|
|
799
|
+
state.editor = (_a = this.editor) !== null && _a !== void 0 ? _a : new Editor_1.Editor();
|
|
1177
800
|
let transpileResult;
|
|
1178
801
|
if (this.needsTranspiled) {
|
|
1179
|
-
|
|
802
|
+
const astTranspile = this.ast.transpile(state);
|
|
803
|
+
const trailingComments = [];
|
|
804
|
+
if (util_1.util.hasLeadingComments(this.parser.eofToken)) {
|
|
805
|
+
if (util_1.util.isLeadingCommentOnSameLine(this.ast.statements[this.ast.statements.length - 1], this.parser.eofToken)) {
|
|
806
|
+
trailingComments.push(' ');
|
|
807
|
+
}
|
|
808
|
+
else {
|
|
809
|
+
trailingComments.push('\n');
|
|
810
|
+
}
|
|
811
|
+
trailingComments.push(...state.transpileLeadingComments(this.parser.eofToken));
|
|
812
|
+
}
|
|
813
|
+
transpileResult = util_1.util.sourceNodeFromTranspileResult(null, null, state.srcPath, [...astTranspile, ...trailingComments]);
|
|
1180
814
|
}
|
|
1181
815
|
else if (this.program.options.sourceMap) {
|
|
1182
816
|
//emit code as-is with a simple map to the original file location
|
|
@@ -1186,12 +820,18 @@ class BrsFile {
|
|
|
1186
820
|
//simple SourceNode wrapping the entire file to simplify the logic below
|
|
1187
821
|
transpileResult = new source_map_1.SourceNode(null, null, state.srcPath, this.fileContents);
|
|
1188
822
|
}
|
|
823
|
+
//if we created an editor for this flow, undo the edits now
|
|
824
|
+
if (!this.editor) {
|
|
825
|
+
//undo any AST edits that the transpile cycle has made
|
|
826
|
+
state.editor.undoAll();
|
|
827
|
+
}
|
|
1189
828
|
if (this.program.options.sourceMap) {
|
|
1190
|
-
|
|
829
|
+
const stagingFileName = path.basename(state.srcPath).replace(/\.bs$/, '.brs');
|
|
830
|
+
return new source_map_1.SourceNode(null, null, stagingFileName, [
|
|
1191
831
|
transpileResult,
|
|
1192
832
|
//add the sourcemap reference comment
|
|
1193
|
-
`'//# sourceMappingURL=./${
|
|
1194
|
-
]).toStringWithSourceMap();
|
|
833
|
+
state.newline + `'//# sourceMappingURL=./${stagingFileName}.map`
|
|
834
|
+
]).toStringWithSourceMap({ file: stagingFileName });
|
|
1195
835
|
}
|
|
1196
836
|
else {
|
|
1197
837
|
return {
|
|
@@ -1200,30 +840,326 @@ class BrsFile {
|
|
|
1200
840
|
};
|
|
1201
841
|
}
|
|
1202
842
|
}
|
|
843
|
+
getNamespaceSymbolTable(allowCache = true) {
|
|
844
|
+
var _a;
|
|
845
|
+
const makeImportTreeNamespaceTable = () => {
|
|
846
|
+
const nsTable = new SymbolTable_1.SymbolTable(`File Complete NamespaceTypes ${this.destPath}`, () => this.program.globalScope.symbolTable);
|
|
847
|
+
this.updateWithDependenciesNamespaceTables(nsTable, new Set());
|
|
848
|
+
return nsTable;
|
|
849
|
+
};
|
|
850
|
+
if (!allowCache) {
|
|
851
|
+
return makeImportTreeNamespaceTable();
|
|
852
|
+
}
|
|
853
|
+
return (_a = this.cache) === null || _a === void 0 ? void 0 : _a.getOrAdd(`namespaceSymbolTable`, makeImportTreeNamespaceTable);
|
|
854
|
+
}
|
|
855
|
+
updateWithDependenciesNamespaceTables(symbolTableToUpdate, filesToSkip) {
|
|
856
|
+
symbolTableToUpdate.mergeNamespaceSymbolTables(this.getOwnNamespaceSymbolTable());
|
|
857
|
+
filesToSkip.add(this.destPath.toLowerCase());
|
|
858
|
+
for (const filePath of this.dependencies) {
|
|
859
|
+
if (filesToSkip.has(filePath.toLowerCase())) {
|
|
860
|
+
continue;
|
|
861
|
+
}
|
|
862
|
+
const importedFile = this.program.getFile(filePath);
|
|
863
|
+
if (!(0, reflection_1.isBrsFile)(importedFile) || importedFile === this) {
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
importedFile.updateWithDependenciesNamespaceTables(symbolTableToUpdate, filesToSkip);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
getOwnNamespaceSymbolTable() {
|
|
870
|
+
var _a;
|
|
871
|
+
return (_a = this.cache) === null || _a === void 0 ? void 0 : _a.getOrAdd(`ownNamespaceSymbolTable`, () => {
|
|
872
|
+
const nsTable = new SymbolTable_1.SymbolTable(`File NamespaceTypes ${this.destPath}`, () => this.program.globalScope.symbolTable);
|
|
873
|
+
this.populateNameSpaceSymbolTable(nsTable);
|
|
874
|
+
return nsTable;
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
processSymbolInformation() {
|
|
878
|
+
// Get namespaces across imported files
|
|
879
|
+
const nsTable = this.getNamespaceSymbolTable(false);
|
|
880
|
+
this.linkSymbolTableDisposables.push(this.ast.symbolTable.addSibling(nsTable));
|
|
881
|
+
this.validationSegmenter.processTree(this.ast);
|
|
882
|
+
this.program.addFileSymbolInfo(this);
|
|
883
|
+
this.unlinkNamespaceSymbolTables();
|
|
884
|
+
}
|
|
885
|
+
unlinkNamespaceSymbolTables() {
|
|
886
|
+
for (let disposable of this.linkSymbolTableDisposables) {
|
|
887
|
+
disposable();
|
|
888
|
+
}
|
|
889
|
+
this.linkSymbolTableDisposables = [];
|
|
890
|
+
}
|
|
891
|
+
populateNameSpaceSymbolTable(namespaceSymbolTable) {
|
|
892
|
+
var _a;
|
|
893
|
+
//Add namespace aggregates to namespace member tables
|
|
894
|
+
const namespaceTypesKnown = new Map();
|
|
895
|
+
// eslint-disable-next-line no-bitwise
|
|
896
|
+
let getTypeOptions = { flags: 1 /* SymbolTypeFlag.runtime */ | 2 /* SymbolTypeFlag.typetime */ };
|
|
897
|
+
for (const [nsName, nsContainer] of this.getNamespaceLookupObject()) {
|
|
898
|
+
let currentNSType = null;
|
|
899
|
+
let parentNSType = null;
|
|
900
|
+
const existingNsStmt = (_a = nsContainer.namespaceStatements) === null || _a === void 0 ? void 0 : _a[0];
|
|
901
|
+
if (!nsContainer.isTopLevel) {
|
|
902
|
+
parentNSType = namespaceTypesKnown.get(nsContainer.parentNameLower);
|
|
903
|
+
if (!parentNSType) {
|
|
904
|
+
// we don't know about the parent namespace... uh, oh!
|
|
905
|
+
this.program.logger.error(`Unable to find parent namespace type for namespace ${nsName}`);
|
|
906
|
+
break;
|
|
907
|
+
}
|
|
908
|
+
currentNSType = parentNSType.getMemberType(nsContainer.fullNameLower, getTypeOptions);
|
|
909
|
+
}
|
|
910
|
+
else {
|
|
911
|
+
currentNSType = namespaceSymbolTable.getSymbolType(nsContainer.fullNameLower, getTypeOptions);
|
|
912
|
+
}
|
|
913
|
+
if (!(0, reflection_1.isNamespaceType)(currentNSType)) {
|
|
914
|
+
if (!currentNSType || (0, reflection_1.isReferenceType)(currentNSType) || (0, reflection_1.isCallableType)(currentNSType)) {
|
|
915
|
+
currentNSType = existingNsStmt
|
|
916
|
+
? existingNsStmt.getType(getTypeOptions)
|
|
917
|
+
: new types_1.NamespaceType(nsName);
|
|
918
|
+
if (parentNSType) {
|
|
919
|
+
// adding as a member of existing NS
|
|
920
|
+
parentNSType.addMember(nsContainer.lastPartName, { definingNode: existingNsStmt }, currentNSType, getTypeOptions.flags);
|
|
921
|
+
}
|
|
922
|
+
else {
|
|
923
|
+
namespaceSymbolTable.addSymbol(nsContainer.lastPartName, { definingNode: existingNsStmt }, currentNSType, getTypeOptions.flags);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
else {
|
|
927
|
+
// Something else already used the name this namespace is using.
|
|
928
|
+
continue;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
else {
|
|
932
|
+
// Existing known namespace
|
|
933
|
+
}
|
|
934
|
+
if (!namespaceTypesKnown.has(nsName)) {
|
|
935
|
+
namespaceTypesKnown.set(nsName, currentNSType);
|
|
936
|
+
}
|
|
937
|
+
currentNSType.memberTable.addSibling(nsContainer.symbolTable);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
getValidationSegments(changedSymbols) {
|
|
941
|
+
const segments = this.validationSegmenter.getSegments(changedSymbols);
|
|
942
|
+
return segments;
|
|
943
|
+
}
|
|
944
|
+
get requiredSymbols() {
|
|
945
|
+
return this.cache.getOrAdd(`requiredSymbols`, () => {
|
|
946
|
+
var _a, _b, _c;
|
|
947
|
+
const allNeededSymbolSets = this.validationSegmenter.unresolvedSegmentsSymbols.values();
|
|
948
|
+
const requiredSymbols = [];
|
|
949
|
+
const addedSymbols = new Map();
|
|
950
|
+
addedSymbols.set(1 /* SymbolTypeFlag.runtime */, new Set());
|
|
951
|
+
addedSymbols.set(2 /* SymbolTypeFlag.typetime */, new Set());
|
|
952
|
+
for (const setOfSymbols of allNeededSymbolSets) {
|
|
953
|
+
for (const symbol of setOfSymbols) {
|
|
954
|
+
const fullSymbolKey = symbol.typeChain.map(tce => tce.name).join('.').toLowerCase();
|
|
955
|
+
//for (const flag of [SymbolTypeFlag.runtime, SymbolTypeFlag.typetime]) {
|
|
956
|
+
// eslint-disable-next-line no-bitwise
|
|
957
|
+
const flag = symbol.endChainFlags;
|
|
958
|
+
// if (symbol.endChainFlags & flag) {
|
|
959
|
+
if ((_a = this.providedSymbols.symbolMap.get(flag)) === null || _a === void 0 ? void 0 : _a.has(fullSymbolKey)) {
|
|
960
|
+
// this catches namespaced things
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
if (!((_b = addedSymbols.get(flag)) === null || _b === void 0 ? void 0 : _b.has(fullSymbolKey))) {
|
|
964
|
+
requiredSymbols.push(symbol);
|
|
965
|
+
(_c = addedSymbols.get(flag)) === null || _c === void 0 ? void 0 : _c.add(fullSymbolKey);
|
|
966
|
+
}
|
|
967
|
+
// }
|
|
968
|
+
//}
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
return requiredSymbols;
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
get providedSymbols() {
|
|
975
|
+
var _a;
|
|
976
|
+
return (_a = this.cache) === null || _a === void 0 ? void 0 : _a.getOrAdd(`providedSymbols`, () => {
|
|
977
|
+
return this.getProvidedSymbols();
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
get assignedSymbols() {
|
|
981
|
+
return this.cache.getOrAdd(`assignedSymbols`, () => {
|
|
982
|
+
var _a;
|
|
983
|
+
const allAssignedSymbolsEntries = (_a = this.validationSegmenter.assignedTokensInSegment.entries()) !== null && _a !== void 0 ? _a : [];
|
|
984
|
+
let allAssignedSymbolsSet = [];
|
|
985
|
+
for (const [_segment, assignedSymbolSet] of allAssignedSymbolsEntries) {
|
|
986
|
+
allAssignedSymbolsSet.push(...assignedSymbolSet.values());
|
|
987
|
+
}
|
|
988
|
+
return allAssignedSymbolsSet;
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
getProvidedSymbols() {
|
|
992
|
+
var _a, _b;
|
|
993
|
+
const symbolMap = new Map();
|
|
994
|
+
const runTimeSymbolMap = new Map();
|
|
995
|
+
const typeTimeSymbolMap = new Map();
|
|
996
|
+
const tablesToGetSymbolsFrom = [{
|
|
997
|
+
table: this.parser.symbolTable
|
|
998
|
+
}];
|
|
999
|
+
for (const namespaceStatement of this._cachedLookups.namespaceStatements) {
|
|
1000
|
+
tablesToGetSymbolsFrom.push({
|
|
1001
|
+
table: namespaceStatement.body.getSymbolTable(),
|
|
1002
|
+
namePrefixLower: namespaceStatement.getName(Parser_1.ParseMode.BrighterScript).toLowerCase()
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
for (const symbolTable of tablesToGetSymbolsFrom) {
|
|
1006
|
+
const runTimeSymbols = symbolTable.table.getOwnSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1007
|
+
const typeTimeSymbols = symbolTable.table.getOwnSymbols(2 /* SymbolTypeFlag.typetime */);
|
|
1008
|
+
for (const symbol of runTimeSymbols) {
|
|
1009
|
+
if (!(0, reflection_1.isAnyReferenceType)(symbol.type) && symbol.name.toLowerCase() !== 'm') {
|
|
1010
|
+
const symbolNameLower = symbolTable.namePrefixLower
|
|
1011
|
+
? `${symbolTable.namePrefixLower}.${symbol.name.toLowerCase()}`
|
|
1012
|
+
: symbol.name.toLowerCase();
|
|
1013
|
+
runTimeSymbolMap.set(symbolNameLower, symbol);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
for (const symbol of typeTimeSymbols) {
|
|
1017
|
+
if (!(0, reflection_1.isAnyReferenceType)(symbol.type)) {
|
|
1018
|
+
const symbolNameLower = symbolTable.namePrefixLower
|
|
1019
|
+
? `${symbolTable.namePrefixLower}.${symbol.name.toLowerCase()}`
|
|
1020
|
+
: symbol.name.toLowerCase();
|
|
1021
|
+
typeTimeSymbolMap.set(symbolNameLower, symbol);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
symbolMap.set(1 /* SymbolTypeFlag.runtime */, runTimeSymbolMap);
|
|
1026
|
+
symbolMap.set(2 /* SymbolTypeFlag.typetime */, typeTimeSymbolMap);
|
|
1027
|
+
const changes = new Map();
|
|
1028
|
+
changes.set(1 /* SymbolTypeFlag.runtime */, new Set());
|
|
1029
|
+
changes.set(2 /* SymbolTypeFlag.typetime */, new Set());
|
|
1030
|
+
const previouslyProvidedSymbols = (_a = this.program.getFileSymbolInfo(this)) === null || _a === void 0 ? void 0 : _a.provides.symbolMap;
|
|
1031
|
+
const previousSymbolsChecked = new Map();
|
|
1032
|
+
previousSymbolsChecked.set(1 /* SymbolTypeFlag.runtime */, new Set());
|
|
1033
|
+
previousSymbolsChecked.set(2 /* SymbolTypeFlag.typetime */, new Set());
|
|
1034
|
+
for (const flag of [1 /* SymbolTypeFlag.runtime */, 2 /* SymbolTypeFlag.typetime */]) {
|
|
1035
|
+
const newSymbolMapForFlag = symbolMap.get(flag);
|
|
1036
|
+
const oldSymbolMapForFlag = previouslyProvidedSymbols === null || previouslyProvidedSymbols === void 0 ? void 0 : previouslyProvidedSymbols.get(flag);
|
|
1037
|
+
const previousSymbolsCheckedForFlag = previousSymbolsChecked.get(flag);
|
|
1038
|
+
const changesForFlag = changes.get(flag);
|
|
1039
|
+
if (!oldSymbolMapForFlag) {
|
|
1040
|
+
for (const key of newSymbolMapForFlag.keys()) {
|
|
1041
|
+
changesForFlag.add(key);
|
|
1042
|
+
}
|
|
1043
|
+
continue;
|
|
1044
|
+
}
|
|
1045
|
+
for (const [symbolKey, symbol] of newSymbolMapForFlag) {
|
|
1046
|
+
const symbolType = symbol.type;
|
|
1047
|
+
const previousType = (_b = oldSymbolMapForFlag === null || oldSymbolMapForFlag === void 0 ? void 0 : oldSymbolMapForFlag.get(symbolKey)) === null || _b === void 0 ? void 0 : _b.type;
|
|
1048
|
+
previousSymbolsCheckedForFlag.add(symbolKey);
|
|
1049
|
+
if (!previousType) {
|
|
1050
|
+
changesForFlag.add(symbolKey);
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
const data = {};
|
|
1054
|
+
if (!symbolType.isEqual(previousType, data)) {
|
|
1055
|
+
changesForFlag.add(symbolKey);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
for (const [symbolKey] of previouslyProvidedSymbols.get(flag)) {
|
|
1059
|
+
if (!previousSymbolsCheckedForFlag.has(symbolKey)) {
|
|
1060
|
+
changesForFlag.add(symbolKey);
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
return {
|
|
1065
|
+
symbolMap: symbolMap,
|
|
1066
|
+
changes: changes
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
markSegmentAsValidated(node) {
|
|
1070
|
+
this.validationSegmenter.markSegmentAsValidated(node);
|
|
1071
|
+
}
|
|
1072
|
+
getNamespaceLookupObject() {
|
|
1073
|
+
if (!this.isValidated) {
|
|
1074
|
+
return this.buildNamespaceLookup();
|
|
1075
|
+
}
|
|
1076
|
+
return this.cache.getOrAdd(`namespaceLookup`, () => {
|
|
1077
|
+
const nsLookup = this.buildNamespaceLookup();
|
|
1078
|
+
return nsLookup;
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
buildNamespaceLookup() {
|
|
1082
|
+
const namespaceLookup = new Map();
|
|
1083
|
+
for (let namespaceStatement of this._cachedLookups.namespaceStatements) {
|
|
1084
|
+
let nameParts = namespaceStatement.getNameParts();
|
|
1085
|
+
let loopName = null;
|
|
1086
|
+
let lowerLoopName = null;
|
|
1087
|
+
let parentNameLower = null;
|
|
1088
|
+
//ensure each namespace section is represented in the results
|
|
1089
|
+
//(so if the namespace name is A.B.C, this will make an entry for "A", an entry for "A.B", and an entry for "A.B.C"
|
|
1090
|
+
for (let i = 0; i < nameParts.length; i++) {
|
|
1091
|
+
let part = nameParts[i];
|
|
1092
|
+
let lowerPartName = part.text.toLowerCase();
|
|
1093
|
+
if (i === 0) {
|
|
1094
|
+
loopName = part.text;
|
|
1095
|
+
lowerLoopName = lowerPartName;
|
|
1096
|
+
}
|
|
1097
|
+
else {
|
|
1098
|
+
parentNameLower = lowerLoopName;
|
|
1099
|
+
loopName += '.' + part.text;
|
|
1100
|
+
lowerLoopName += '.' + lowerPartName;
|
|
1101
|
+
}
|
|
1102
|
+
if (!namespaceLookup.has(lowerLoopName)) {
|
|
1103
|
+
namespaceLookup.set(lowerLoopName, {
|
|
1104
|
+
isTopLevel: i === 0,
|
|
1105
|
+
file: this,
|
|
1106
|
+
fullName: loopName,
|
|
1107
|
+
fullNameLower: lowerLoopName,
|
|
1108
|
+
parentNameLower: parentNameLower,
|
|
1109
|
+
nameParts: nameParts.slice(0, i),
|
|
1110
|
+
nameRange: namespaceStatement.nameExpression.range,
|
|
1111
|
+
lastPartName: part.text,
|
|
1112
|
+
lastPartNameLower: lowerPartName,
|
|
1113
|
+
functionStatements: new Map(),
|
|
1114
|
+
namespaceStatements: [],
|
|
1115
|
+
namespaces: new Map(),
|
|
1116
|
+
classStatements: new Map(),
|
|
1117
|
+
enumStatements: new Map(),
|
|
1118
|
+
constStatements: new Map(),
|
|
1119
|
+
statements: [],
|
|
1120
|
+
// the aggregate symbol table should have no parent. It should include just the symbols of the namespace.
|
|
1121
|
+
symbolTable: new SymbolTable_1.SymbolTable(`Namespace Aggregate: '${loopName}'`)
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
let ns = namespaceLookup.get(lowerLoopName);
|
|
1126
|
+
ns.namespaceStatements.push(namespaceStatement);
|
|
1127
|
+
ns.statements.push(...namespaceStatement.body.statements);
|
|
1128
|
+
for (let statement of namespaceStatement.body.statements) {
|
|
1129
|
+
if ((0, reflection_1.isClassStatement)(statement) && statement.tokens.name) {
|
|
1130
|
+
ns.classStatements.set(statement.tokens.name.text.toLowerCase(), statement);
|
|
1131
|
+
}
|
|
1132
|
+
else if ((0, reflection_1.isFunctionStatement)(statement) && statement.tokens.name) {
|
|
1133
|
+
ns.functionStatements.set(statement.tokens.name.text.toLowerCase(), statement);
|
|
1134
|
+
}
|
|
1135
|
+
else if ((0, reflection_1.isEnumStatement)(statement) && statement.fullName) {
|
|
1136
|
+
ns.enumStatements.set(statement.fullName.toLowerCase(), statement);
|
|
1137
|
+
}
|
|
1138
|
+
else if ((0, reflection_1.isConstStatement)(statement) && statement.fullName) {
|
|
1139
|
+
ns.constStatements.set(statement.fullName.toLowerCase(), statement);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
// Merges all the symbol tables of the namespace statements into the new symbol table created above.
|
|
1143
|
+
// Set those symbol tables to have this new merged table as a parent
|
|
1144
|
+
ns.symbolTable.mergeSymbolTable(namespaceStatement.body.getSymbolTable());
|
|
1145
|
+
}
|
|
1146
|
+
return namespaceLookup;
|
|
1147
|
+
}
|
|
1203
1148
|
getTypedef() {
|
|
1204
1149
|
const state = new BrsTranspileState_1.BrsTranspileState(this);
|
|
1205
1150
|
const typedef = this.ast.getTypedef(state);
|
|
1206
|
-
const programNode =
|
|
1151
|
+
const programNode = util_1.util.sourceNodeFromTranspileResult(null, null, this.srcPath, typedef);
|
|
1207
1152
|
return programNode.toString();
|
|
1208
1153
|
}
|
|
1209
1154
|
dispose() {
|
|
1210
1155
|
var _a;
|
|
1211
1156
|
(_a = this._parser) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
1157
|
+
//deleting these properties result in lower memory usage (garbage collection is magic!)
|
|
1158
|
+
delete this.fileContents;
|
|
1159
|
+
delete this._parser;
|
|
1160
|
+
delete this._functionScopes;
|
|
1161
|
+
delete this.scopesByFunc;
|
|
1212
1162
|
}
|
|
1213
1163
|
}
|
|
1214
1164
|
exports.BrsFile = BrsFile;
|
|
1215
|
-
/**
|
|
1216
|
-
* List of completions for all valid keywords/reserved words.
|
|
1217
|
-
* Build this list once because it won't change for the lifetime of this process
|
|
1218
|
-
*/
|
|
1219
|
-
exports.KeywordCompletions = Object.keys(lexer_1.Keywords)
|
|
1220
|
-
//remove any keywords with whitespace
|
|
1221
|
-
.filter(x => !x.includes(' '))
|
|
1222
|
-
//create completions
|
|
1223
|
-
.map(x => {
|
|
1224
|
-
return {
|
|
1225
|
-
label: x,
|
|
1226
|
-
kind: vscode_languageserver_1.CompletionItemKind.Keyword
|
|
1227
|
-
};
|
|
1228
|
-
});
|
|
1229
1165
|
//# sourceMappingURL=BrsFile.js.map
|