brighterscript 1.0.0-alpha.5 → 1.0.0-alpha.50
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/README.md +76 -138
- package/bsconfig.schema.json +121 -5
- 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 +45 -0
- package/dist/AstValidationSegmenter.js +322 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +72 -39
- package/dist/BusyStatusTracker.d.ts +61 -0
- package/dist/BusyStatusTracker.js +148 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.d.ts +3 -8
- package/dist/Cache.js +9 -14
- 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 +12 -4
- package/dist/CodeActionUtil.js +22 -5
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +7 -6
- package/dist/CommentFlagProcessor.js +11 -8
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/CrossScopeValidator.d.ts +68 -0
- package/dist/CrossScopeValidator.js +642 -0
- package/dist/CrossScopeValidator.js.map +1 -0
- 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 +21 -5
- package/dist/DiagnosticCollection.js +77 -24
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +27 -6
- package/dist/DiagnosticFilterer.js +273 -60
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticManager.d.ts +82 -0
- package/dist/DiagnosticManager.js +406 -0
- package/dist/DiagnosticManager.js.map +1 -0
- package/dist/DiagnosticMessages.d.ts +558 -196
- package/dist/DiagnosticMessages.js +870 -340
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
- package/dist/DiagnosticSeverityAdjuster.js +45 -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 +100 -105
- package/dist/LanguageServer.js +444 -745
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +17 -13
- package/dist/Logger.js +64 -34
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +32 -10
- package/dist/PluginInterface.js +117 -7
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +241 -98
- package/dist/Program.js +1432 -717
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +47 -23
- package/dist/ProgramBuilder.js +224 -178
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +149 -109
- package/dist/Scope.js +557 -550
- package/dist/Scope.js.map +1 -1
- package/dist/SemanticTokenUtils.js +5 -1
- package/dist/SemanticTokenUtils.js.map +1 -1
- 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 +136 -24
- package/dist/SymbolTable.js +565 -64
- package/dist/SymbolTable.js.map +1 -1
- package/dist/SymbolTypeFlag.d.ts +9 -0
- package/dist/SymbolTypeFlag.js +14 -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 +34 -90
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +50 -0
- package/dist/astUtils/CachedLookups.js +334 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/CachedLookups.spec.js +39 -0
- package/dist/astUtils/CachedLookups.spec.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 +54 -19
- package/dist/astUtils/creators.js +242 -42
- 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 +196 -85
- package/dist/astUtils/reflection.js +497 -144
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +267 -167
- 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 +116 -53
- package/dist/astUtils/visitors.js +95 -15
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +629 -51
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -8
- package/dist/astUtils/xml.js +12 -7
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +24 -4
- package/dist/bscPlugin/BscPlugin.js +88 -4
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
- package/dist/bscPlugin/CallExpressionInfo.js +143 -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 +6 -5
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +173 -27
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +138 -21
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +65 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js +633 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +2512 -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 +212 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js +87 -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 +230 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +991 -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 +57 -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 +164 -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 +564 -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 +33 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
- package/dist/bscPlugin/serialize/BslibManager.d.ts +12 -0
- package/dist/bscPlugin/serialize/BslibManager.js +46 -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 +75 -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 +141 -0
- package/dist/bscPlugin/symbols/symbolUtils.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +27 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +418 -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 +75 -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/BrsFileAfterValidator.d.ts +7 -0
- package/dist/bscPlugin/validation/BrsFileAfterValidator.js +18 -0
- package/dist/bscPlugin/validation/BrsFileAfterValidator.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +37 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +638 -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 +1517 -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 +141 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +1323 -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 +6135 -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 +36 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
- package/dist/cli.js +126 -27
- package/dist/cli.js.map +1 -1
- package/dist/common/Sequencer.d.ts +53 -0
- package/dist/common/Sequencer.js +233 -0
- package/dist/common/Sequencer.js.map +1 -0
- package/dist/common/Sequencer.spec.d.ts +1 -0
- package/dist/common/Sequencer.spec.js +75 -0
- package/dist/common/Sequencer.spec.js.map +1 -0
- package/dist/deferred.d.ts +5 -3
- package/dist/deferred.js +10 -0
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +10 -3
- package/dist/diagnosticUtils.js +64 -25
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.d.ts +2 -2
- 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 +1213 -259
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +145 -87
- package/dist/files/BrsFile.js +836 -934
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +4226 -902
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +102 -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 +21 -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 +80 -41
- package/dist/files/XmlFile.js +161 -137
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +444 -336
- 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 +424 -184
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +32 -4
- package/dist/index.js +54 -7
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +942 -125
- package/dist/interfaces.js +21 -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 +51 -12
- package/dist/lexer/Lexer.js +215 -65
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +812 -568
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +27 -11
- package/dist/lexer/Token.js +10 -2
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +40 -2
- package/dist/lexer/TokenKind.js +147 -10
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/logging.d.ts +14 -0
- package/dist/logging.js +29 -0
- package/dist/logging.js.map +1 -0
- package/dist/lsp/ActionQueue.d.ts +35 -0
- package/dist/lsp/ActionQueue.js +115 -0
- package/dist/lsp/ActionQueue.js.map +1 -0
- package/dist/lsp/ActionQueue.spec.d.ts +1 -0
- package/dist/lsp/ActionQueue.spec.js +80 -0
- package/dist/lsp/ActionQueue.spec.js.map +1 -0
- package/dist/lsp/DocumentManager.d.ts +63 -0
- package/dist/lsp/DocumentManager.js +122 -0
- package/dist/lsp/DocumentManager.js.map +1 -0
- package/dist/lsp/DocumentManager.spec.d.ts +1 -0
- package/dist/lsp/DocumentManager.spec.js +103 -0
- package/dist/lsp/DocumentManager.spec.js.map +1 -0
- package/dist/lsp/LspProject.d.ts +239 -0
- package/dist/lsp/LspProject.js +3 -0
- package/dist/lsp/LspProject.js.map +1 -0
- package/dist/lsp/PathFilterer.d.ts +75 -0
- package/dist/lsp/PathFilterer.js +196 -0
- package/dist/lsp/PathFilterer.js.map +1 -0
- package/dist/lsp/PathFilterer.spec.d.ts +1 -0
- package/dist/lsp/PathFilterer.spec.js +182 -0
- package/dist/lsp/PathFilterer.spec.js.map +1 -0
- package/dist/lsp/Project.d.ts +168 -0
- package/dist/lsp/Project.js +437 -0
- package/dist/lsp/Project.js.map +1 -0
- package/dist/lsp/Project.spec.d.ts +1 -0
- package/dist/lsp/Project.spec.js +267 -0
- package/dist/lsp/Project.spec.js.map +1 -0
- package/dist/lsp/ProjectManager.d.ts +242 -0
- package/dist/lsp/ProjectManager.js +824 -0
- package/dist/lsp/ProjectManager.js.map +1 -0
- package/dist/lsp/ProjectManager.spec.d.ts +1 -0
- package/dist/lsp/ProjectManager.spec.js +913 -0
- package/dist/lsp/ProjectManager.spec.js.map +1 -0
- package/dist/lsp/ReaderWriterManager.d.ts +21 -0
- package/dist/lsp/ReaderWriterManager.js +60 -0
- package/dist/lsp/ReaderWriterManager.js.map +1 -0
- package/dist/lsp/worker/MessageHandler.d.ts +99 -0
- package/dist/lsp/worker/MessageHandler.js +138 -0
- package/dist/lsp/worker/MessageHandler.js.map +1 -0
- package/dist/lsp/worker/MessageHandler.spec.d.ts +1 -0
- package/dist/lsp/worker/MessageHandler.spec.js +64 -0
- package/dist/lsp/worker/MessageHandler.spec.js.map +1 -0
- package/dist/lsp/worker/WorkerPool.d.ts +38 -0
- package/dist/lsp/worker/WorkerPool.js +78 -0
- package/dist/lsp/worker/WorkerPool.js.map +1 -0
- package/dist/lsp/worker/WorkerPool.spec.d.ts +1 -0
- package/dist/lsp/worker/WorkerPool.spec.js +59 -0
- package/dist/lsp/worker/WorkerPool.spec.js.map +1 -0
- package/dist/lsp/worker/WorkerThreadProject.d.ts +143 -0
- package/dist/lsp/worker/WorkerThreadProject.js +189 -0
- package/dist/lsp/worker/WorkerThreadProject.js.map +1 -0
- package/dist/lsp/worker/WorkerThreadProject.spec.d.ts +2 -0
- package/dist/lsp/worker/WorkerThreadProject.spec.js +71 -0
- package/dist/lsp/worker/WorkerThreadProject.spec.js.map +1 -0
- package/dist/lsp/worker/WorkerThreadProjectRunner.d.ts +15 -0
- package/dist/lsp/worker/WorkerThreadProjectRunner.js +58 -0
- package/dist/lsp/worker/WorkerThreadProjectRunner.js.map +1 -0
- package/dist/lsp/worker/run.d.ts +1 -0
- package/dist/lsp/worker/run.js +14 -0
- package/dist/lsp/worker/run.js.map +1 -0
- package/dist/parser/AstNode.d.ts +203 -0
- package/dist/parser/AstNode.js +303 -0
- package/dist/parser/AstNode.js.map +1 -0
- package/dist/parser/AstNode.spec.d.ts +1 -0
- package/dist/parser/AstNode.spec.js +1455 -0
- package/dist/parser/AstNode.spec.js.map +1 -0
- package/dist/parser/BrightScriptDocParser.d.ts +56 -0
- package/dist/parser/BrightScriptDocParser.js +294 -0
- package/dist/parser/BrightScriptDocParser.js.map +1 -0
- package/dist/parser/BrightScriptDocParser.spec.d.ts +1 -0
- package/dist/parser/BrightScriptDocParser.spec.js +310 -0
- package/dist/parser/BrightScriptDocParser.spec.js.map +1 -0
- package/dist/parser/BrsTranspileState.d.ts +22 -3
- package/dist/parser/BrsTranspileState.js +19 -0
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +553 -221
- package/dist/parser/Expression.js +1414 -505
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Expression.spec.d.ts +1 -0
- package/dist/parser/Expression.spec.js +40 -0
- package/dist/parser/Expression.spec.js.map +1 -0
- package/dist/parser/Parser.Class.spec.js +255 -125
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +117 -124
- package/dist/parser/Parser.js +1669 -982
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +2111 -525
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +29 -13
- package/dist/parser/SGParser.js +85 -56
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +30 -45
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +134 -46
- package/dist/parser/SGTypes.js +206 -115
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +849 -267
- package/dist/parser/Statement.js +2412 -625
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +133 -36
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +26 -12
- package/dist/parser/TranspileState.js +115 -24
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.d.ts +3 -9
- package/dist/parser/tests/Parser.spec.js +7 -13
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +83 -75
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +85 -51
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +382 -239
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +52 -45
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +51 -43
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +192 -142
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +236 -160
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +41 -34
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +173 -55
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +20 -20
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +291 -282
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +193 -110
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +42 -42
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +260 -115
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +58 -52
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +76 -60
- 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 +50 -50
- 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 +281 -94
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +747 -192
- 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 +44 -44
- 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 +500 -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 +61 -55
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +29 -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 +744 -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 +226 -215
- 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 +64 -61
- 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 +110 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/LibraryStatement.spec.js +22 -22
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +127 -168
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +133 -114
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +57 -54
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +131 -117
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +14 -13
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +11 -8
- 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 +20347 -0
- package/dist/roku-types/index.d.ts +5726 -0
- package/dist/roku-types/index.js +11 -0
- package/dist/roku-types/index.js.map +1 -0
- package/dist/types/ArrayType.d.ts +12 -5
- package/dist/types/ArrayType.js +89 -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 +15 -0
- package/dist/types/AssociativeArrayType.js +64 -0
- package/dist/types/AssociativeArrayType.js.map +1 -0
- package/dist/types/BaseFunctionType.d.ts +10 -0
- package/dist/types/BaseFunctionType.js +26 -0
- package/dist/types/BaseFunctionType.js.map +1 -0
- package/dist/types/BooleanType.d.ts +9 -5
- package/dist/types/BooleanType.js +19 -8
- 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 +41 -3
- package/dist/types/BscType.js +152 -0
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BscTypeKind.d.ts +28 -0
- package/dist/types/BscTypeKind.js +33 -0
- package/dist/types/BscTypeKind.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.d.ts +28 -0
- package/dist/types/BuiltInInterfaceAdder.js +212 -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/CallFuncableType.d.ts +24 -0
- package/dist/types/CallFuncableType.js +91 -0
- package/dist/types/CallFuncableType.js.map +1 -0
- package/dist/types/ClassType.d.ts +17 -0
- package/dist/types/ClassType.js +60 -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 +22 -0
- package/dist/types/ComponentType.js +107 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +10 -5
- package/dist/types/DoubleType.js +21 -17
- 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 +13 -5
- package/dist/types/DynamicType.js +26 -5
- 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 +42 -0
- package/dist/types/EnumType.js +98 -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 +21 -17
- 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 +8 -22
- package/dist/types/FunctionType.js +25 -63
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +29 -0
- package/dist/types/InheritableType.js +173 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/InlineInterfaceType.d.ts +5 -0
- package/dist/types/InlineInterfaceType.js +17 -0
- package/dist/types/InlineInterfaceType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +10 -5
- package/dist/types/IntegerType.js +21 -17
- 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 +30 -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/IntersectionType.d.ts +29 -0
- package/dist/types/IntersectionType.js +253 -0
- package/dist/types/IntersectionType.js.map +1 -0
- package/dist/types/IntersectionType.spec.d.ts +1 -0
- package/dist/types/IntersectionType.spec.js +150 -0
- package/dist/types/IntersectionType.spec.js.map +1 -0
- package/dist/types/InvalidType.d.ts +10 -5
- package/dist/types/InvalidType.js +21 -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 +21 -17
- 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 +12 -5
- package/dist/types/ObjectType.js +25 -8
- 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 +123 -0
- package/dist/types/ReferenceType.js +720 -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 +12 -5
- package/dist/types/StringType.js +23 -8
- 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/TypeStatementType.d.ts +18 -0
- package/dist/types/TypeStatementType.js +45 -0
- package/dist/types/TypeStatementType.js.map +1 -0
- package/dist/types/TypedFunctionType.d.ts +34 -0
- package/dist/types/TypedFunctionType.js +147 -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 +11 -6
- package/dist/types/UninitializedType.js +20 -11
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +27 -0
- package/dist/types/UnionType.js +193 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +205 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +11 -5
- package/dist/types/VoidType.js +22 -8
- 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 +174 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +51 -0
- package/dist/types/helpers.js +323 -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/types/roFunctionType.d.ts +11 -0
- package/dist/types/roFunctionType.js +37 -0
- package/dist/types/roFunctionType.js.map +1 -0
- package/dist/types/roFunctionType.spec.d.ts +1 -0
- package/dist/types/roFunctionType.spec.js +20 -0
- package/dist/types/roFunctionType.spec.js.map +1 -0
- package/dist/util.d.ts +288 -187
- package/dist/util.js +2018 -575
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +9 -15
- package/dist/validators/ClassValidator.js +93 -138
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +185 -138
- package/CHANGELOG.md +0 -1188
- 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/bscPlugin/semanticTokens/SemanticTokensProcessor.d.ts +0 -7
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +0 -63
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +0 -1
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js +0 -45
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.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/SGTypes.spec.js +0 -351
- package/dist/parser/SGTypes.spec.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/{bscPlugin/semanticTokens/SemanticTokensProcessor.spec.d.ts → astUtils/CachedLookups.spec.d.ts} +0 -0
- /package/dist/{parser/SGTypes.spec.d.ts → astUtils/Editor.spec.d.ts} +0 -0
- /package/dist/{preprocessor/Preprocessor.spec.d.ts → bscPlugin/completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{preprocessor/PreprocessorParser.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
- /package/dist/{types/FunctionType.spec.d.ts → bscPlugin/hover/HoverProcessor.spec.d.ts} +0 -0
package/dist/util.js
CHANGED
|
@@ -5,35 +5,73 @@ const fs = require("fs");
|
|
|
5
5
|
const fsExtra = require("fs-extra");
|
|
6
6
|
const jsonc_parser_1 = require("jsonc-parser");
|
|
7
7
|
const path = require("path");
|
|
8
|
-
const
|
|
8
|
+
const roku_deploy_1 = require("roku-deploy");
|
|
9
|
+
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
9
10
|
const vscode_uri_1 = require("vscode-uri");
|
|
10
|
-
const xml2js = require("xml2js");
|
|
11
11
|
const DiagnosticMessages_1 = require("./DiagnosticMessages");
|
|
12
|
+
const interfaces_1 = require("./interfaces");
|
|
12
13
|
const BooleanType_1 = require("./types/BooleanType");
|
|
13
14
|
const DoubleType_1 = require("./types/DoubleType");
|
|
14
15
|
const DynamicType_1 = require("./types/DynamicType");
|
|
15
16
|
const FloatType_1 = require("./types/FloatType");
|
|
16
|
-
const FunctionType_1 = require("./types/FunctionType");
|
|
17
17
|
const IntegerType_1 = require("./types/IntegerType");
|
|
18
|
-
const InvalidType_1 = require("./types/InvalidType");
|
|
19
18
|
const LongIntegerType_1 = require("./types/LongIntegerType");
|
|
20
19
|
const ObjectType_1 = require("./types/ObjectType");
|
|
21
20
|
const StringType_1 = require("./types/StringType");
|
|
22
21
|
const VoidType_1 = require("./types/VoidType");
|
|
23
22
|
const Parser_1 = require("./parser/Parser");
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
23
|
+
const logging_1 = require("./logging");
|
|
24
|
+
const Token_1 = require("./lexer/Token");
|
|
25
|
+
const TokenKind_1 = require("./lexer/TokenKind");
|
|
26
|
+
const reflection_1 = require("./astUtils/reflection");
|
|
27
|
+
const visitors_1 = require("./astUtils/visitors");
|
|
28
28
|
const source_map_1 = require("source-map");
|
|
29
|
-
const
|
|
29
|
+
const requireRelative = require("require-relative");
|
|
30
|
+
const AstNode_1 = require("./parser/AstNode");
|
|
31
|
+
const creators_1 = require("./astUtils/creators");
|
|
32
|
+
const diagnosticUtils_1 = require("./diagnosticUtils");
|
|
33
|
+
const UnionType_1 = require("./types/UnionType");
|
|
34
|
+
const ArrayType_1 = require("./types/ArrayType");
|
|
35
|
+
const ReferenceType_1 = require("./types/ReferenceType");
|
|
36
|
+
const AssociativeArrayType_1 = require("./types/AssociativeArrayType");
|
|
37
|
+
const ComponentType_1 = require("./types/ComponentType");
|
|
38
|
+
const FunctionType_1 = require("./types/FunctionType");
|
|
39
|
+
const helpers_1 = require("./types/helpers");
|
|
40
|
+
const InvalidType_1 = require("./types/InvalidType");
|
|
41
|
+
const types_1 = require("./types");
|
|
42
|
+
const IntersectionType_1 = require("./types/IntersectionType");
|
|
30
43
|
class Util {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.isWindows = process.platform === 'win32';
|
|
46
|
+
this.standardizePathCache = new Map();
|
|
47
|
+
}
|
|
31
48
|
clearConsole() {
|
|
32
49
|
// process.stdout.write('\x1Bc');
|
|
33
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the version of brighterscript
|
|
53
|
+
*/
|
|
54
|
+
getBrighterScriptVersion() {
|
|
55
|
+
try {
|
|
56
|
+
return fsExtra.readJsonSync(`${__dirname}/../package.json`).version;
|
|
57
|
+
}
|
|
58
|
+
catch (_a) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns the number of parent directories in the filPath
|
|
64
|
+
*/
|
|
65
|
+
getParentDirectoryCount(filePath) {
|
|
66
|
+
if (!filePath) {
|
|
67
|
+
return -1;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return filePath.replace(/^pkg:/, '').split(/[\\\/]/).length - 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
34
73
|
/**
|
|
35
74
|
* Determine if the file exists
|
|
36
|
-
* @param filePath
|
|
37
75
|
*/
|
|
38
76
|
async pathExists(filePath) {
|
|
39
77
|
if (!filePath) {
|
|
@@ -45,7 +83,6 @@ class Util {
|
|
|
45
83
|
}
|
|
46
84
|
/**
|
|
47
85
|
* Determine if the file exists
|
|
48
|
-
* @param filePath
|
|
49
86
|
*/
|
|
50
87
|
pathExistsSync(filePath) {
|
|
51
88
|
if (!filePath) {
|
|
@@ -59,40 +96,39 @@ class Util {
|
|
|
59
96
|
* Determine if this path is a directory
|
|
60
97
|
*/
|
|
61
98
|
isDirectorySync(dirPath) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
sanitizePkgPath(pkgPath) {
|
|
68
|
-
pkgPath = pkgPath.replace(/\\/g, '/');
|
|
69
|
-
//if there's no protocol, assume it's supposed to start with `pkg:/`
|
|
70
|
-
if (!this.startsWithProtocol(pkgPath)) {
|
|
71
|
-
pkgPath = 'pkg:/' + pkgPath;
|
|
99
|
+
try {
|
|
100
|
+
return dirPath !== undefined && fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
return false;
|
|
72
104
|
}
|
|
73
|
-
return pkgPath;
|
|
74
105
|
}
|
|
75
106
|
/**
|
|
76
|
-
*
|
|
107
|
+
* Read a file from disk. If a failure occurrs, simply return undefined
|
|
108
|
+
* @param filePath path to the file
|
|
109
|
+
* @returns the string contents, or undefined if the file doesn't exist
|
|
77
110
|
*/
|
|
78
|
-
|
|
79
|
-
|
|
111
|
+
readFileSync(filePath) {
|
|
112
|
+
try {
|
|
113
|
+
return fsExtra.readFileSync(filePath);
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
80
118
|
}
|
|
81
119
|
/**
|
|
82
|
-
* Given a path
|
|
83
|
-
* @param filePath
|
|
120
|
+
* Given a pkg path of any kind, transform it to a roku-specific pkg path (i.e. "pkg:/some/path.brs")
|
|
84
121
|
*/
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return filePath.replace(/[\\/]+/g, separator);
|
|
122
|
+
sanitizePkgPath(pkgPath) {
|
|
123
|
+
//convert all slashes to forwardslash
|
|
124
|
+
pkgPath = pkgPath.replace(/[\/\\]+/g, '/');
|
|
125
|
+
//ensure every path has the leading pkg:/
|
|
126
|
+
return 'pkg:/' + pkgPath.replace(/^pkg:\//i, '');
|
|
91
127
|
}
|
|
92
128
|
/**
|
|
93
129
|
* Find the path to the config file.
|
|
94
130
|
* If the config file path doesn't exist
|
|
95
|
-
* @param
|
|
131
|
+
* @param cwd the current working directory where the search for configs should begin
|
|
96
132
|
*/
|
|
97
133
|
getConfigFilePath(cwd) {
|
|
98
134
|
cwd = cwd !== null && cwd !== void 0 ? cwd : process.cwd();
|
|
@@ -126,15 +162,16 @@ class Util {
|
|
|
126
162
|
colIndex++;
|
|
127
163
|
}
|
|
128
164
|
}
|
|
129
|
-
return
|
|
165
|
+
return exports.util.createRange(lineIndex, colIndex, lineIndex, colIndex + length);
|
|
130
166
|
}
|
|
131
167
|
/**
|
|
132
168
|
* Load the contents of a config file.
|
|
133
169
|
* If the file extends another config, this will load the base config as well.
|
|
134
|
-
* @param configFilePath
|
|
135
|
-
* @param parentProjectPaths
|
|
170
|
+
* @param configFilePath the relative or absolute path to a brighterscript config json file
|
|
171
|
+
* @param parentProjectPaths a list of parent config files. This is used by this method to recursively build the config list
|
|
136
172
|
*/
|
|
137
173
|
loadConfigFile(configFilePath, parentProjectPaths, cwd = process.cwd()) {
|
|
174
|
+
var _a;
|
|
138
175
|
if (configFilePath) {
|
|
139
176
|
//if the config file path starts with question mark, then it's optional. return undefined if it doesn't exist
|
|
140
177
|
if (configFilePath.startsWith('?')) {
|
|
@@ -155,16 +192,24 @@ class Util {
|
|
|
155
192
|
//load the project file
|
|
156
193
|
let projectFileContents = fsExtra.readFileSync(configFilePath).toString();
|
|
157
194
|
let parseErrors = [];
|
|
158
|
-
let projectConfig = jsonc_parser_1.parse(projectFileContents, parseErrors
|
|
195
|
+
let projectConfig = (_a = (0, jsonc_parser_1.parse)(projectFileContents, parseErrors, {
|
|
196
|
+
allowEmptyContent: true,
|
|
197
|
+
allowTrailingComma: true,
|
|
198
|
+
disallowComments: false
|
|
199
|
+
})) !== null && _a !== void 0 ? _a : {};
|
|
159
200
|
if (parseErrors.length > 0) {
|
|
160
201
|
let err = parseErrors[0];
|
|
161
|
-
let diagnostic = Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
162
|
-
|
|
163
|
-
|
|
202
|
+
let diagnostic = Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.syntaxError(`Syntax errors in bsconfig.json: ${(0, jsonc_parser_1.printParseErrorCode)(parseErrors[0].error)}`)), { location: {
|
|
203
|
+
uri: this.pathToUri(configFilePath),
|
|
204
|
+
range: this.getRangeFromOffsetLength(projectFileContents, err.offset, err.length)
|
|
205
|
+
} });
|
|
164
206
|
throw diagnostic; //eslint-disable-line @typescript-eslint/no-throw-literal
|
|
165
207
|
}
|
|
166
|
-
this.resolvePluginPaths(projectConfig, configFilePath);
|
|
167
208
|
let projectFileCwd = path.dirname(configFilePath);
|
|
209
|
+
//`plugins` paths should be relative to the current bsconfig
|
|
210
|
+
this.resolvePathsRelativeTo(projectConfig, 'plugins', projectFileCwd);
|
|
211
|
+
//`require` paths should be relative to cwd
|
|
212
|
+
exports.util.resolvePathsRelativeTo(projectConfig, 'require', projectFileCwd);
|
|
168
213
|
let result;
|
|
169
214
|
//if the project has a base file, load it
|
|
170
215
|
if (projectConfig && typeof projectConfig.extends === 'string') {
|
|
@@ -179,75 +224,50 @@ class Util {
|
|
|
179
224
|
result._ancestors = parentProjectPaths;
|
|
180
225
|
}
|
|
181
226
|
//make any paths in the config absolute (relative to the CURRENT config file)
|
|
182
|
-
if (result.outFile) {
|
|
183
|
-
result.outFile = path.resolve(projectFileCwd, result.outFile);
|
|
184
|
-
}
|
|
185
227
|
if (result.rootDir) {
|
|
186
228
|
result.rootDir = path.resolve(projectFileCwd, result.rootDir);
|
|
187
229
|
}
|
|
230
|
+
if (result.outDir) {
|
|
231
|
+
result.outDir = path.resolve(projectFileCwd, result.outDir);
|
|
232
|
+
}
|
|
188
233
|
if (result.cwd) {
|
|
189
234
|
result.cwd = path.resolve(projectFileCwd, result.cwd);
|
|
190
235
|
}
|
|
236
|
+
if (result.sourceRoot && result.resolveSourceRoot) {
|
|
237
|
+
result.sourceRoot = path.resolve(projectFileCwd, result.sourceRoot);
|
|
238
|
+
}
|
|
191
239
|
return result;
|
|
192
240
|
}
|
|
193
241
|
}
|
|
194
242
|
/**
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* @param config
|
|
198
|
-
* @param
|
|
243
|
+
* Convert relative paths to absolute paths, relative to the given directory. Also de-dupes the paths. Modifies the array in-place
|
|
244
|
+
* @param collection usually a bsconfig.
|
|
245
|
+
* @param key a key of the config to read paths from (usually this is `'plugins'` or `'require'`)
|
|
246
|
+
* @param relativeDir the path to the folder where the paths should be resolved relative to. This should be an absolute path
|
|
199
247
|
*/
|
|
200
|
-
|
|
248
|
+
resolvePathsRelativeTo(collection, key, relativeDir) {
|
|
201
249
|
var _a;
|
|
202
|
-
if (
|
|
203
|
-
|
|
204
|
-
const exists = {};
|
|
205
|
-
config.plugins = config.plugins.map(p => {
|
|
206
|
-
return (p === null || p === void 0 ? void 0 : p.startsWith('.')) ? path.resolve(relPath, p) : p;
|
|
207
|
-
}).filter(p => {
|
|
208
|
-
if (!p || exists[p]) {
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
211
|
-
exists[p] = true;
|
|
212
|
-
return true;
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Do work within the scope of a changed current working directory
|
|
218
|
-
* @param targetCwd
|
|
219
|
-
* @param callback
|
|
220
|
-
*/
|
|
221
|
-
cwdWork(targetCwd, callback) {
|
|
222
|
-
let originalCwd = process.cwd();
|
|
223
|
-
if (targetCwd) {
|
|
224
|
-
process.chdir(targetCwd);
|
|
225
|
-
}
|
|
226
|
-
let result;
|
|
227
|
-
let err;
|
|
228
|
-
try {
|
|
229
|
-
result = callback();
|
|
230
|
-
}
|
|
231
|
-
catch (e) {
|
|
232
|
-
err = e;
|
|
233
|
-
}
|
|
234
|
-
if (targetCwd) {
|
|
235
|
-
process.chdir(originalCwd);
|
|
250
|
+
if (!collection[key]) {
|
|
251
|
+
return;
|
|
236
252
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
253
|
+
const result = new Set();
|
|
254
|
+
for (const p of (_a = collection[key]) !== null && _a !== void 0 ? _a : []) {
|
|
255
|
+
if (p) {
|
|
256
|
+
result.add((p === null || p === void 0 ? void 0 : p.startsWith('.')) ? path.resolve(relativeDir, p) : p);
|
|
257
|
+
}
|
|
242
258
|
}
|
|
259
|
+
collection[key] = [...result];
|
|
243
260
|
}
|
|
244
261
|
/**
|
|
245
262
|
* Given a BsConfig object, start with defaults,
|
|
246
263
|
* merge with bsconfig.json and the provided options.
|
|
247
|
-
* @param config
|
|
264
|
+
* @param config a bsconfig object to use as the baseline for the resulting config
|
|
248
265
|
*/
|
|
249
266
|
normalizeAndResolveConfig(config) {
|
|
250
|
-
let result = this.normalizeConfig({});
|
|
267
|
+
let result = this.normalizeConfig(Object.assign({}, config));
|
|
268
|
+
if (config === null || config === void 0 ? void 0 : config.noProject) {
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
251
271
|
//if no options were provided, try to find a bsconfig.json file
|
|
252
272
|
if (!config || !config.project) {
|
|
253
273
|
result.project = this.getConfigFilePath(config === null || config === void 0 ? void 0 : config.cwd);
|
|
@@ -257,7 +277,7 @@ class Util {
|
|
|
257
277
|
result.project = config.project;
|
|
258
278
|
}
|
|
259
279
|
if (result.project) {
|
|
260
|
-
let configFile = this.loadConfigFile(result.project,
|
|
280
|
+
let configFile = this.loadConfigFile(result.project, undefined, config === null || config === void 0 ? void 0 : config.cwd);
|
|
261
281
|
result = Object.assign(result, configFile);
|
|
262
282
|
}
|
|
263
283
|
//override the defaults with the specified options
|
|
@@ -266,42 +286,79 @@ class Util {
|
|
|
266
286
|
}
|
|
267
287
|
/**
|
|
268
288
|
* Set defaults for any missing items
|
|
269
|
-
* @param config
|
|
289
|
+
* @param config a bsconfig object to use as the baseline for the resulting config
|
|
270
290
|
*/
|
|
271
291
|
normalizeConfig(config) {
|
|
272
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
273
|
-
config = config
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
config.files = (_a = config.files) !== null && _a !== void 0 ? _a : rokuDeploy.getOptions().files;
|
|
277
|
-
config.createPackage = config.createPackage === false ? false : true;
|
|
278
|
-
let rootFolderName = path.basename(process.cwd());
|
|
279
|
-
config.outFile = (_b = config.outFile) !== null && _b !== void 0 ? _b : `./out/${rootFolderName}.zip`;
|
|
280
|
-
config.sourceMap = config.sourceMap === true;
|
|
281
|
-
config.username = (_c = config.username) !== null && _c !== void 0 ? _c : 'rokudev';
|
|
282
|
-
config.watch = config.watch === true ? true : false;
|
|
283
|
-
config.emitFullPaths = config.emitFullPaths === true ? true : false;
|
|
284
|
-
config.retainStagingFolder = config.retainStagingFolder === true ? true : false;
|
|
285
|
-
config.copyToStaging = config.copyToStaging === false ? false : true;
|
|
286
|
-
config.ignoreErrorCodes = (_d = config.ignoreErrorCodes) !== null && _d !== void 0 ? _d : [];
|
|
287
|
-
config.diagnosticFilters = (_e = config.diagnosticFilters) !== null && _e !== void 0 ? _e : [];
|
|
288
|
-
config.plugins = (_f = config.plugins) !== null && _f !== void 0 ? _f : [];
|
|
289
|
-
config.autoImportComponentScript = config.autoImportComponentScript === true ? true : false;
|
|
290
|
-
config.showDiagnosticsInConsole = config.showDiagnosticsInConsole === false ? false : true;
|
|
291
|
-
config.sourceRoot = config.sourceRoot ? standardizePath(config.sourceRoot) : undefined;
|
|
292
|
-
config.cwd = (_g = config.cwd) !== null && _g !== void 0 ? _g : process.cwd();
|
|
293
|
-
config.emitDefinitions = config.emitDefinitions === true ? true : false;
|
|
292
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
293
|
+
config = config !== null && config !== void 0 ? config : {};
|
|
294
|
+
const cwd = (_a = config.cwd) !== null && _a !== void 0 ? _a : process.cwd();
|
|
295
|
+
let logLevel = logging_1.LogLevel.log;
|
|
294
296
|
if (typeof config.logLevel === 'string') {
|
|
295
|
-
|
|
297
|
+
logLevel = (_b = logging_1.LogLevel[config.logLevel.toLowerCase()]) !== null && _b !== void 0 ? _b : logging_1.LogLevel.log;
|
|
298
|
+
}
|
|
299
|
+
let bslibDestinationDir = (_c = config.bslibDestinationDir) !== null && _c !== void 0 ? _c : 'source';
|
|
300
|
+
if (bslibDestinationDir !== 'source') {
|
|
301
|
+
// strip leading and trailing slashes
|
|
302
|
+
bslibDestinationDir = bslibDestinationDir.replace(/^(\/*)(.*?)(\/*)$/, '$2');
|
|
303
|
+
}
|
|
304
|
+
let noEmit;
|
|
305
|
+
if ('noEmit' in config) {
|
|
306
|
+
noEmit = config.noEmit;
|
|
296
307
|
}
|
|
297
|
-
|
|
298
|
-
|
|
308
|
+
else if ('copyToStaging' in config) {
|
|
309
|
+
noEmit = !config.copyToStaging; //invert the old value
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
noEmit = false; //default case
|
|
313
|
+
}
|
|
314
|
+
let outDir;
|
|
315
|
+
if ('outDir' in config) {
|
|
316
|
+
outDir = (_d = config.outDir) !== null && _d !== void 0 ? _d : './out';
|
|
317
|
+
}
|
|
318
|
+
else if ('stagingFolderPath' in config) {
|
|
319
|
+
outDir = config.stagingFolderPath;
|
|
320
|
+
}
|
|
321
|
+
else if ('stagingDir' in config) {
|
|
322
|
+
outDir = config.stagingDir;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
outDir = './out'; //default case
|
|
326
|
+
}
|
|
327
|
+
const configWithDefaults = {
|
|
328
|
+
cwd: cwd,
|
|
329
|
+
//use default files array from rokuDeploy
|
|
330
|
+
files: (_e = config.files) !== null && _e !== void 0 ? _e : [...roku_deploy_1.DefaultFiles],
|
|
331
|
+
outDir: outDir,
|
|
332
|
+
sourceMap: config.sourceMap === true,
|
|
333
|
+
watch: config.watch === true ? true : false,
|
|
334
|
+
emitFullPaths: config.emitFullPaths === true ? true : false,
|
|
335
|
+
noEmit: noEmit,
|
|
336
|
+
ignoreErrorCodes: (_f = config.ignoreErrorCodes) !== null && _f !== void 0 ? _f : [],
|
|
337
|
+
diagnosticSeverityOverrides: (_g = config.diagnosticSeverityOverrides) !== null && _g !== void 0 ? _g : {},
|
|
338
|
+
diagnosticFilters: (_h = config.diagnosticFilters) !== null && _h !== void 0 ? _h : [],
|
|
339
|
+
diagnosticFiltersV0Compatibility: config.diagnosticFiltersV0Compatibility === true ? true : false,
|
|
340
|
+
plugins: (_j = config.plugins) !== null && _j !== void 0 ? _j : [],
|
|
341
|
+
pruneEmptyCodeFiles: config.pruneEmptyCodeFiles === true ? true : false,
|
|
342
|
+
autoImportComponentScript: config.autoImportComponentScript === true ? true : false,
|
|
343
|
+
showDiagnosticsInConsole: config.showDiagnosticsInConsole === false ? false : true,
|
|
344
|
+
sourceRoot: config.sourceRoot ? standardizePath(config.sourceRoot) : undefined,
|
|
345
|
+
resolveSourceRoot: config.resolveSourceRoot === true ? true : false,
|
|
346
|
+
allowBrighterScriptInBrightScript: config.allowBrighterScriptInBrightScript === true ? true : false,
|
|
347
|
+
emitDefinitions: config.emitDefinitions === true ? true : false,
|
|
348
|
+
removeParameterTypes: config.removeParameterTypes === true ? true : false,
|
|
349
|
+
logLevel: logLevel,
|
|
350
|
+
bslibDestinationDir: bslibDestinationDir,
|
|
351
|
+
legacyCallfuncHandling: config.legacyCallfuncHandling === true ? true : false
|
|
352
|
+
};
|
|
353
|
+
//mutate `config` in case anyone is holding a reference to the incomplete one
|
|
354
|
+
const merged = Object.assign(config, configWithDefaults);
|
|
355
|
+
return merged;
|
|
299
356
|
}
|
|
300
357
|
/**
|
|
301
358
|
* Get the root directory from options.
|
|
302
359
|
* Falls back to options.cwd.
|
|
303
360
|
* Falls back to process.cwd
|
|
304
|
-
* @param options
|
|
361
|
+
* @param options a bsconfig object
|
|
305
362
|
*/
|
|
306
363
|
getRootDir(options) {
|
|
307
364
|
if (!options) {
|
|
@@ -313,19 +370,8 @@ class Util {
|
|
|
313
370
|
rootDir = path.resolve(cwd, rootDir);
|
|
314
371
|
return rootDir;
|
|
315
372
|
}
|
|
316
|
-
/**
|
|
317
|
-
* Format a string with placeholders replaced by argument indexes
|
|
318
|
-
* @param subject
|
|
319
|
-
* @param params
|
|
320
|
-
*/
|
|
321
|
-
stringFormat(subject, ...args) {
|
|
322
|
-
return subject.replace(/{(\d+)}/g, (match, num) => {
|
|
323
|
-
return typeof args[num] !== 'undefined' ? args[num] : match;
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
373
|
/**
|
|
327
374
|
* Given a list of callables as a dictionary indexed by their full name (namespace included, transpiled to underscore-separated.
|
|
328
|
-
* @param callables
|
|
329
375
|
*/
|
|
330
376
|
getCallableContainersByLowerName(callables) {
|
|
331
377
|
//find duplicate functions
|
|
@@ -344,33 +390,34 @@ class Util {
|
|
|
344
390
|
return result;
|
|
345
391
|
}
|
|
346
392
|
/**
|
|
347
|
-
*
|
|
348
|
-
*
|
|
393
|
+
* Given an absolute path to a source file, and a target path,
|
|
394
|
+
* compute the pkg path for the target relative to the source file's location
|
|
349
395
|
*/
|
|
350
|
-
|
|
351
|
-
return text.split(/\r?\n/);
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Compute the pkg path for the target relative to the source file's location
|
|
355
|
-
* @param sourcePkgPath The pkgPath of the file that contains the target path
|
|
356
|
-
* @param targetPath a full pkgPath, or a path relative to the containing file
|
|
357
|
-
*/
|
|
358
|
-
getPkgPathFromTarget(sourcePkgPath, targetPath) {
|
|
396
|
+
getPkgPathFromTarget(containingFilePathAbsolute, targetPath) {
|
|
359
397
|
var _a;
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
398
|
+
// https://regex101.com/r/w7CG2N/1
|
|
399
|
+
const regexp = /^(?:pkg|libpkg):(\/)?/i;
|
|
400
|
+
const [fullScheme, slash] = (_a = regexp.exec(targetPath)) !== null && _a !== void 0 ? _a : [];
|
|
401
|
+
//if the target starts with 'pkg:' or 'libpkg:' then it's an absolute path. Return as is
|
|
402
|
+
if (slash) {
|
|
403
|
+
targetPath = targetPath.substring(fullScheme.length);
|
|
404
|
+
if (targetPath === '') {
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
return path.normalize(targetPath);
|
|
409
|
+
}
|
|
364
410
|
}
|
|
365
|
-
//if the
|
|
366
|
-
if (
|
|
367
|
-
return
|
|
411
|
+
//if the path is exactly `pkg:` or `libpkg:`
|
|
412
|
+
if (targetPath === fullScheme && !slash) {
|
|
413
|
+
return null;
|
|
368
414
|
}
|
|
415
|
+
//remove the filename
|
|
416
|
+
let containingFolder = path.normalize(path.dirname(containingFilePathAbsolute));
|
|
369
417
|
//start with the containing folder, split by slash
|
|
370
|
-
|
|
371
|
-
let result = containingFolder.split(/[\\/]/);
|
|
418
|
+
let result = containingFolder.split(path.sep);
|
|
372
419
|
//split on slash
|
|
373
|
-
let targetParts = path.
|
|
420
|
+
let targetParts = path.normalize(targetPath).split(path.sep);
|
|
374
421
|
for (let part of targetParts) {
|
|
375
422
|
if (part === '' || part === '.') {
|
|
376
423
|
//do nothing, it means current directory
|
|
@@ -384,19 +431,19 @@ class Util {
|
|
|
384
431
|
result.push(part);
|
|
385
432
|
}
|
|
386
433
|
}
|
|
387
|
-
return result.join(
|
|
434
|
+
return result.join(path.sep);
|
|
388
435
|
}
|
|
389
436
|
/**
|
|
390
437
|
* Compute the relative path from the source file to the target file
|
|
391
|
-
* @param
|
|
392
|
-
* @param
|
|
438
|
+
* @param pkgSrcPath - the absolute path to the source, where cwd is the package location
|
|
439
|
+
* @param pkgTargetPath - the absolute path to the target, where cwd is the package location
|
|
393
440
|
*/
|
|
394
|
-
getRelativePath(
|
|
395
|
-
|
|
396
|
-
|
|
441
|
+
getRelativePath(pkgSrcPath, pkgTargetPath) {
|
|
442
|
+
pkgSrcPath = path.normalize(pkgSrcPath);
|
|
443
|
+
pkgTargetPath = path.normalize(pkgTargetPath);
|
|
397
444
|
//break by path separator
|
|
398
|
-
let sourceParts =
|
|
399
|
-
let targetParts =
|
|
445
|
+
let sourceParts = pkgSrcPath.split(path.sep);
|
|
446
|
+
let targetParts = pkgTargetPath.split(path.sep);
|
|
400
447
|
let commonParts = [];
|
|
401
448
|
//find their common root
|
|
402
449
|
for (let i = 0; i < targetParts.length; i++) {
|
|
@@ -419,16 +466,26 @@ class Util {
|
|
|
419
466
|
resultParts = [...resultParts, ...targetParts];
|
|
420
467
|
return path.join(...resultParts);
|
|
421
468
|
}
|
|
469
|
+
getImportPackagePath(srcPath, pkgTargetPath) {
|
|
470
|
+
const srcExt = this.getExtension(srcPath);
|
|
471
|
+
const lowerSrcExt = srcExt.toLowerCase();
|
|
472
|
+
const lowerTargetExt = this.getExtension(pkgTargetPath).toLowerCase();
|
|
473
|
+
if (lowerSrcExt === '.bs' && lowerTargetExt === '.brs') {
|
|
474
|
+
// if source is .bs, use that as the import extenstion
|
|
475
|
+
return pkgTargetPath.substring(0, pkgTargetPath.length - lowerTargetExt.length) + srcExt;
|
|
476
|
+
}
|
|
477
|
+
return pkgTargetPath;
|
|
478
|
+
}
|
|
422
479
|
/**
|
|
423
480
|
* Walks left in a DottedGetExpression and returns a VariableExpression if found, or undefined if not found
|
|
424
481
|
*/
|
|
425
482
|
findBeginningVariableExpression(dottedGet) {
|
|
426
483
|
let left = dottedGet;
|
|
427
484
|
while (left) {
|
|
428
|
-
if (
|
|
485
|
+
if ((0, reflection_1.isVariableExpression)(left)) {
|
|
429
486
|
return left;
|
|
430
487
|
}
|
|
431
|
-
else if (
|
|
488
|
+
else if ((0, reflection_1.isDottedGetExpression)(left)) {
|
|
432
489
|
left = left.obj;
|
|
433
490
|
}
|
|
434
491
|
else {
|
|
@@ -437,9 +494,19 @@ class Util {
|
|
|
437
494
|
}
|
|
438
495
|
}
|
|
439
496
|
/**
|
|
440
|
-
*
|
|
497
|
+
* Do `a` and `b` overlap by at least one character. This returns false if they are at the edges. Here's some examples:
|
|
498
|
+
* ```
|
|
499
|
+
* | true | true | true | true | true | false | false | false | false |
|
|
500
|
+
* |------|------|------|------|------|-------|-------|-------|-------|
|
|
501
|
+
* | aa | aaa | aaa | aaa | a | aa | aa | a | a |
|
|
502
|
+
* | bbb | bb | bbb | b | bbb | bb | bb | b | a |
|
|
503
|
+
* ```
|
|
441
504
|
*/
|
|
442
505
|
rangesIntersect(a, b) {
|
|
506
|
+
//stop if the either range is misisng
|
|
507
|
+
if (!a || !b) {
|
|
508
|
+
return false;
|
|
509
|
+
}
|
|
443
510
|
// Check if `a` is before `b`
|
|
444
511
|
if (a.end.line < b.start.line || (a.end.line === b.start.line && a.end.character <= b.start.character)) {
|
|
445
512
|
return false;
|
|
@@ -451,74 +518,159 @@ class Util {
|
|
|
451
518
|
// These ranges must intersect
|
|
452
519
|
return true;
|
|
453
520
|
}
|
|
521
|
+
/**
|
|
522
|
+
* Do `a` and `b` overlap by at least one character or touch at the edges
|
|
523
|
+
* ```
|
|
524
|
+
* | true | true | true | true | true | true | true | false | false |
|
|
525
|
+
* |------|------|------|------|------|-------|-------|-------|-------|
|
|
526
|
+
* | aa | aaa | aaa | aaa | a | aa | aa | a | a |
|
|
527
|
+
* | bbb | bb | bbb | b | bbb | bb | bb | b | a |
|
|
528
|
+
* ```
|
|
529
|
+
*/
|
|
530
|
+
rangesIntersectOrTouch(a, b) {
|
|
531
|
+
//stop if the either range is misisng
|
|
532
|
+
if (!a || !b) {
|
|
533
|
+
return false;
|
|
534
|
+
}
|
|
535
|
+
// Check if `a` is before `b`
|
|
536
|
+
if (a.end.line < b.start.line || (a.end.line === b.start.line && a.end.character < b.start.character)) {
|
|
537
|
+
return false;
|
|
538
|
+
}
|
|
539
|
+
// Check if `b` is before `a`
|
|
540
|
+
if (b.end.line < a.start.line || (b.end.line === a.start.line && b.end.character < a.start.character)) {
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
// These ranges must intersect
|
|
544
|
+
return true;
|
|
545
|
+
}
|
|
454
546
|
/**
|
|
455
547
|
* Test if `position` is in `range`. If the position is at the edges, will return true.
|
|
456
548
|
* Adapted from core vscode
|
|
457
|
-
* @param range
|
|
458
|
-
* @param position
|
|
459
549
|
*/
|
|
460
550
|
rangeContains(range, position) {
|
|
461
551
|
return this.comparePositionToRange(position, range) === 0;
|
|
462
552
|
}
|
|
463
553
|
comparePositionToRange(position, range) {
|
|
464
|
-
if
|
|
554
|
+
//stop if the either range is missng
|
|
555
|
+
if (!position || !range) {
|
|
556
|
+
return 0;
|
|
557
|
+
}
|
|
558
|
+
if (this.comparePosition(position, range.start) < 0) {
|
|
559
|
+
return -1;
|
|
560
|
+
}
|
|
561
|
+
if (this.comparePosition(position, range.end) > 0) {
|
|
562
|
+
return 1;
|
|
563
|
+
}
|
|
564
|
+
return 0;
|
|
565
|
+
}
|
|
566
|
+
comparePosition(a, b) {
|
|
567
|
+
//stop if the either position is missing
|
|
568
|
+
if (!a || !b) {
|
|
569
|
+
return 0;
|
|
570
|
+
}
|
|
571
|
+
if (a.line < b.line || (a.line === b.line && a.character < b.character)) {
|
|
465
572
|
return -1;
|
|
466
573
|
}
|
|
467
|
-
if (
|
|
574
|
+
if (a.line > b.line || (a.line === b.line && a.character > b.character)) {
|
|
468
575
|
return 1;
|
|
469
576
|
}
|
|
470
577
|
return 0;
|
|
471
578
|
}
|
|
472
579
|
/**
|
|
473
|
-
*
|
|
474
|
-
* @param text
|
|
580
|
+
* Is the inner range completely enclosed in the outer range
|
|
475
581
|
*/
|
|
476
|
-
|
|
477
|
-
return
|
|
478
|
-
|
|
479
|
-
if (err) {
|
|
480
|
-
reject(err);
|
|
481
|
-
}
|
|
482
|
-
else {
|
|
483
|
-
resolve(data);
|
|
484
|
-
}
|
|
485
|
-
});
|
|
486
|
-
});
|
|
582
|
+
isRangeInRange(inner, outer) {
|
|
583
|
+
return this.comparePosition(inner.start, outer.start) === 1 &&
|
|
584
|
+
this.comparePosition(inner.end, outer.end) === -1;
|
|
487
585
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
586
|
+
/**
|
|
587
|
+
* Combine all the documentation for a node - uses the AstNode's leadingTrivia property
|
|
588
|
+
* @param node the node to get the documentation for
|
|
589
|
+
* @param options extra options
|
|
590
|
+
* @param options.prettyPrint if true, will format the comment text for markdown
|
|
591
|
+
* @param options.commentTokens out Array of tokens that match the comment lines
|
|
592
|
+
*/
|
|
593
|
+
getNodeDocumentation(node, options = { prettyPrint: true }) {
|
|
594
|
+
var _a, _b, _c, _d;
|
|
595
|
+
if (!node) {
|
|
596
|
+
return '';
|
|
597
|
+
}
|
|
598
|
+
options = options !== null && options !== void 0 ? options : { prettyPrint: true };
|
|
599
|
+
options.commentTokens = (_a = options.commentTokens) !== null && _a !== void 0 ? _a : [];
|
|
600
|
+
const nodeTrivia = (_b = node.leadingTrivia) !== null && _b !== void 0 ? _b : [];
|
|
601
|
+
const leadingTrivia = (0, reflection_1.isStatement)(node)
|
|
602
|
+
? [...((_d = (_c = node.annotations) === null || _c === void 0 ? void 0 : _c.map(anno => { var _a; return (_a = anno.leadingTrivia) !== null && _a !== void 0 ? _a : []; }).flat()) !== null && _d !== void 0 ? _d : []), ...nodeTrivia]
|
|
603
|
+
: nodeTrivia;
|
|
604
|
+
const tokens = leadingTrivia === null || leadingTrivia === void 0 ? void 0 : leadingTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Newline || t.kind === TokenKind_1.TokenKind.Comment);
|
|
605
|
+
const comments = [];
|
|
606
|
+
let newLinesInRow = 0;
|
|
607
|
+
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
608
|
+
const token = tokens[i];
|
|
609
|
+
//skip whitespace and newline chars
|
|
610
|
+
if (token.kind === TokenKind_1.TokenKind.Comment) {
|
|
611
|
+
comments.push(token);
|
|
612
|
+
newLinesInRow = 0;
|
|
613
|
+
}
|
|
614
|
+
else if (token.kind === TokenKind_1.TokenKind.Newline) {
|
|
615
|
+
//skip these tokens
|
|
616
|
+
newLinesInRow++;
|
|
617
|
+
if (newLinesInRow > 1) {
|
|
618
|
+
// stop processing on empty line.
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
621
|
+
//any other token means there are no more comments
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
break;
|
|
493
625
|
}
|
|
494
626
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
while (subject.length < totalLength) {
|
|
500
|
-
subject = char + subject;
|
|
627
|
+
const jsDocCommentBlockLine = /(\/\*{2,}|\*{1,}\/)/i;
|
|
628
|
+
let usesjsDocCommentBlock = false;
|
|
629
|
+
if (comments.length === 0) {
|
|
630
|
+
return '';
|
|
501
631
|
}
|
|
502
|
-
return
|
|
632
|
+
return comments.reverse()
|
|
633
|
+
.map(x => ({ line: x.text.replace(/^('|rem)/i, '').trim(), token: x }))
|
|
634
|
+
.filter(({ line }) => {
|
|
635
|
+
if (jsDocCommentBlockLine.exec(line)) {
|
|
636
|
+
usesjsDocCommentBlock = true;
|
|
637
|
+
return false;
|
|
638
|
+
}
|
|
639
|
+
return true;
|
|
640
|
+
}).map(({ line, token }) => {
|
|
641
|
+
if (usesjsDocCommentBlock) {
|
|
642
|
+
if (line.startsWith('*')) {
|
|
643
|
+
//remove jsDoc leading '*'
|
|
644
|
+
line = line.slice(1).trim();
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (options.prettyPrint && line.startsWith('@')) {
|
|
648
|
+
// Handle jsdoc/brightscriptdoc tags specially
|
|
649
|
+
// make sure they are on their own markdown line, and add italics
|
|
650
|
+
const firstSpaceIndex = line.indexOf(' ');
|
|
651
|
+
if (firstSpaceIndex === -1) {
|
|
652
|
+
return `\n_${line}_`;
|
|
653
|
+
}
|
|
654
|
+
const firstWord = line.substring(0, firstSpaceIndex);
|
|
655
|
+
return `\n_${firstWord}_ ${line.substring(firstSpaceIndex + 1)}`;
|
|
656
|
+
}
|
|
657
|
+
if (options.commentTokens) {
|
|
658
|
+
options.commentTokens.push(token);
|
|
659
|
+
}
|
|
660
|
+
return line;
|
|
661
|
+
}).join('\n');
|
|
503
662
|
}
|
|
504
663
|
/**
|
|
505
|
-
*
|
|
506
|
-
*
|
|
664
|
+
* Prefixes a component name so it can be used as type in the symbol table, without polluting available symbols
|
|
665
|
+
*
|
|
666
|
+
* @param sgNodeName the Name of the component
|
|
667
|
+
* @returns the node name, prefixed with `roSGNode`
|
|
507
668
|
*/
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
//Uri annoyingly coverts all drive letters to lower case...so this will bring back whatever case it came in as
|
|
511
|
-
let match = /\/\/\/([a-z]:)/i.exec(uri);
|
|
512
|
-
if (match) {
|
|
513
|
-
let originalDriveCasing = match[1];
|
|
514
|
-
parsedPath = originalDriveCasing + parsedPath.substring(2);
|
|
515
|
-
}
|
|
516
|
-
const normalizedPath = path.normalize(parsedPath);
|
|
517
|
-
return normalizedPath;
|
|
669
|
+
getSgNodeTypeName(sgNodeName) {
|
|
670
|
+
return 'roSGNode' + sgNodeName;
|
|
518
671
|
}
|
|
519
672
|
/**
|
|
520
673
|
* Force the drive letter to lower case
|
|
521
|
-
* @param fullPath
|
|
522
674
|
*/
|
|
523
675
|
driveLetterToLower(fullPath) {
|
|
524
676
|
if (fullPath) {
|
|
@@ -534,53 +686,67 @@ class Util {
|
|
|
534
686
|
return fullPath;
|
|
535
687
|
}
|
|
536
688
|
/**
|
|
537
|
-
*
|
|
538
|
-
* This considers order and compares by equality.
|
|
689
|
+
* Replace the first instance of `search` in `subject` with `replacement`
|
|
539
690
|
*/
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
691
|
+
replaceCaseInsensitive(subject, search, replacement) {
|
|
692
|
+
let idx = subject.toLowerCase().indexOf(search.toLowerCase());
|
|
693
|
+
if (idx > -1) {
|
|
694
|
+
let result = subject.substring(0, idx) + replacement + subject.substring(idx + search.length);
|
|
695
|
+
return result;
|
|
543
696
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
return false;
|
|
547
|
-
}
|
|
697
|
+
else {
|
|
698
|
+
return subject;
|
|
548
699
|
}
|
|
549
|
-
return true;
|
|
550
700
|
}
|
|
551
701
|
/**
|
|
552
|
-
*
|
|
553
|
-
* @param srcPath The absolute path to the source file on disk
|
|
702
|
+
* Does the string appear to be a uri (i.e. does it start with `file:`)
|
|
554
703
|
*/
|
|
555
|
-
|
|
556
|
-
return
|
|
704
|
+
isUriLike(filePath) {
|
|
705
|
+
return (filePath === null || filePath === void 0 ? void 0 : filePath.indexOf('file:')) === 0; // eslint-disable-line @typescript-eslint/prefer-string-starts-ends-with
|
|
557
706
|
}
|
|
558
707
|
/**
|
|
559
|
-
*
|
|
560
|
-
* @param options
|
|
708
|
+
* Given a file path, convert it to a URI string
|
|
561
709
|
*/
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
710
|
+
pathToUri(filePath) {
|
|
711
|
+
if (!filePath) {
|
|
712
|
+
return filePath;
|
|
713
|
+
}
|
|
714
|
+
else if (this.isUriLike(filePath)) {
|
|
715
|
+
return filePath;
|
|
567
716
|
}
|
|
568
717
|
else {
|
|
569
|
-
return
|
|
718
|
+
return vscode_uri_1.URI.file(filePath).toString();
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Given a URI, convert that to a regular fs path
|
|
723
|
+
*/
|
|
724
|
+
uriToPath(uri) {
|
|
725
|
+
//if this doesn't look like a URI, then assume it's already a path
|
|
726
|
+
if (this.isUriLike(uri) === false) {
|
|
727
|
+
return uri;
|
|
570
728
|
}
|
|
729
|
+
let parsedPath = vscode_uri_1.URI.parse(uri).fsPath;
|
|
730
|
+
//Uri annoyingly converts all drive letters to lower case...so this will bring back whatever case it came in as
|
|
731
|
+
let match = /\/\/\/([a-z]:)/i.exec(uri);
|
|
732
|
+
if (match) {
|
|
733
|
+
let originalDriveCasing = match[1];
|
|
734
|
+
parsedPath = originalDriveCasing + parsedPath.substring(2);
|
|
735
|
+
}
|
|
736
|
+
const normalizedPath = path.normalize(parsedPath);
|
|
737
|
+
return normalizedPath;
|
|
571
738
|
}
|
|
572
739
|
/**
|
|
573
740
|
* Get paths to all files on disc that match this project's source list
|
|
574
741
|
*/
|
|
575
742
|
async getFilePaths(options) {
|
|
576
743
|
let rootDir = this.getRootDir(options);
|
|
577
|
-
let files = await rokuDeploy.getFilePaths(options.files, rootDir);
|
|
744
|
+
let files = await roku_deploy_1.rokuDeploy.getFilePaths(options.files, rootDir);
|
|
578
745
|
return files;
|
|
579
746
|
}
|
|
580
747
|
/**
|
|
581
748
|
* Given a path to a brs file, compute the path to a theoretical d.bs file.
|
|
582
|
-
* Only `.brs` files can have
|
|
583
|
-
* @param brsSrcPath The absolute path to the .brs source file on disk
|
|
749
|
+
* Only `.brs` files can have typedef path, so return undefined for everything else
|
|
584
750
|
*/
|
|
585
751
|
getTypedefPath(brsSrcPath) {
|
|
586
752
|
const typedefPath = brsSrcPath
|
|
@@ -593,51 +759,9 @@ class Util {
|
|
|
593
759
|
return undefined;
|
|
594
760
|
}
|
|
595
761
|
}
|
|
596
|
-
/**
|
|
597
|
-
* Determine whether this diagnostic should be supressed or not, based on brs comment-flags
|
|
598
|
-
* @param diagnostic
|
|
599
|
-
*/
|
|
600
|
-
diagnosticIsSuppressed(diagnostic) {
|
|
601
|
-
var _a, _b;
|
|
602
|
-
for (let flag of (_b = (_a = diagnostic.file) === null || _a === void 0 ? void 0 : _a.commentFlags) !== null && _b !== void 0 ? _b : []) {
|
|
603
|
-
//this diagnostic is affected by this flag
|
|
604
|
-
if (this.rangeContains(flag.affectedRange, diagnostic.range.start)) {
|
|
605
|
-
//if the flag acts upon this diagnostic's code
|
|
606
|
-
if (flag.codes === null || flag.codes.includes(diagnostic.code)) {
|
|
607
|
-
return true;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
/**
|
|
613
|
-
* Walks up the chain
|
|
614
|
-
* @param currentPath
|
|
615
|
-
*/
|
|
616
|
-
async findClosestConfigFile(currentPath) {
|
|
617
|
-
//make the path absolute
|
|
618
|
-
currentPath = path.resolve(path.normalize(currentPath));
|
|
619
|
-
let previousPath;
|
|
620
|
-
//using ../ on the root of the drive results in the same file path, so that's how we know we reached the top
|
|
621
|
-
while (previousPath !== currentPath) {
|
|
622
|
-
previousPath = currentPath;
|
|
623
|
-
let bsPath = path.join(currentPath, 'bsconfig.json');
|
|
624
|
-
let brsPath = path.join(currentPath, 'brsconfig.json');
|
|
625
|
-
if (await this.pathExists(bsPath)) {
|
|
626
|
-
return bsPath;
|
|
627
|
-
}
|
|
628
|
-
else if (await this.pathExists(brsPath)) {
|
|
629
|
-
return brsPath;
|
|
630
|
-
}
|
|
631
|
-
else {
|
|
632
|
-
//walk upwards one directory
|
|
633
|
-
currentPath = path.resolve(path.join(currentPath, '../'));
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
//got to the root path, no config file exists
|
|
637
|
-
}
|
|
638
762
|
/**
|
|
639
763
|
* Set a timeout for the specified milliseconds, and resolve the promise once the timeout is finished.
|
|
640
|
-
* @param milliseconds
|
|
764
|
+
* @param milliseconds the minimum number of milliseconds to sleep for
|
|
641
765
|
*/
|
|
642
766
|
sleep(milliseconds) {
|
|
643
767
|
return new Promise((resolve) => {
|
|
@@ -650,14 +774,6 @@ class Util {
|
|
|
650
774
|
}
|
|
651
775
|
});
|
|
652
776
|
}
|
|
653
|
-
/**
|
|
654
|
-
* Given an array, map and then flatten
|
|
655
|
-
* @param arr
|
|
656
|
-
* @param cb
|
|
657
|
-
*/
|
|
658
|
-
flatMap(array, cb) {
|
|
659
|
-
return Array.prototype.concat.apply([], array.map(cb));
|
|
660
|
-
}
|
|
661
777
|
/**
|
|
662
778
|
* Determines if the position is greater than the range. This means
|
|
663
779
|
* the position does not touch the range, and has a position greater than the end
|
|
@@ -682,56 +798,49 @@ class Util {
|
|
|
682
798
|
}
|
|
683
799
|
}
|
|
684
800
|
/**
|
|
685
|
-
* Get a
|
|
686
|
-
*/
|
|
687
|
-
getRange(startObj, endObj) {
|
|
688
|
-
return exports.util.createRangeFromPositions(startObj.range.start, endObj.range.end);
|
|
689
|
-
}
|
|
690
|
-
/**
|
|
691
|
-
* If the two items both start on the same line
|
|
801
|
+
* Get a range back from an object that contains (or is) a range
|
|
692
802
|
*/
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
803
|
+
extractRange(rangeIsh) {
|
|
804
|
+
var _a;
|
|
805
|
+
if (!rangeIsh) {
|
|
806
|
+
return undefined;
|
|
807
|
+
}
|
|
808
|
+
else if ('location' in rangeIsh) {
|
|
809
|
+
return (_a = rangeIsh.location) === null || _a === void 0 ? void 0 : _a.range;
|
|
810
|
+
}
|
|
811
|
+
else if ('range' in rangeIsh) {
|
|
812
|
+
return rangeIsh.range;
|
|
813
|
+
}
|
|
814
|
+
else if (vscode_languageserver_1.Range.is(rangeIsh)) {
|
|
815
|
+
return rangeIsh;
|
|
696
816
|
}
|
|
697
817
|
else {
|
|
698
|
-
return
|
|
818
|
+
return undefined;
|
|
699
819
|
}
|
|
700
820
|
}
|
|
701
821
|
/**
|
|
702
822
|
* If the two items have lines that touch
|
|
703
|
-
* @param first
|
|
704
|
-
* @param second
|
|
705
823
|
*/
|
|
706
824
|
linesTouch(first, second) {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
825
|
+
const firstRange = this.extractRange(first);
|
|
826
|
+
const secondRange = this.extractRange(second);
|
|
827
|
+
if (firstRange && secondRange && (firstRange.start.line === secondRange.start.line ||
|
|
828
|
+
firstRange.start.line === secondRange.end.line ||
|
|
829
|
+
firstRange.end.line === secondRange.start.line ||
|
|
830
|
+
firstRange.end.line === secondRange.end.line)) {
|
|
711
831
|
return true;
|
|
712
832
|
}
|
|
713
833
|
else {
|
|
714
834
|
return false;
|
|
715
835
|
}
|
|
716
836
|
}
|
|
717
|
-
/**
|
|
718
|
-
* Given text with (or without) dots separating text, get the rightmost word.
|
|
719
|
-
* (i.e. given "A.B.C", returns "C". or "B" returns "B because there's no dot)
|
|
720
|
-
*/
|
|
721
|
-
getTextAfterFinalDot(name) {
|
|
722
|
-
if (name) {
|
|
723
|
-
let parts = name.split('.');
|
|
724
|
-
if (parts.length > 0) {
|
|
725
|
-
return parts[parts.length - 1];
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
837
|
/**
|
|
730
838
|
* Find a script import that the current position touches, or undefined if not found
|
|
731
839
|
*/
|
|
732
840
|
getScriptImportAtPosition(scriptImports, position) {
|
|
733
841
|
let scriptImport = scriptImports.find((x) => {
|
|
734
|
-
return x.filePathRange
|
|
842
|
+
return x.filePathRange &&
|
|
843
|
+
x.filePathRange.start.line === position.line &&
|
|
735
844
|
//column between start and end
|
|
736
845
|
position.character >= x.filePathRange.start.character &&
|
|
737
846
|
position.character <= x.filePathRange.end.character;
|
|
@@ -775,11 +884,46 @@ class Util {
|
|
|
775
884
|
rangeLines.push(lines[i]);
|
|
776
885
|
}
|
|
777
886
|
const lastLine = rangeLines.pop();
|
|
778
|
-
|
|
887
|
+
if (lastLine !== undefined) {
|
|
888
|
+
rangeLines.push(lastLine.substring(0, endCharacter));
|
|
889
|
+
}
|
|
779
890
|
return rangeLines.join('\n');
|
|
780
891
|
}
|
|
781
892
|
/**
|
|
782
|
-
* Helper for creating `
|
|
893
|
+
* Helper for creating `Location` objects. Prefer using this function because vscode-languageserver's `Location.create()` is significantly slower at scale
|
|
894
|
+
*/
|
|
895
|
+
createLocationFromRange(uri, range) {
|
|
896
|
+
return {
|
|
897
|
+
uri: exports.util.pathToUri(uri),
|
|
898
|
+
range: range
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Helper for creating `Location` objects from a file and range
|
|
903
|
+
*/
|
|
904
|
+
createLocationFromFileRange(file, range) {
|
|
905
|
+
return this.createLocationFromRange(this.pathToUri(file === null || file === void 0 ? void 0 : file.srcPath), range);
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Helper for creating `Location` objects by passing each range value in directly. Prefer using this function because vscode-languageserver's `Location.create()` is significantly slower at scale
|
|
909
|
+
*/
|
|
910
|
+
createLocation(startLine, startCharacter, endLine, endCharacter, uri) {
|
|
911
|
+
return {
|
|
912
|
+
uri: exports.util.pathToUri(uri),
|
|
913
|
+
range: {
|
|
914
|
+
start: {
|
|
915
|
+
line: startLine,
|
|
916
|
+
character: startCharacter
|
|
917
|
+
},
|
|
918
|
+
end: {
|
|
919
|
+
line: endLine,
|
|
920
|
+
character: endCharacter
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Helper for creating `Range` objects. Prefer using this function because vscode-languageserver's `Range.create()` is significantly slower.
|
|
783
927
|
*/
|
|
784
928
|
createRange(startLine, startCharacter, endLine, endCharacter) {
|
|
785
929
|
return {
|
|
@@ -797,141 +941,708 @@ class Util {
|
|
|
797
941
|
* Create a `Range` from two `Position`s
|
|
798
942
|
*/
|
|
799
943
|
createRangeFromPositions(startPosition, endPosition) {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
line: endPosition.line,
|
|
807
|
-
character: endPosition.character
|
|
808
|
-
}
|
|
809
|
-
};
|
|
944
|
+
startPosition = startPosition !== null && startPosition !== void 0 ? startPosition : endPosition;
|
|
945
|
+
endPosition = endPosition !== null && endPosition !== void 0 ? endPosition : startPosition;
|
|
946
|
+
if (!startPosition && !endPosition) {
|
|
947
|
+
return undefined;
|
|
948
|
+
}
|
|
949
|
+
return this.createRange(startPosition.line, startPosition.character, endPosition.line, endPosition.character);
|
|
810
950
|
}
|
|
811
951
|
/**
|
|
812
|
-
*
|
|
813
|
-
* righthand range. Returns undefined if none of the items have a range.
|
|
952
|
+
* Clone a range
|
|
814
953
|
*/
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
if (leftmost && rightmost) {
|
|
831
|
-
break;
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
if (leftmost) {
|
|
835
|
-
return this.createRangeFromPositions(leftmost.range.start, rightmost.range.end);
|
|
954
|
+
cloneLocation(location) {
|
|
955
|
+
if (location) {
|
|
956
|
+
return {
|
|
957
|
+
uri: location.uri,
|
|
958
|
+
range: {
|
|
959
|
+
start: {
|
|
960
|
+
line: location.range.start.line,
|
|
961
|
+
character: location.range.start.character
|
|
962
|
+
},
|
|
963
|
+
end: {
|
|
964
|
+
line: location.range.end.line,
|
|
965
|
+
character: location.range.end.character
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
};
|
|
836
969
|
}
|
|
837
970
|
else {
|
|
838
|
-
return
|
|
971
|
+
return location;
|
|
839
972
|
}
|
|
840
973
|
}
|
|
841
974
|
/**
|
|
842
|
-
*
|
|
843
|
-
*/
|
|
844
|
-
createPosition(line, character) {
|
|
845
|
-
return {
|
|
846
|
-
line: line,
|
|
847
|
-
character: character
|
|
848
|
-
};
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* Convert a list of tokens into a string, including their leading whitespace
|
|
975
|
+
* Clone every token
|
|
852
976
|
*/
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
977
|
+
cloneToken(token) {
|
|
978
|
+
if (token) {
|
|
979
|
+
const result = {
|
|
980
|
+
kind: token.kind,
|
|
981
|
+
location: this.cloneLocation(token.location),
|
|
982
|
+
text: token.text,
|
|
983
|
+
isReserved: token.isReserved,
|
|
984
|
+
leadingWhitespace: token.leadingWhitespace,
|
|
985
|
+
leadingTrivia: token.leadingTrivia.map(x => this.cloneToken(x))
|
|
986
|
+
};
|
|
987
|
+
//handle those tokens that have charCode
|
|
988
|
+
if ('charCode' in token) {
|
|
989
|
+
result.charCode = token.charCode;
|
|
990
|
+
}
|
|
991
|
+
return result;
|
|
992
|
+
}
|
|
993
|
+
else {
|
|
994
|
+
return token;
|
|
859
995
|
}
|
|
860
|
-
return result;
|
|
861
996
|
}
|
|
862
997
|
/**
|
|
863
|
-
*
|
|
998
|
+
* Gets the bounding range of a bunch of ranges or objects that have ranges
|
|
999
|
+
* TODO: this does a full iteration of the args. If the args were guaranteed to be in range order, we could optimize this
|
|
864
1000
|
*/
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
1001
|
+
createBoundingLocation(...locatables) {
|
|
1002
|
+
var _a, _b;
|
|
1003
|
+
let uri;
|
|
1004
|
+
let startPosition;
|
|
1005
|
+
let endPosition;
|
|
1006
|
+
for (let locatable of locatables) {
|
|
1007
|
+
let range;
|
|
1008
|
+
if (!locatable) {
|
|
1009
|
+
continue;
|
|
1010
|
+
}
|
|
1011
|
+
else if ('location' in locatable) {
|
|
1012
|
+
range = (_a = locatable.location) === null || _a === void 0 ? void 0 : _a.range;
|
|
1013
|
+
if (!uri) {
|
|
1014
|
+
uri = (_b = locatable.location) === null || _b === void 0 ? void 0 : _b.uri;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
else if (vscode_languageserver_1.Location.is(locatable)) {
|
|
1018
|
+
range = locatable.range;
|
|
1019
|
+
if (!uri) {
|
|
1020
|
+
uri = locatable.uri;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
else if ('range' in locatable) {
|
|
1024
|
+
range = locatable.range;
|
|
1025
|
+
}
|
|
1026
|
+
else {
|
|
1027
|
+
range = locatable;
|
|
1028
|
+
}
|
|
1029
|
+
//skip undefined locations or locations without a range
|
|
1030
|
+
if (!range) {
|
|
1031
|
+
continue;
|
|
1032
|
+
}
|
|
1033
|
+
if (!startPosition) {
|
|
1034
|
+
startPosition = range.start;
|
|
1035
|
+
}
|
|
1036
|
+
else if (this.comparePosition(range.start, startPosition) < 0) {
|
|
1037
|
+
startPosition = range.start;
|
|
1038
|
+
}
|
|
1039
|
+
if (!endPosition) {
|
|
1040
|
+
endPosition = range.end;
|
|
1041
|
+
}
|
|
1042
|
+
else if (this.comparePosition(range.end, endPosition) > 0) {
|
|
1043
|
+
endPosition = range.end;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
if (startPosition && endPosition) {
|
|
1047
|
+
return exports.util.createLocation(startPosition.line, startPosition.character, endPosition.line, endPosition.character, uri);
|
|
1048
|
+
}
|
|
1049
|
+
else {
|
|
1050
|
+
return undefined;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Gets the bounding range of a bunch of ranges or objects that have ranges
|
|
1055
|
+
* TODO: this does a full iteration of the args. If the args were guaranteed to be in range order, we could optimize this
|
|
1056
|
+
*/
|
|
1057
|
+
createBoundingRange(...locatables) {
|
|
1058
|
+
var _a;
|
|
1059
|
+
return (_a = this.createBoundingLocation(...locatables)) === null || _a === void 0 ? void 0 : _a.range;
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Gets the bounding range of an object that contains a bunch of tokens
|
|
1063
|
+
* @param tokens Object with tokens in it
|
|
1064
|
+
* @returns Range containing all the tokens
|
|
1065
|
+
*/
|
|
1066
|
+
createBoundingLocationFromTokens(tokens) {
|
|
1067
|
+
var _a;
|
|
1068
|
+
let uri;
|
|
1069
|
+
let startPosition;
|
|
1070
|
+
let endPosition;
|
|
1071
|
+
for (let key in tokens) {
|
|
1072
|
+
let token = tokens === null || tokens === void 0 ? void 0 : tokens[key];
|
|
1073
|
+
let locatableRange = (_a = token === null || token === void 0 ? void 0 : token.location) === null || _a === void 0 ? void 0 : _a.range;
|
|
1074
|
+
if (!locatableRange) {
|
|
1075
|
+
continue;
|
|
1076
|
+
}
|
|
1077
|
+
if (!startPosition) {
|
|
1078
|
+
startPosition = locatableRange.start;
|
|
1079
|
+
}
|
|
1080
|
+
else if (this.comparePosition(locatableRange.start, startPosition) < 0) {
|
|
1081
|
+
startPosition = locatableRange.start;
|
|
1082
|
+
}
|
|
1083
|
+
if (!endPosition) {
|
|
1084
|
+
endPosition = locatableRange.end;
|
|
1085
|
+
}
|
|
1086
|
+
else if (this.comparePosition(locatableRange.end, endPosition) > 0) {
|
|
1087
|
+
endPosition = locatableRange.end;
|
|
1088
|
+
}
|
|
1089
|
+
if (!uri) {
|
|
1090
|
+
uri = token.location.uri;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
if (startPosition && endPosition) {
|
|
1094
|
+
return this.createLocation(startPosition.line, startPosition.character, endPosition.line, endPosition.character, uri);
|
|
1095
|
+
}
|
|
1096
|
+
else {
|
|
1097
|
+
return undefined;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Create a `Position` object. Prefer this over `Position.create` for performance reasons.
|
|
1102
|
+
*/
|
|
1103
|
+
createPosition(line, character) {
|
|
1104
|
+
return {
|
|
1105
|
+
line: line,
|
|
1106
|
+
character: character
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
/**
|
|
1110
|
+
* Convert a token into a BscType
|
|
1111
|
+
*/
|
|
1112
|
+
tokenToBscType(token) {
|
|
1113
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
1114
|
+
switch (token.kind) {
|
|
1115
|
+
case TokenKind_1.TokenKind.Boolean:
|
|
1116
|
+
return BooleanType_1.BooleanType.instance;
|
|
1117
|
+
case TokenKind_1.TokenKind.True:
|
|
1118
|
+
case TokenKind_1.TokenKind.False:
|
|
1119
|
+
return BooleanType_1.BooleanType.instance;
|
|
1120
|
+
case TokenKind_1.TokenKind.Double:
|
|
1121
|
+
return DoubleType_1.DoubleType.instance;
|
|
1122
|
+
case TokenKind_1.TokenKind.DoubleLiteral:
|
|
1123
|
+
return DoubleType_1.DoubleType.instance;
|
|
1124
|
+
case TokenKind_1.TokenKind.Dynamic:
|
|
1125
|
+
return DynamicType_1.DynamicType.instance;
|
|
1126
|
+
case TokenKind_1.TokenKind.Float:
|
|
1127
|
+
return FloatType_1.FloatType.instance;
|
|
1128
|
+
case TokenKind_1.TokenKind.FloatLiteral:
|
|
1129
|
+
return FloatType_1.FloatType.instance;
|
|
1130
|
+
case TokenKind_1.TokenKind.Function:
|
|
1131
|
+
return FunctionType_1.FunctionType.instance;
|
|
1132
|
+
case TokenKind_1.TokenKind.Integer:
|
|
1133
|
+
return IntegerType_1.IntegerType.instance;
|
|
1134
|
+
case TokenKind_1.TokenKind.IntegerLiteral:
|
|
1135
|
+
return IntegerType_1.IntegerType.instance;
|
|
1136
|
+
case TokenKind_1.TokenKind.Invalid:
|
|
1137
|
+
return InvalidType_1.InvalidType.instance;
|
|
1138
|
+
case TokenKind_1.TokenKind.LongInteger:
|
|
1139
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1140
|
+
case TokenKind_1.TokenKind.LongIntegerLiteral:
|
|
1141
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1142
|
+
case TokenKind_1.TokenKind.Object:
|
|
1143
|
+
return ObjectType_1.ObjectType.instance;
|
|
1144
|
+
case TokenKind_1.TokenKind.String:
|
|
1145
|
+
return StringType_1.StringType.instance;
|
|
1146
|
+
case TokenKind_1.TokenKind.StringLiteral:
|
|
1147
|
+
case TokenKind_1.TokenKind.TemplateStringExpressionBegin:
|
|
1148
|
+
case TokenKind_1.TokenKind.TemplateStringExpressionEnd:
|
|
1149
|
+
case TokenKind_1.TokenKind.TemplateStringQuasi:
|
|
1150
|
+
return StringType_1.StringType.instance;
|
|
1151
|
+
case TokenKind_1.TokenKind.Void:
|
|
1152
|
+
return VoidType_1.VoidType.instance;
|
|
1153
|
+
case TokenKind_1.TokenKind.Identifier:
|
|
1154
|
+
switch (token.text.toLowerCase()) {
|
|
1155
|
+
case 'boolean':
|
|
1156
|
+
return BooleanType_1.BooleanType.instance;
|
|
1157
|
+
case 'double':
|
|
1158
|
+
return DoubleType_1.DoubleType.instance;
|
|
1159
|
+
case 'dynamic':
|
|
1160
|
+
return DynamicType_1.DynamicType.instance;
|
|
1161
|
+
case 'float':
|
|
1162
|
+
return FloatType_1.FloatType.instance;
|
|
1163
|
+
case 'function':
|
|
1164
|
+
return FunctionType_1.FunctionType.instance;
|
|
1165
|
+
case 'integer':
|
|
1166
|
+
return IntegerType_1.IntegerType.instance;
|
|
916
1167
|
case 'invalid':
|
|
917
|
-
return
|
|
1168
|
+
return InvalidType_1.InvalidType.instance;
|
|
918
1169
|
case 'longinteger':
|
|
919
|
-
return
|
|
1170
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
920
1171
|
case 'object':
|
|
921
|
-
return
|
|
1172
|
+
return ObjectType_1.ObjectType.instance;
|
|
922
1173
|
case 'string':
|
|
923
|
-
return
|
|
1174
|
+
return StringType_1.StringType.instance;
|
|
924
1175
|
case 'void':
|
|
925
|
-
return
|
|
1176
|
+
return VoidType_1.VoidType.instance;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
/**
|
|
1181
|
+
* Deciphers the correct types for fields based on docs
|
|
1182
|
+
* https://developer.roku.com/en-ca/docs/references/scenegraph/xml-elements/interface.md
|
|
1183
|
+
* @param typeDescriptor the type descriptor from the docs
|
|
1184
|
+
* @returns {BscType} the known type, or dynamic
|
|
1185
|
+
*/
|
|
1186
|
+
getNodeFieldType(typeDescriptor, lookupTable) {
|
|
1187
|
+
let typeDescriptorLower = typeDescriptor.toLowerCase().trim().replace(/\*/g, '');
|
|
1188
|
+
if (typeDescriptorLower.startsWith('as ')) {
|
|
1189
|
+
typeDescriptorLower = typeDescriptorLower.substring(3).trim();
|
|
1190
|
+
}
|
|
1191
|
+
const nodeFilter = (new RegExp(/^\[?(.* node)/, 'i')).exec(typeDescriptorLower);
|
|
1192
|
+
if (nodeFilter === null || nodeFilter === void 0 ? void 0 : nodeFilter[1]) {
|
|
1193
|
+
typeDescriptorLower = nodeFilter[1].trim();
|
|
1194
|
+
}
|
|
1195
|
+
const parensFilter = (new RegExp(/(.*)\(.*\)/, 'gi')).exec(typeDescriptorLower);
|
|
1196
|
+
if (parensFilter === null || parensFilter === void 0 ? void 0 : parensFilter[1]) {
|
|
1197
|
+
typeDescriptorLower = parensFilter[1].trim();
|
|
1198
|
+
}
|
|
1199
|
+
const bscType = this.tokenToBscType((0, creators_1.createToken)(TokenKind_1.TokenKind.Identifier, typeDescriptorLower));
|
|
1200
|
+
if (bscType) {
|
|
1201
|
+
return bscType;
|
|
1202
|
+
}
|
|
1203
|
+
function getRect2dType() {
|
|
1204
|
+
const rect2dType = new AssociativeArrayType_1.AssociativeArrayType();
|
|
1205
|
+
rect2dType.addMember('height', {}, FloatType_1.FloatType.instance, 1 /* SymbolTypeFlag.runtime */);
|
|
1206
|
+
rect2dType.addMember('width', {}, FloatType_1.FloatType.instance, 1 /* SymbolTypeFlag.runtime */);
|
|
1207
|
+
rect2dType.addMember('x', {}, FloatType_1.FloatType.instance, 1 /* SymbolTypeFlag.runtime */);
|
|
1208
|
+
rect2dType.addMember('y', {}, FloatType_1.FloatType.instance, 1 /* SymbolTypeFlag.runtime */);
|
|
1209
|
+
return rect2dType;
|
|
1210
|
+
}
|
|
1211
|
+
function getColorType() {
|
|
1212
|
+
return (0, UnionType_1.unionTypeFactory)([IntegerType_1.IntegerType.instance, StringType_1.StringType.instance]);
|
|
1213
|
+
}
|
|
1214
|
+
//check for uniontypes
|
|
1215
|
+
const multipleTypes = typeDescriptorLower.split(' or ').map(s => s.trim());
|
|
1216
|
+
if (multipleTypes.length > 1) {
|
|
1217
|
+
const individualTypes = multipleTypes.map(t => this.getNodeFieldType(t, lookupTable));
|
|
1218
|
+
return (0, UnionType_1.unionTypeFactory)(individualTypes);
|
|
1219
|
+
}
|
|
1220
|
+
const typeIsArray = typeDescriptorLower.startsWith('array of ') || typeDescriptorLower.startsWith('roarray of ');
|
|
1221
|
+
if (typeIsArray) {
|
|
1222
|
+
const ofSearch = ' of ';
|
|
1223
|
+
const arrayPrefixLength = typeDescriptorLower.indexOf(ofSearch) + ofSearch.length;
|
|
1224
|
+
let arrayOfTypeName = typeDescriptorLower.substring(arrayPrefixLength); //cut off beginnin, eg. 'array of' or 'roarray of'
|
|
1225
|
+
if (arrayOfTypeName.endsWith('s')) {
|
|
1226
|
+
// remove "s" in "floats", etc.
|
|
1227
|
+
arrayOfTypeName = arrayOfTypeName.substring(0, arrayOfTypeName.length - 1);
|
|
1228
|
+
}
|
|
1229
|
+
if (arrayOfTypeName.endsWith('\'')) {
|
|
1230
|
+
// remove "'" in "float's", etc.
|
|
1231
|
+
arrayOfTypeName = arrayOfTypeName.substring(0, arrayOfTypeName.length - 1);
|
|
1232
|
+
}
|
|
1233
|
+
if (arrayOfTypeName === 'rectangle') {
|
|
1234
|
+
arrayOfTypeName = 'rect2d';
|
|
1235
|
+
}
|
|
1236
|
+
let arrayType = this.getNodeFieldType(arrayOfTypeName, lookupTable);
|
|
1237
|
+
return new ArrayType_1.ArrayType(arrayType);
|
|
1238
|
+
}
|
|
1239
|
+
else if (typeDescriptorLower.startsWith('option ')) {
|
|
1240
|
+
const actualTypeName = typeDescriptorLower.substring('option '.length); //cut off beginning 'option '
|
|
1241
|
+
return this.getNodeFieldType(actualTypeName, lookupTable);
|
|
1242
|
+
}
|
|
1243
|
+
else if (typeDescriptorLower.startsWith('value ')) {
|
|
1244
|
+
const actualTypeName = typeDescriptorLower.substring('value '.length); //cut off beginning 'value '
|
|
1245
|
+
return this.getNodeFieldType(actualTypeName, lookupTable);
|
|
1246
|
+
}
|
|
1247
|
+
else if (typeDescriptorLower === 'n/a') {
|
|
1248
|
+
return DynamicType_1.DynamicType.instance;
|
|
1249
|
+
}
|
|
1250
|
+
else if (typeDescriptorLower === 'uri') {
|
|
1251
|
+
return StringType_1.StringType.instance;
|
|
1252
|
+
}
|
|
1253
|
+
else if (typeDescriptorLower === 'color') {
|
|
1254
|
+
return getColorType();
|
|
1255
|
+
}
|
|
1256
|
+
else if (typeDescriptorLower === 'vector2d' || typeDescriptorLower === 'floatarray') {
|
|
1257
|
+
return new ArrayType_1.ArrayType(FloatType_1.FloatType.instance);
|
|
1258
|
+
}
|
|
1259
|
+
else if (typeDescriptorLower === 'vector2darray') {
|
|
1260
|
+
return new ArrayType_1.ArrayType(new ArrayType_1.ArrayType(FloatType_1.FloatType.instance));
|
|
1261
|
+
}
|
|
1262
|
+
else if (typeDescriptorLower === 'intarray') {
|
|
1263
|
+
return new ArrayType_1.ArrayType(IntegerType_1.IntegerType.instance);
|
|
1264
|
+
}
|
|
1265
|
+
else if (typeDescriptorLower === 'colorarray') {
|
|
1266
|
+
return new ArrayType_1.ArrayType(getColorType());
|
|
1267
|
+
}
|
|
1268
|
+
else if (typeDescriptorLower === 'boolarray') {
|
|
1269
|
+
return new ArrayType_1.ArrayType(BooleanType_1.BooleanType.instance);
|
|
1270
|
+
}
|
|
1271
|
+
else if (typeDescriptorLower === 'stringarray' || typeDescriptorLower === 'strarray') {
|
|
1272
|
+
return new ArrayType_1.ArrayType(StringType_1.StringType.instance);
|
|
1273
|
+
}
|
|
1274
|
+
else if (typeDescriptorLower === 'int') {
|
|
1275
|
+
return IntegerType_1.IntegerType.instance;
|
|
1276
|
+
}
|
|
1277
|
+
else if (typeDescriptorLower === 'time') {
|
|
1278
|
+
return DoubleType_1.DoubleType.instance;
|
|
1279
|
+
}
|
|
1280
|
+
else if (typeDescriptorLower === 'str') {
|
|
1281
|
+
return StringType_1.StringType.instance;
|
|
1282
|
+
}
|
|
1283
|
+
else if (typeDescriptorLower === 'bool') {
|
|
1284
|
+
return BooleanType_1.BooleanType.instance;
|
|
1285
|
+
}
|
|
1286
|
+
else if (typeDescriptorLower === 'array' || typeDescriptorLower === 'roarray') {
|
|
1287
|
+
return new ArrayType_1.ArrayType();
|
|
1288
|
+
}
|
|
1289
|
+
else if (typeDescriptorLower === 'assocarray' ||
|
|
1290
|
+
typeDescriptorLower === 'associative array' ||
|
|
1291
|
+
typeDescriptorLower === 'associativearray' ||
|
|
1292
|
+
typeDescriptorLower === 'roassociativearray' ||
|
|
1293
|
+
typeDescriptorLower.startsWith('associative array of') ||
|
|
1294
|
+
typeDescriptorLower.startsWith('associativearray of') ||
|
|
1295
|
+
typeDescriptorLower.startsWith('roassociativearray of')) {
|
|
1296
|
+
return new AssociativeArrayType_1.AssociativeArrayType();
|
|
1297
|
+
}
|
|
1298
|
+
else if (typeDescriptorLower === 'node') {
|
|
1299
|
+
return ComponentType_1.ComponentType.instance;
|
|
1300
|
+
}
|
|
1301
|
+
else if (typeDescriptorLower === 'nodearray') {
|
|
1302
|
+
return new ArrayType_1.ArrayType(ComponentType_1.ComponentType.instance);
|
|
1303
|
+
}
|
|
1304
|
+
else if (typeDescriptorLower === 'rect2d') {
|
|
1305
|
+
return getRect2dType();
|
|
1306
|
+
}
|
|
1307
|
+
else if (typeDescriptorLower === 'rect2darray') {
|
|
1308
|
+
return new ArrayType_1.ArrayType(getRect2dType());
|
|
1309
|
+
}
|
|
1310
|
+
else if (typeDescriptorLower === 'font') {
|
|
1311
|
+
return this.getNodeFieldType('roSGNodeFont', lookupTable);
|
|
1312
|
+
}
|
|
1313
|
+
else if (typeDescriptorLower === 'contentnode') {
|
|
1314
|
+
return this.getNodeFieldType('roSGNodeContentNode', lookupTable);
|
|
1315
|
+
}
|
|
1316
|
+
else if (typeDescriptorLower.endsWith(' node')) {
|
|
1317
|
+
return this.getNodeFieldType('roSgNode' + typeDescriptorLower.substring(0, typeDescriptorLower.length - 5), lookupTable);
|
|
1318
|
+
}
|
|
1319
|
+
else if (lookupTable) {
|
|
1320
|
+
//try doing a lookup
|
|
1321
|
+
return lookupTable.getSymbolType(typeDescriptorLower, {
|
|
1322
|
+
flags: 2 /* SymbolTypeFlag.typetime */,
|
|
1323
|
+
fullName: typeDescriptor,
|
|
1324
|
+
tableProvider: () => lookupTable
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
return DynamicType_1.DynamicType.instance;
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Return the type of the result of a binary operator
|
|
1331
|
+
* Note: compound assignments (eg. +=) internally use a binary expression, so that's why TokenKind.PlusEqual, etc. are here too
|
|
1332
|
+
*/
|
|
1333
|
+
binaryOperatorResultType(leftType, operator, rightType) {
|
|
1334
|
+
if (((0, reflection_1.isAnyReferenceType)(leftType) && !leftType.isResolvable()) ||
|
|
1335
|
+
((0, reflection_1.isAnyReferenceType)(rightType) && !rightType.isResolvable())) {
|
|
1336
|
+
return new ReferenceType_1.BinaryOperatorReferenceType(leftType, operator, rightType, (lhs, op, rhs) => {
|
|
1337
|
+
return this.binaryOperatorResultType(lhs, op, rhs);
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
// Try to find a common value of union type
|
|
1341
|
+
leftType = (0, helpers_1.getUniqueType)([leftType], UnionType_1.unionTypeFactory);
|
|
1342
|
+
rightType = (0, helpers_1.getUniqueType)([rightType], UnionType_1.unionTypeFactory);
|
|
1343
|
+
if ((0, reflection_1.isUnionType)(leftType)) {
|
|
1344
|
+
leftType = this.getHighestPriorityType(leftType.types);
|
|
1345
|
+
}
|
|
1346
|
+
if ((0, reflection_1.isUnionType)(rightType)) {
|
|
1347
|
+
rightType = this.getHighestPriorityType(rightType.types);
|
|
1348
|
+
}
|
|
1349
|
+
if ((0, reflection_1.isVoidType)(leftType) || (0, reflection_1.isVoidType)(rightType) || (0, reflection_1.isUninitializedType)(leftType) || (0, reflection_1.isUninitializedType)(rightType)) {
|
|
1350
|
+
return undefined;
|
|
1351
|
+
}
|
|
1352
|
+
if ((0, reflection_1.isEnumMemberType)(leftType)) {
|
|
1353
|
+
leftType = leftType.underlyingType;
|
|
1354
|
+
}
|
|
1355
|
+
if ((0, reflection_1.isEnumMemberType)(rightType)) {
|
|
1356
|
+
rightType = rightType.underlyingType;
|
|
1357
|
+
}
|
|
1358
|
+
// treat object type like dynamic
|
|
1359
|
+
if ((0, reflection_1.isObjectType)(leftType)) {
|
|
1360
|
+
leftType = DynamicType_1.DynamicType.instance;
|
|
1361
|
+
}
|
|
1362
|
+
if ((0, reflection_1.isObjectType)(rightType)) {
|
|
1363
|
+
rightType = DynamicType_1.DynamicType.instance;
|
|
1364
|
+
}
|
|
1365
|
+
let hasDouble = (0, reflection_1.isDoubleTypeLike)(leftType) || (0, reflection_1.isDoubleTypeLike)(rightType);
|
|
1366
|
+
let hasFloat = (0, reflection_1.isFloatTypeLike)(leftType) || (0, reflection_1.isFloatTypeLike)(rightType);
|
|
1367
|
+
let hasLongInteger = (0, reflection_1.isLongIntegerTypeLike)(leftType) || (0, reflection_1.isLongIntegerTypeLike)(rightType);
|
|
1368
|
+
let hasInvalid = (0, reflection_1.isInvalidTypeLike)(leftType) || (0, reflection_1.isInvalidTypeLike)(rightType);
|
|
1369
|
+
let hasDynamic = (0, reflection_1.isDynamicType)(leftType) || (0, reflection_1.isDynamicType)(rightType);
|
|
1370
|
+
let bothDynamic = (0, reflection_1.isDynamicType)(leftType) && (0, reflection_1.isDynamicType)(rightType);
|
|
1371
|
+
let bothNumbers = (0, reflection_1.isNumberTypeLike)(leftType) && (0, reflection_1.isNumberTypeLike)(rightType);
|
|
1372
|
+
let hasNumber = (0, reflection_1.isNumberTypeLike)(leftType) || (0, reflection_1.isNumberTypeLike)(rightType);
|
|
1373
|
+
let bothStrings = (0, reflection_1.isStringTypeLike)(leftType) && (0, reflection_1.isStringTypeLike)(rightType);
|
|
1374
|
+
let hasString = (0, reflection_1.isStringTypeLike)(leftType) || (0, reflection_1.isStringTypeLike)(rightType);
|
|
1375
|
+
let hasBoolean = (0, reflection_1.isBooleanTypeLike)(leftType) || (0, reflection_1.isBooleanTypeLike)(rightType);
|
|
1376
|
+
let eitherBooleanOrNum = ((0, reflection_1.isNumberTypeLike)(leftType) || (0, reflection_1.isBooleanTypeLike)(leftType)) && ((0, reflection_1.isNumberTypeLike)(rightType) || (0, reflection_1.isBooleanTypeLike)(rightType));
|
|
1377
|
+
let leftIsPrimitive = (0, reflection_1.isPrimitiveType)(leftType);
|
|
1378
|
+
let rightIsPrimitive = (0, reflection_1.isPrimitiveType)(rightType);
|
|
1379
|
+
let hasPrimitive = leftIsPrimitive || rightIsPrimitive;
|
|
1380
|
+
let nonDynamicType;
|
|
1381
|
+
if (hasPrimitive) {
|
|
1382
|
+
nonDynamicType = leftIsPrimitive ? leftType : rightType;
|
|
1383
|
+
}
|
|
1384
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
1385
|
+
switch (operator.kind) {
|
|
1386
|
+
// Math operators
|
|
1387
|
+
case TokenKind_1.TokenKind.Plus:
|
|
1388
|
+
case TokenKind_1.TokenKind.PlusEqual:
|
|
1389
|
+
if (bothStrings) {
|
|
1390
|
+
// "string" + "string" is the only binary expression allowed with strings
|
|
1391
|
+
return StringType_1.StringType.instance;
|
|
1392
|
+
}
|
|
1393
|
+
else if (hasString && hasDynamic) {
|
|
1394
|
+
// assume dynamicValue is a string
|
|
1395
|
+
return StringType_1.StringType.instance;
|
|
926
1396
|
}
|
|
927
|
-
|
|
928
|
-
|
|
1397
|
+
// eslint-disable-next-line no-fallthrough
|
|
1398
|
+
case TokenKind_1.TokenKind.Minus:
|
|
1399
|
+
case TokenKind_1.TokenKind.MinusEqual:
|
|
1400
|
+
case TokenKind_1.TokenKind.Star:
|
|
1401
|
+
case TokenKind_1.TokenKind.StarEqual:
|
|
1402
|
+
case TokenKind_1.TokenKind.Mod:
|
|
1403
|
+
if (bothNumbers) {
|
|
1404
|
+
if (hasDouble) {
|
|
1405
|
+
return DoubleType_1.DoubleType.instance;
|
|
1406
|
+
}
|
|
1407
|
+
else if (hasFloat) {
|
|
1408
|
+
return FloatType_1.FloatType.instance;
|
|
1409
|
+
}
|
|
1410
|
+
else if (hasLongInteger) {
|
|
1411
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1412
|
+
}
|
|
1413
|
+
return IntegerType_1.IntegerType.instance;
|
|
1414
|
+
}
|
|
1415
|
+
else if (hasNumber && hasDynamic) {
|
|
1416
|
+
// assume dynamic is a number
|
|
1417
|
+
return nonDynamicType;
|
|
929
1418
|
}
|
|
1419
|
+
break;
|
|
1420
|
+
case TokenKind_1.TokenKind.Forwardslash:
|
|
1421
|
+
case TokenKind_1.TokenKind.ForwardslashEqual:
|
|
1422
|
+
if (bothNumbers) {
|
|
1423
|
+
if (hasDouble) {
|
|
1424
|
+
return DoubleType_1.DoubleType.instance;
|
|
1425
|
+
}
|
|
1426
|
+
else if (hasFloat) {
|
|
1427
|
+
return FloatType_1.FloatType.instance;
|
|
1428
|
+
}
|
|
1429
|
+
else if (hasLongInteger) {
|
|
1430
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1431
|
+
}
|
|
1432
|
+
return FloatType_1.FloatType.instance;
|
|
1433
|
+
}
|
|
1434
|
+
else if (hasNumber && hasDynamic) {
|
|
1435
|
+
// assume dynamic is a number
|
|
1436
|
+
return nonDynamicType;
|
|
1437
|
+
}
|
|
1438
|
+
break;
|
|
1439
|
+
case TokenKind_1.TokenKind.Backslash:
|
|
1440
|
+
case TokenKind_1.TokenKind.BackslashEqual:
|
|
1441
|
+
if (bothNumbers) {
|
|
1442
|
+
if (hasLongInteger) {
|
|
1443
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1444
|
+
}
|
|
1445
|
+
return IntegerType_1.IntegerType.instance;
|
|
1446
|
+
}
|
|
1447
|
+
else if (hasNumber && hasDynamic) {
|
|
1448
|
+
// assume dynamic is a number
|
|
1449
|
+
return IntegerType_1.IntegerType.instance;
|
|
1450
|
+
}
|
|
1451
|
+
break;
|
|
1452
|
+
case TokenKind_1.TokenKind.Caret:
|
|
1453
|
+
if (bothNumbers) {
|
|
1454
|
+
if (hasDouble || hasLongInteger) {
|
|
1455
|
+
return DoubleType_1.DoubleType.instance;
|
|
1456
|
+
}
|
|
1457
|
+
else if (hasFloat) {
|
|
1458
|
+
return FloatType_1.FloatType.instance;
|
|
1459
|
+
}
|
|
1460
|
+
return IntegerType_1.IntegerType.instance;
|
|
1461
|
+
}
|
|
1462
|
+
else if (hasNumber && hasDynamic) {
|
|
1463
|
+
// assume dynamic is a number
|
|
1464
|
+
return IntegerType_1.IntegerType.instance;
|
|
1465
|
+
}
|
|
1466
|
+
break;
|
|
1467
|
+
// Bitshift operators
|
|
1468
|
+
case TokenKind_1.TokenKind.LeftShift:
|
|
1469
|
+
case TokenKind_1.TokenKind.LeftShiftEqual:
|
|
1470
|
+
case TokenKind_1.TokenKind.RightShift:
|
|
1471
|
+
case TokenKind_1.TokenKind.RightShiftEqual:
|
|
1472
|
+
if (bothNumbers) {
|
|
1473
|
+
if (hasLongInteger) {
|
|
1474
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1475
|
+
}
|
|
1476
|
+
// Bitshifts are allowed with non-integer numerics
|
|
1477
|
+
// but will always truncate to ints
|
|
1478
|
+
return IntegerType_1.IntegerType.instance;
|
|
1479
|
+
}
|
|
1480
|
+
else if (hasNumber && hasDynamic) {
|
|
1481
|
+
// assume dynamic is a number
|
|
1482
|
+
return IntegerType_1.IntegerType.instance;
|
|
1483
|
+
}
|
|
1484
|
+
break;
|
|
1485
|
+
// Comparison operators
|
|
1486
|
+
// All comparison operators result in boolean
|
|
1487
|
+
case TokenKind_1.TokenKind.Equal:
|
|
1488
|
+
case TokenKind_1.TokenKind.LessGreater:
|
|
1489
|
+
// = and <> can accept invalid / dynamic
|
|
1490
|
+
if (hasDynamic || hasInvalid || bothStrings || eitherBooleanOrNum) {
|
|
1491
|
+
return BooleanType_1.BooleanType.instance;
|
|
1492
|
+
}
|
|
1493
|
+
break;
|
|
1494
|
+
case TokenKind_1.TokenKind.Greater:
|
|
1495
|
+
case TokenKind_1.TokenKind.Less:
|
|
1496
|
+
case TokenKind_1.TokenKind.GreaterEqual:
|
|
1497
|
+
case TokenKind_1.TokenKind.LessEqual:
|
|
1498
|
+
if (bothStrings || bothNumbers) {
|
|
1499
|
+
return BooleanType_1.BooleanType.instance;
|
|
1500
|
+
}
|
|
1501
|
+
else if ((hasNumber || hasString) && hasDynamic) {
|
|
1502
|
+
// assume dynamic is a valid type
|
|
1503
|
+
return BooleanType_1.BooleanType.instance;
|
|
1504
|
+
}
|
|
1505
|
+
break;
|
|
1506
|
+
// Logical or bitwise operators
|
|
1507
|
+
case TokenKind_1.TokenKind.Or:
|
|
1508
|
+
case TokenKind_1.TokenKind.And:
|
|
1509
|
+
if (bothNumbers) {
|
|
1510
|
+
// "and"/"or" represent bitwise operators
|
|
1511
|
+
if (hasLongInteger && !hasDouble && !hasFloat) {
|
|
1512
|
+
// 2 long ints or long int and int
|
|
1513
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1514
|
+
}
|
|
1515
|
+
return IntegerType_1.IntegerType.instance;
|
|
1516
|
+
}
|
|
1517
|
+
else if (eitherBooleanOrNum) {
|
|
1518
|
+
// "and"/"or" represent logical operators
|
|
1519
|
+
return BooleanType_1.BooleanType.instance;
|
|
1520
|
+
}
|
|
1521
|
+
else if (hasNumber && hasDynamic) {
|
|
1522
|
+
// assume dynamic is a valid type
|
|
1523
|
+
return IntegerType_1.IntegerType.instance;
|
|
1524
|
+
}
|
|
1525
|
+
else if (hasBoolean && hasDynamic) {
|
|
1526
|
+
// assume dynamic is a valid type
|
|
1527
|
+
return BooleanType_1.BooleanType.instance;
|
|
1528
|
+
}
|
|
1529
|
+
break;
|
|
1530
|
+
}
|
|
1531
|
+
if (bothDynamic) {
|
|
1532
|
+
return DynamicType_1.DynamicType.instance;
|
|
930
1533
|
}
|
|
1534
|
+
return undefined;
|
|
1535
|
+
}
|
|
1536
|
+
getHighestPriorityType(types, depth = 0) {
|
|
1537
|
+
let result;
|
|
1538
|
+
if (depth > 4) {
|
|
1539
|
+
// shortcut for very complicated types, or self-referencing union types
|
|
1540
|
+
return DynamicType_1.DynamicType.instance;
|
|
1541
|
+
}
|
|
1542
|
+
for (let type of types) {
|
|
1543
|
+
if ((0, reflection_1.isUnionType)(type)) {
|
|
1544
|
+
type = (0, helpers_1.getUniqueType)([type], UnionType_1.unionTypeFactory);
|
|
1545
|
+
if ((0, reflection_1.isUnionType)(type)) {
|
|
1546
|
+
type = this.getHighestPriorityType(type.types, depth + 1);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
if (!result) {
|
|
1550
|
+
result = type;
|
|
1551
|
+
}
|
|
1552
|
+
else {
|
|
1553
|
+
if (type.binaryOpPriorityLevel < result.binaryOpPriorityLevel) {
|
|
1554
|
+
result = type;
|
|
1555
|
+
}
|
|
1556
|
+
else if (type.binaryOpPriorityLevel === result.binaryOpPriorityLevel && !result.isEqual(type)) {
|
|
1557
|
+
// equal priority types, but not equal types, like Boolean and String... just be dynamic at this point
|
|
1558
|
+
result = DynamicType_1.DynamicType.instance;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
if ((0, reflection_1.isUninitializedType)(type)) {
|
|
1562
|
+
return type;
|
|
1563
|
+
}
|
|
1564
|
+
if ((0, reflection_1.isVoidType)(type)) {
|
|
1565
|
+
return type;
|
|
1566
|
+
}
|
|
1567
|
+
if ((0, reflection_1.isInvalidTypeLike)(type)) {
|
|
1568
|
+
return type;
|
|
1569
|
+
}
|
|
1570
|
+
if ((0, reflection_1.isObjectType)(type) && !(0, reflection_1.isDynamicType)(type)) {
|
|
1571
|
+
result = type;
|
|
1572
|
+
}
|
|
1573
|
+
if ((0, reflection_1.isDynamicType)(type)) {
|
|
1574
|
+
result = type;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
return result !== null && result !== void 0 ? result : DynamicType_1.DynamicType.instance;
|
|
1578
|
+
}
|
|
1579
|
+
/**
|
|
1580
|
+
* Return the type of the result of a unary operator
|
|
1581
|
+
*/
|
|
1582
|
+
unaryOperatorResultType(operator, exprType) {
|
|
1583
|
+
if ((0, reflection_1.isUnionType)(exprType)) {
|
|
1584
|
+
exprType = this.getHighestPriorityType(exprType.types);
|
|
1585
|
+
}
|
|
1586
|
+
if ((0, reflection_1.isVoidType)(exprType) || (0, reflection_1.isInvalidTypeLike)(exprType) || (0, reflection_1.isUninitializedType)(exprType)) {
|
|
1587
|
+
return undefined;
|
|
1588
|
+
}
|
|
1589
|
+
if ((0, reflection_1.isDynamicType)(exprType) || (0, reflection_1.isObjectType)(exprType)) {
|
|
1590
|
+
return exprType;
|
|
1591
|
+
}
|
|
1592
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
1593
|
+
switch (operator.kind) {
|
|
1594
|
+
// Math operators
|
|
1595
|
+
case TokenKind_1.TokenKind.Plus: // (`num = +num` is valid syntax)
|
|
1596
|
+
case TokenKind_1.TokenKind.Minus:
|
|
1597
|
+
if ((0, reflection_1.isNumberTypeLike)(exprType)) {
|
|
1598
|
+
// a negative number will be the same type, eg, double->double, int->int, etc.
|
|
1599
|
+
return this.getUnboxedType(exprType);
|
|
1600
|
+
}
|
|
1601
|
+
break;
|
|
1602
|
+
case TokenKind_1.TokenKind.Not:
|
|
1603
|
+
if ((0, reflection_1.isBooleanTypeLike)(exprType)) {
|
|
1604
|
+
return BooleanType_1.BooleanType.instance;
|
|
1605
|
+
}
|
|
1606
|
+
else if ((0, reflection_1.isNumberTypeLike)(exprType)) {
|
|
1607
|
+
//numbers can be "notted"
|
|
1608
|
+
// by default they go to ints, except longints, which stay that way
|
|
1609
|
+
if ((0, reflection_1.isLongIntegerTypeLike)(exprType)) {
|
|
1610
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1611
|
+
}
|
|
1612
|
+
return IntegerType_1.IntegerType.instance;
|
|
1613
|
+
}
|
|
1614
|
+
break;
|
|
1615
|
+
}
|
|
1616
|
+
return undefined;
|
|
1617
|
+
}
|
|
1618
|
+
getUnboxedType(boxedType) {
|
|
1619
|
+
if ((0, reflection_1.isIntegerTypeLike)(boxedType)) {
|
|
1620
|
+
return IntegerType_1.IntegerType.instance;
|
|
1621
|
+
}
|
|
1622
|
+
else if ((0, reflection_1.isLongIntegerTypeLike)(boxedType)) {
|
|
1623
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1624
|
+
}
|
|
1625
|
+
else if ((0, reflection_1.isFloatTypeLike)(boxedType)) {
|
|
1626
|
+
return FloatType_1.FloatType.instance;
|
|
1627
|
+
}
|
|
1628
|
+
else if ((0, reflection_1.isDoubleTypeLike)(boxedType)) {
|
|
1629
|
+
return DoubleType_1.DoubleType.instance;
|
|
1630
|
+
}
|
|
1631
|
+
else if ((0, reflection_1.isBooleanTypeLike)(boxedType)) {
|
|
1632
|
+
return BooleanType_1.BooleanType.instance;
|
|
1633
|
+
}
|
|
1634
|
+
else if ((0, reflection_1.isStringTypeLike)(boxedType)) {
|
|
1635
|
+
return StringType_1.StringType.instance;
|
|
1636
|
+
}
|
|
1637
|
+
else if ((0, reflection_1.isInvalidTypeLike)(boxedType)) {
|
|
1638
|
+
return InvalidType_1.InvalidType.instance;
|
|
1639
|
+
}
|
|
1640
|
+
return boxedType;
|
|
931
1641
|
}
|
|
932
1642
|
/**
|
|
933
1643
|
* Get the extension for the given file path. Basically the part after the final dot, except for
|
|
934
1644
|
* `d.bs` which is treated as single extension
|
|
1645
|
+
* @returns the file extension (i.e. ".d.bs", ".bs", ".brs", ".xml", ".jpg", etc...)
|
|
935
1646
|
*/
|
|
936
1647
|
getExtension(filePath) {
|
|
937
1648
|
filePath = filePath.toLowerCase();
|
|
@@ -939,21 +1650,18 @@ class Util {
|
|
|
939
1650
|
return '.d.bs';
|
|
940
1651
|
}
|
|
941
1652
|
else {
|
|
942
|
-
|
|
943
|
-
if (idx > -1) {
|
|
944
|
-
return filePath.substring(idx);
|
|
945
|
-
}
|
|
1653
|
+
return path.extname(filePath).toLowerCase();
|
|
946
1654
|
}
|
|
947
1655
|
}
|
|
948
1656
|
/**
|
|
949
1657
|
* Load and return the list of plugins
|
|
950
1658
|
*/
|
|
951
1659
|
loadPlugins(cwd, pathOrModules, onError) {
|
|
952
|
-
const logger =
|
|
1660
|
+
const logger = (0, logging_1.createLogger)();
|
|
953
1661
|
return pathOrModules.reduce((acc, pathOrModule) => {
|
|
954
1662
|
if (typeof pathOrModule === 'string') {
|
|
955
1663
|
try {
|
|
956
|
-
const loaded =
|
|
1664
|
+
const loaded = requireRelative(pathOrModule, cwd);
|
|
957
1665
|
const theExport = loaded.default ? loaded.default : loaded;
|
|
958
1666
|
let plugin;
|
|
959
1667
|
// legacy plugins returned a plugin object. If we find that, then add a warning
|
|
@@ -963,7 +1671,13 @@ class Util {
|
|
|
963
1671
|
// the official plugin format is a factory function that returns a new instance of a plugin.
|
|
964
1672
|
}
|
|
965
1673
|
else if (typeof theExport === 'function') {
|
|
966
|
-
plugin = theExport(
|
|
1674
|
+
plugin = theExport({
|
|
1675
|
+
version: this.getBrighterScriptVersion()
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1678
|
+
else {
|
|
1679
|
+
//this should never happen; somehow an invalid plugin has made it into here
|
|
1680
|
+
throw new Error(`TILT: Encountered an invalid plugin: ${String(plugin)}`);
|
|
967
1681
|
}
|
|
968
1682
|
if (!plugin.name) {
|
|
969
1683
|
plugin.name = pathOrModule;
|
|
@@ -982,45 +1696,45 @@ class Util {
|
|
|
982
1696
|
return acc;
|
|
983
1697
|
}, []);
|
|
984
1698
|
}
|
|
985
|
-
resolveRequire(cwd, pathOrModule) {
|
|
986
|
-
let target = pathOrModule;
|
|
987
|
-
if (!path.isAbsolute(pathOrModule)) {
|
|
988
|
-
const localPath = path.resolve(cwd, pathOrModule);
|
|
989
|
-
if (fs.existsSync(localPath)) {
|
|
990
|
-
target = localPath;
|
|
991
|
-
}
|
|
992
|
-
else {
|
|
993
|
-
const modulePath = path.resolve(cwd, 'node_modules', pathOrModule);
|
|
994
|
-
if (fs.existsSync(modulePath)) {
|
|
995
|
-
target = modulePath;
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
// eslint-disable-next-line
|
|
1000
|
-
return require(target);
|
|
1001
|
-
}
|
|
1002
1699
|
/**
|
|
1003
1700
|
* Gathers expressions, variables, and unique names from an expression.
|
|
1004
1701
|
* This is mostly used for the ternary expression
|
|
1005
1702
|
*/
|
|
1006
|
-
getExpressionInfo(expression) {
|
|
1703
|
+
getExpressionInfo(expression, file) {
|
|
1007
1704
|
const expressions = [expression];
|
|
1008
1705
|
const variableExpressions = [];
|
|
1009
1706
|
const uniqueVarNames = new Set();
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
expression === null || expression === void 0 ? void 0 : expression.walk((expression) => {
|
|
1013
|
-
if (astUtils_1.isExpression(expression)) {
|
|
1707
|
+
function expressionWalker(expression) {
|
|
1708
|
+
if ((0, reflection_1.isExpression)(expression)) {
|
|
1014
1709
|
expressions.push(expression);
|
|
1015
1710
|
}
|
|
1016
|
-
if (
|
|
1711
|
+
if ((0, reflection_1.isVariableExpression)(expression)) {
|
|
1017
1712
|
variableExpressions.push(expression);
|
|
1018
|
-
uniqueVarNames.add(expression.name.text);
|
|
1713
|
+
uniqueVarNames.add(expression.tokens.name.text);
|
|
1019
1714
|
}
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1715
|
+
}
|
|
1716
|
+
// Collect all expressions. Most of these expressions are fairly small so this should be quick!
|
|
1717
|
+
// This should only be called during transpile time and only when we actually need it.
|
|
1718
|
+
expression === null || expression === void 0 ? void 0 : expression.walk(expressionWalker, {
|
|
1719
|
+
walkMode: visitors_1.WalkMode.visitExpressions
|
|
1022
1720
|
});
|
|
1023
|
-
|
|
1721
|
+
//handle the expression itself (for situations when expression is a VariableExpression)
|
|
1722
|
+
expressionWalker(expression);
|
|
1723
|
+
const scope = file.program.getFirstScopeForFile(file);
|
|
1724
|
+
let filteredVarNames = [...uniqueVarNames];
|
|
1725
|
+
if (scope) {
|
|
1726
|
+
filteredVarNames = filteredVarNames.filter((varName) => {
|
|
1727
|
+
const varNameLower = varName.toLowerCase();
|
|
1728
|
+
// TODO: include namespaces in this filter
|
|
1729
|
+
return !scope.getEnumMap().has(varNameLower) &&
|
|
1730
|
+
!scope.getConstMap().has(varNameLower);
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
return { expressions: expressions, varExpressions: variableExpressions, uniqueVarNames: filteredVarNames };
|
|
1734
|
+
}
|
|
1735
|
+
concatAnnotationLeadingTrivia(stmt) {
|
|
1736
|
+
var _a, _b;
|
|
1737
|
+
return [...((_b = (_a = stmt.annotations) === null || _a === void 0 ? void 0 : _a.map(anno => { var _a; return (_a = anno.leadingTrivia) !== null && _a !== void 0 ? _a : []; }).flat()) !== null && _b !== void 0 ? _b : []), ...stmt.leadingTrivia];
|
|
1024
1738
|
}
|
|
1025
1739
|
/**
|
|
1026
1740
|
* Create a SourceNode that maps every line to itself. Useful for creating maps for files
|
|
@@ -1037,129 +1751,105 @@ class Util {
|
|
|
1037
1751
|
return new source_map_1.SourceNode(null, null, source, chunks);
|
|
1038
1752
|
}
|
|
1039
1753
|
/**
|
|
1040
|
-
*
|
|
1754
|
+
* Converts a path into a standardized format (drive letter to lower, remove extra slashes, use single slash type, resolve relative parts, etc...)
|
|
1041
1755
|
*/
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
* Shorthand for creating a new source node
|
|
1047
|
-
*/
|
|
1048
|
-
sourceNode(source, locatable, code) {
|
|
1049
|
-
if (code !== undefined) {
|
|
1050
|
-
const node = new source_map_1.SourceNode(null, null, source, code);
|
|
1051
|
-
if (locatable.range) {
|
|
1052
|
-
//convert 0-based Range line to 1-based SourceNode line
|
|
1053
|
-
node.line = locatable.range.start.line + 1;
|
|
1054
|
-
//SourceNode columns are 0-based so no conversion necessary
|
|
1055
|
-
node.column = locatable.range.start.character;
|
|
1056
|
-
}
|
|
1057
|
-
return node;
|
|
1756
|
+
standardizePath(thePath) {
|
|
1757
|
+
//if we have the value in cache already, return it
|
|
1758
|
+
if (this.standardizePathCache.has(thePath)) {
|
|
1759
|
+
return this.standardizePathCache.get(thePath);
|
|
1058
1760
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
*/
|
|
1063
|
-
removeProtocol(pkgPath) {
|
|
1064
|
-
let match = /^[-a-z_]+:\//.exec(pkgPath);
|
|
1065
|
-
if (match) {
|
|
1066
|
-
return pkgPath.substring(match[0].length);
|
|
1761
|
+
const originalPath = thePath;
|
|
1762
|
+
if (typeof thePath !== 'string') {
|
|
1763
|
+
return thePath;
|
|
1067
1764
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1765
|
+
//handle `virtual:/` paths specially - just normalize slashes, don't use path.normalize which would mangle the `virtual:` prefix
|
|
1766
|
+
if (/^virtual:[\/\\]/i.test(thePath)) {
|
|
1767
|
+
// Strip the `virtual:` prefix, normalize slashes, then re-add the prefix
|
|
1768
|
+
thePath = 'virtual:/' + thePath.slice(8).replace(/^[\/\\]+/, '').replace(/[\/\\]+/g, '/').toLowerCase();
|
|
1769
|
+
this.standardizePathCache.set(originalPath, thePath);
|
|
1770
|
+
return thePath;
|
|
1070
1771
|
}
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
const bslib = require('@rokucommunity/bslib');
|
|
1083
|
-
let source = bslib.source;
|
|
1084
|
-
//apply the `bslib_` prefix to the functions
|
|
1085
|
-
let match;
|
|
1086
|
-
const positions = [];
|
|
1087
|
-
const regexp = /^(\s*(?:function|sub)\s+)([a-z0-9_]+)/mg;
|
|
1088
|
-
// eslint-disable-next-line no-cond-assign
|
|
1089
|
-
while (match = regexp.exec(source)) {
|
|
1090
|
-
positions.push(match.index + match[1].length);
|
|
1772
|
+
//windows path.normalize will convert all slashes to backslashes and remove duplicates
|
|
1773
|
+
if (this.isWindows) {
|
|
1774
|
+
thePath = path.win32.normalize(thePath);
|
|
1775
|
+
}
|
|
1776
|
+
else {
|
|
1777
|
+
//replace all windows or consecutive slashes with path.sep
|
|
1778
|
+
thePath = thePath.replace(/[\/\\]+/g, '/');
|
|
1779
|
+
// only use path.normalize if dots are present since it's expensive
|
|
1780
|
+
if (thePath.includes('./')) {
|
|
1781
|
+
thePath = path.posix.normalize(thePath);
|
|
1782
|
+
}
|
|
1091
1783
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1784
|
+
// Lowercase drive letter on Windows-like paths (e.g., "C:/...")
|
|
1785
|
+
if (thePath.charCodeAt(1) === 58 /* : */) {
|
|
1786
|
+
// eslint-disable-next-line no-var
|
|
1787
|
+
var firstChar = thePath.charCodeAt(0);
|
|
1788
|
+
if (firstChar >= 65 && firstChar <= 90) {
|
|
1789
|
+
thePath = String.fromCharCode(firstChar + 32) + thePath.slice(1);
|
|
1790
|
+
}
|
|
1095
1791
|
}
|
|
1096
|
-
|
|
1792
|
+
this.standardizePathCache.set(originalPath, thePath);
|
|
1793
|
+
return thePath;
|
|
1097
1794
|
}
|
|
1098
1795
|
/**
|
|
1099
|
-
* Given a Diagnostic or BsDiagnostic, return a
|
|
1796
|
+
* Given a Diagnostic or BsDiagnostic, return a deep clone of the diagnostic.
|
|
1797
|
+
* @param diagnostic the diagnostic to clone
|
|
1798
|
+
* @param relatedInformationFallbackLocation a default location to use for all `relatedInformation` entries that are missing a location
|
|
1100
1799
|
*/
|
|
1101
|
-
toDiagnostic(diagnostic) {
|
|
1102
|
-
var _a;
|
|
1103
|
-
|
|
1800
|
+
toDiagnostic(diagnostic, relatedInformationFallbackLocation) {
|
|
1801
|
+
var _a, _b, _c, _d, _e;
|
|
1802
|
+
let relatedInformation = (_a = diagnostic.relatedInformation) !== null && _a !== void 0 ? _a : [];
|
|
1803
|
+
if (relatedInformation.length > diagnosticUtils_1.MAX_RELATED_INFOS_COUNT) {
|
|
1804
|
+
const relatedInfoLength = relatedInformation.length;
|
|
1805
|
+
relatedInformation = relatedInformation.slice(0, diagnosticUtils_1.MAX_RELATED_INFOS_COUNT);
|
|
1806
|
+
relatedInformation.push({
|
|
1807
|
+
message: `...and ${relatedInfoLength - diagnosticUtils_1.MAX_RELATED_INFOS_COUNT} more`,
|
|
1808
|
+
location: exports.util.createLocationFromRange(' ', exports.util.createRange(0, 0, 0, 0))
|
|
1809
|
+
});
|
|
1810
|
+
}
|
|
1811
|
+
const range = (_c = (_b = diagnostic.location) === null || _b === void 0 ? void 0 : _b.range) !== null && _c !== void 0 ? _c : diagnostic.range;
|
|
1812
|
+
let result = {
|
|
1104
1813
|
severity: diagnostic.severity,
|
|
1105
|
-
range:
|
|
1814
|
+
range: range,
|
|
1106
1815
|
message: diagnostic.message,
|
|
1107
|
-
relatedInformation:
|
|
1816
|
+
relatedInformation: relatedInformation.map(x => {
|
|
1108
1817
|
//clone related information just in case a plugin added circular ref info here
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1818
|
+
const clone = Object.assign({}, x);
|
|
1819
|
+
if (!clone.location) {
|
|
1820
|
+
// use the fallback location if available
|
|
1821
|
+
if (relatedInformationFallbackLocation) {
|
|
1822
|
+
clone.location = exports.util.createLocationFromRange(relatedInformationFallbackLocation, range);
|
|
1823
|
+
}
|
|
1824
|
+
else {
|
|
1825
|
+
//remove this related information so it doesn't bring crash the language server
|
|
1826
|
+
return undefined;
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
return clone;
|
|
1830
|
+
//filter out null relatedInformation items
|
|
1831
|
+
}).filter((x) => Boolean(x)),
|
|
1832
|
+
code: diagnostic.code ? diagnostic.code : diagnostic.legacyCode,
|
|
1833
|
+
source: (_d = diagnostic.source) !== null && _d !== void 0 ? _d : 'brs'
|
|
1113
1834
|
};
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
* Gets the minimum and maximum number of allowed params
|
|
1117
|
-
* @param params The list of callable parameters to check
|
|
1118
|
-
* @returns the minimum and maximum number of allowed params
|
|
1119
|
-
*/
|
|
1120
|
-
getMinMaxParamCount(params) {
|
|
1121
|
-
//get min/max parameter count for callable
|
|
1122
|
-
let minParams = 0;
|
|
1123
|
-
let maxParams = 0;
|
|
1124
|
-
let continueCheckingForRequired = true;
|
|
1125
|
-
for (let param of params) {
|
|
1126
|
-
maxParams++;
|
|
1127
|
-
//optional parameters must come last, so we can assume that minParams won't increase once we hit
|
|
1128
|
-
//the first isOptional
|
|
1129
|
-
if (continueCheckingForRequired && !param.isOptional) {
|
|
1130
|
-
minParams++;
|
|
1131
|
-
}
|
|
1132
|
-
else {
|
|
1133
|
-
continueCheckingForRequired = false;
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
return { min: minParams, max: maxParams };
|
|
1137
|
-
}
|
|
1138
|
-
/**
|
|
1139
|
-
* Finds the array of callables from a container map, taking into account the function from which it was called
|
|
1140
|
-
* If the callable was called in a function in a namespace, functions in that namespace are preferred
|
|
1141
|
-
* @return an array with callable containers - could be empty if nothing was found
|
|
1142
|
-
*/
|
|
1143
|
-
getCallableContainersFromContainerMapByFunctionCall(callablesByLowerName, expCall) {
|
|
1144
|
-
let callablesWithThisName = [];
|
|
1145
|
-
const lowerName = expCall.name.toLowerCase();
|
|
1146
|
-
if (expCall.functionExpression.namespaceName) {
|
|
1147
|
-
// prefer namespaced function
|
|
1148
|
-
const potentialNamespacedCallable = expCall.functionExpression.namespaceName.getName(Parser_1.ParseMode.BrightScript).toLowerCase() + '_' + lowerName;
|
|
1149
|
-
callablesWithThisName = callablesByLowerName.get(potentialNamespacedCallable.toLowerCase());
|
|
1835
|
+
if (((_e = diagnostic === null || diagnostic === void 0 ? void 0 : diagnostic.tags) === null || _e === void 0 ? void 0 : _e.length) > 0) {
|
|
1836
|
+
result.tags = diagnostic.tags;
|
|
1150
1837
|
}
|
|
1151
|
-
|
|
1152
|
-
// just try it as is
|
|
1153
|
-
callablesWithThisName = callablesByLowerName.get(lowerName);
|
|
1154
|
-
}
|
|
1155
|
-
return callablesWithThisName;
|
|
1838
|
+
return result;
|
|
1156
1839
|
}
|
|
1157
1840
|
/**
|
|
1158
1841
|
* Sort an array of objects that have a Range
|
|
1159
1842
|
*/
|
|
1160
1843
|
sortByRange(locatables) {
|
|
1161
1844
|
//sort the tokens by range
|
|
1162
|
-
return locatables.sort((a, b) => {
|
|
1845
|
+
return locatables === null || locatables === void 0 ? void 0 : locatables.sort((a, b) => {
|
|
1846
|
+
//handle undefined tokens to prevent crashes
|
|
1847
|
+
if (!(a === null || a === void 0 ? void 0 : a.range)) {
|
|
1848
|
+
return 1;
|
|
1849
|
+
}
|
|
1850
|
+
if (!(b === null || b === void 0 ? void 0 : b.range)) {
|
|
1851
|
+
return -1;
|
|
1852
|
+
}
|
|
1163
1853
|
//start line
|
|
1164
1854
|
if (a.range.start.line < b.range.start.line) {
|
|
1165
1855
|
return -1;
|
|
@@ -1192,26 +1882,779 @@ class Util {
|
|
|
1192
1882
|
});
|
|
1193
1883
|
}
|
|
1194
1884
|
/**
|
|
1195
|
-
*
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1885
|
+
* Wrap the given code in a markdown code fence (with the language)
|
|
1886
|
+
*/
|
|
1887
|
+
mdFence(code, language = '') {
|
|
1888
|
+
return '```' + language + '\n' + code + '\n```';
|
|
1889
|
+
}
|
|
1890
|
+
/**
|
|
1891
|
+
* Gets each part of the dotted get.
|
|
1892
|
+
* @param node any ast expression
|
|
1893
|
+
* @returns an array of the parts of the dotted get. If not fully a dotted get, then returns undefined
|
|
1894
|
+
*/
|
|
1895
|
+
getAllDottedGetParts(node) {
|
|
1896
|
+
//this is a hot function and has been optimized. Don't rewrite unless necessary
|
|
1897
|
+
const parts = [];
|
|
1898
|
+
let nextPart = node;
|
|
1899
|
+
loop: while (nextPart) {
|
|
1900
|
+
switch (nextPart === null || nextPart === void 0 ? void 0 : nextPart.kind) {
|
|
1901
|
+
case AstNode_1.AstNodeKind.AssignmentStatement:
|
|
1902
|
+
return [node.tokens.name];
|
|
1903
|
+
case AstNode_1.AstNodeKind.DottedGetExpression:
|
|
1904
|
+
parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.tokens.name);
|
|
1905
|
+
nextPart = nextPart.obj;
|
|
1906
|
+
continue;
|
|
1907
|
+
case AstNode_1.AstNodeKind.CallExpression:
|
|
1908
|
+
nextPart = nextPart.callee;
|
|
1909
|
+
continue;
|
|
1910
|
+
case AstNode_1.AstNodeKind.CallfuncExpression:
|
|
1911
|
+
parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.tokens.methodName);
|
|
1912
|
+
nextPart = nextPart.callee;
|
|
1913
|
+
continue;
|
|
1914
|
+
case AstNode_1.AstNodeKind.TypeExpression:
|
|
1915
|
+
nextPart = nextPart.expression;
|
|
1916
|
+
continue;
|
|
1917
|
+
case AstNode_1.AstNodeKind.VariableExpression:
|
|
1918
|
+
parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.tokens.name);
|
|
1919
|
+
break loop;
|
|
1920
|
+
case AstNode_1.AstNodeKind.LiteralExpression:
|
|
1921
|
+
parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.tokens.value);
|
|
1922
|
+
break loop;
|
|
1923
|
+
case AstNode_1.AstNodeKind.IndexedGetExpression:
|
|
1924
|
+
nextPart = nextPart.obj;
|
|
1925
|
+
continue;
|
|
1926
|
+
case AstNode_1.AstNodeKind.FunctionParameterExpression:
|
|
1927
|
+
return [nextPart.tokens.name];
|
|
1928
|
+
case AstNode_1.AstNodeKind.GroupingExpression:
|
|
1929
|
+
parts.push((0, creators_1.createIdentifier)('()', nextPart.location));
|
|
1930
|
+
break loop;
|
|
1931
|
+
default:
|
|
1932
|
+
//we found a non-DottedGet expression, so return because this whole operation is invalid.
|
|
1933
|
+
return undefined;
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
return parts.reverse();
|
|
1937
|
+
}
|
|
1938
|
+
/**
|
|
1939
|
+
* Given an expression, return all the DottedGet name parts as a string.
|
|
1940
|
+
* Mostly used to convert namespaced item full names to a strings
|
|
1941
|
+
*/
|
|
1942
|
+
getAllDottedGetPartsAsString(node, parseMode = Parser_1.ParseMode.BrighterScript, lastSep = '.') {
|
|
1943
|
+
var _a, _b;
|
|
1944
|
+
//this is a hot function and has been optimized. Don't rewrite unless necessary
|
|
1945
|
+
/* eslint-disable no-var */
|
|
1946
|
+
var sep = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
|
|
1947
|
+
const parts = (_a = this.getAllDottedGetParts(node)) !== null && _a !== void 0 ? _a : [];
|
|
1948
|
+
var result = (_b = parts[0]) === null || _b === void 0 ? void 0 : _b.text;
|
|
1949
|
+
for (var i = 1; i < parts.length; i++) {
|
|
1950
|
+
result += (i === parts.length - 1 && parseMode === Parser_1.ParseMode.BrighterScript ? lastSep : sep) + parts[i].text;
|
|
1951
|
+
}
|
|
1952
|
+
return result;
|
|
1953
|
+
/* eslint-enable no-var */
|
|
1954
|
+
}
|
|
1955
|
+
/**
|
|
1956
|
+
* Break an expression into each part.
|
|
1957
|
+
*/
|
|
1958
|
+
splitExpression(expression) {
|
|
1959
|
+
const parts = [expression];
|
|
1960
|
+
let nextPart = expression;
|
|
1961
|
+
while (nextPart) {
|
|
1962
|
+
if ((0, reflection_1.isDottedGetExpression)(nextPart) || (0, reflection_1.isIndexedGetExpression)(nextPart) || (0, reflection_1.isXmlAttributeGetExpression)(nextPart)) {
|
|
1963
|
+
nextPart = nextPart.obj;
|
|
1964
|
+
}
|
|
1965
|
+
else if ((0, reflection_1.isCallExpression)(nextPart) || (0, reflection_1.isCallfuncExpression)(nextPart)) {
|
|
1966
|
+
nextPart = nextPart.callee;
|
|
1967
|
+
}
|
|
1968
|
+
else if ((0, reflection_1.isTypeExpression)(nextPart)) {
|
|
1969
|
+
nextPart = nextPart.expression;
|
|
1970
|
+
}
|
|
1971
|
+
else {
|
|
1972
|
+
break;
|
|
1973
|
+
}
|
|
1974
|
+
parts.unshift(nextPart);
|
|
1975
|
+
}
|
|
1976
|
+
return parts;
|
|
1977
|
+
}
|
|
1978
|
+
/**
|
|
1979
|
+
* Returns an integer if valid, or undefined. Eliminates checking for NaN
|
|
1980
|
+
*/
|
|
1981
|
+
parseInt(value) {
|
|
1982
|
+
const result = parseInt(value);
|
|
1983
|
+
if (!isNaN(result)) {
|
|
1984
|
+
return result;
|
|
1985
|
+
}
|
|
1986
|
+
else {
|
|
1987
|
+
return undefined;
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
/**
|
|
1991
|
+
* Converts a range to a string in the format 1:2-3:4
|
|
1992
|
+
*/
|
|
1993
|
+
rangeToString(range) {
|
|
1994
|
+
var _a, _b, _c, _d;
|
|
1995
|
+
return `${(_a = range === null || range === void 0 ? void 0 : range.start) === null || _a === void 0 ? void 0 : _a.line}:${(_b = range === null || range === void 0 ? void 0 : range.start) === null || _b === void 0 ? void 0 : _b.character}-${(_c = range === null || range === void 0 ? void 0 : range.end) === null || _c === void 0 ? void 0 : _c.line}:${(_d = range === null || range === void 0 ? void 0 : range.end) === null || _d === void 0 ? void 0 : _d.character}`;
|
|
1996
|
+
}
|
|
1997
|
+
validateTooDeepFile(file) {
|
|
1998
|
+
var _a, _b;
|
|
1999
|
+
//find any files nested too deep
|
|
2000
|
+
let destPath = (_a = file === null || file === void 0 ? void 0 : file.destPath) === null || _a === void 0 ? void 0 : _a.toString();
|
|
2001
|
+
let rootFolder = destPath === null || destPath === void 0 ? void 0 : destPath.replace(/^pkg:/, '').split(/[\\\/]/)[0].toLowerCase();
|
|
2002
|
+
if ((0, reflection_1.isBrsFile)(file) && rootFolder !== 'source') {
|
|
2003
|
+
return;
|
|
2004
|
+
}
|
|
2005
|
+
if ((0, reflection_1.isXmlFile)(file) && rootFolder !== 'components') {
|
|
2006
|
+
return;
|
|
2007
|
+
}
|
|
2008
|
+
let fileDepth = this.getParentDirectoryCount(destPath);
|
|
2009
|
+
if (fileDepth >= 8) {
|
|
2010
|
+
(_b = file.program) === null || _b === void 0 ? void 0 : _b.diagnostics.register(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.detectedTooDeepFileSource(fileDepth)), { location: exports.util.createLocationFromFileRange(file, this.createRange(0, 0, 0, Number.MAX_VALUE)) }));
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
/**
|
|
2014
|
+
* Execute dispose for a series of disposable items
|
|
2015
|
+
* @param disposables a list of functions or disposables
|
|
2016
|
+
*/
|
|
2017
|
+
applyDispose(disposables) {
|
|
2018
|
+
var _a;
|
|
2019
|
+
for (const disposable of disposables !== null && disposables !== void 0 ? disposables : []) {
|
|
2020
|
+
if (typeof disposable === 'function') {
|
|
2021
|
+
disposable();
|
|
2022
|
+
}
|
|
2023
|
+
else {
|
|
2024
|
+
(_a = disposable === null || disposable === void 0 ? void 0 : disposable.dispose) === null || _a === void 0 ? void 0 : _a.call(disposable);
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
/**
|
|
2029
|
+
* Race a series of promises, and return the first one that resolves AND matches the matcher function.
|
|
2030
|
+
* If all of the promises reject, then this will emit an AggregatreError with all of the errors.
|
|
2031
|
+
* If at least one promise resolves, then this will log all of the errors to the console
|
|
2032
|
+
* If at least one promise resolves but none of them match the matcher, then this will return undefined.
|
|
2033
|
+
* @param promises all of the promises to race
|
|
2034
|
+
* @param matcher a function that should return true if this value should be kept. Returning any value other than true means `false`
|
|
2035
|
+
* @returns the first resolved value that matches the matcher, or undefined if none of them match
|
|
2036
|
+
*/
|
|
2037
|
+
async promiseRaceMatch(promises, matcher) {
|
|
2038
|
+
const workingPromises = [
|
|
2039
|
+
...promises
|
|
2040
|
+
];
|
|
2041
|
+
const results = [];
|
|
2042
|
+
let returnValue;
|
|
2043
|
+
while (workingPromises.length > 0) {
|
|
2044
|
+
//race the promises. If any of them resolve, evaluate it against the matcher. If that passes, return the value. otherwise, eliminate this promise and try again
|
|
2045
|
+
const result = await Promise.race(workingPromises.map((promise, i) => {
|
|
2046
|
+
return Promise.resolve(promise)
|
|
2047
|
+
.then(value => ({ value: value, index: i }))
|
|
2048
|
+
.catch(error => ({ error: error, index: i }));
|
|
2049
|
+
}));
|
|
2050
|
+
results.push(result);
|
|
2051
|
+
//if we got a value and it matches the matcher, return it
|
|
2052
|
+
if ('value' in result && (matcher === null || matcher === void 0 ? void 0 : matcher(result.value)) === true) {
|
|
2053
|
+
returnValue = result.value;
|
|
2054
|
+
break;
|
|
2055
|
+
}
|
|
2056
|
+
//remove this non-matched (or errored) promise from the list and try again
|
|
2057
|
+
workingPromises.splice(result.index, 1);
|
|
2058
|
+
}
|
|
2059
|
+
const errors = results
|
|
2060
|
+
.filter(x => 'error' in x)
|
|
2061
|
+
.map(x => x.error);
|
|
2062
|
+
//if all of them crashed, then reject
|
|
2063
|
+
if (promises.length > 0 && errors.length === promises.length) {
|
|
2064
|
+
throw new AggregateError(errors, 'All requests failed. First error message: ' + errors[0].message);
|
|
2065
|
+
}
|
|
2066
|
+
else {
|
|
2067
|
+
//log all of the errors
|
|
2068
|
+
for (const error of errors) {
|
|
2069
|
+
console.error(error);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
//return the matched value, or undefined if there wasn't one
|
|
2073
|
+
return returnValue;
|
|
2074
|
+
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Wraps SourceNode's constructor to be compatible with the TranspileResult type
|
|
2077
|
+
*/
|
|
2078
|
+
sourceNodeFromTranspileResult(line, column, source, chunks, name) {
|
|
2079
|
+
// we can use a typecast rather than actually transforming the data because SourceNode
|
|
2080
|
+
// accepts a more permissive type than its typedef states
|
|
2081
|
+
return new source_map_1.SourceNode(line, column, source, chunks, name);
|
|
2082
|
+
}
|
|
2083
|
+
/**
|
|
2084
|
+
* Find the index of the last item in the array that matches.
|
|
2085
|
+
*/
|
|
2086
|
+
findLastIndex(array, matcher) {
|
|
2087
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
2088
|
+
if (matcher(array[i])) {
|
|
2089
|
+
return i;
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
processTypeChain(typeChain) {
|
|
2094
|
+
var _a, _b, _c, _d, _e;
|
|
2095
|
+
let fullChainName = '';
|
|
2096
|
+
let fullErrorName = '';
|
|
2097
|
+
let itemName = '';
|
|
2098
|
+
let previousTypeName = '';
|
|
2099
|
+
let parentTypeName = '';
|
|
2100
|
+
let itemTypeKind = '';
|
|
2101
|
+
let parentTypeKind = '';
|
|
2102
|
+
let astNode;
|
|
2103
|
+
let errorLocation;
|
|
2104
|
+
let containsDynamic = false;
|
|
2105
|
+
let continueResolvingAllItems = true;
|
|
2106
|
+
let crossedCallFunc = false;
|
|
2107
|
+
for (let i = 0; i < typeChain.length; i++) {
|
|
2108
|
+
const chainItem = typeChain[i];
|
|
2109
|
+
const dotSep = (_b = (_a = chainItem.separatorToken) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '.';
|
|
2110
|
+
if (i > 0) {
|
|
2111
|
+
fullChainName += dotSep;
|
|
2112
|
+
}
|
|
2113
|
+
fullChainName += chainItem.name;
|
|
2114
|
+
if (continueResolvingAllItems) {
|
|
2115
|
+
parentTypeName = previousTypeName;
|
|
2116
|
+
parentTypeKind = itemTypeKind;
|
|
2117
|
+
fullErrorName = previousTypeName ? `${previousTypeName}${dotSep}${chainItem.name}` : chainItem.name;
|
|
2118
|
+
itemTypeKind = (_c = chainItem.type) === null || _c === void 0 ? void 0 : _c.kind;
|
|
2119
|
+
let typeString = (_d = chainItem.type) === null || _d === void 0 ? void 0 : _d.toString();
|
|
2120
|
+
let typeToFindStringFor = chainItem.type;
|
|
2121
|
+
while (typeToFindStringFor) {
|
|
2122
|
+
if ((0, reflection_1.isCompoundType)(chainItem.type)) {
|
|
2123
|
+
typeString = `(${typeToFindStringFor.toString()})`;
|
|
2124
|
+
break;
|
|
2125
|
+
}
|
|
2126
|
+
else if ((0, reflection_1.isCallableType)(typeToFindStringFor)) {
|
|
2127
|
+
if ((0, reflection_1.isTypedFunctionType)(typeToFindStringFor) && i < typeChain.length - 1) {
|
|
2128
|
+
typeToFindStringFor = typeToFindStringFor.returnType;
|
|
2129
|
+
}
|
|
2130
|
+
else {
|
|
2131
|
+
typeString = 'function';
|
|
2132
|
+
break;
|
|
2133
|
+
}
|
|
2134
|
+
parentTypeName = previousTypeName;
|
|
2135
|
+
}
|
|
2136
|
+
else if ((0, reflection_1.isNamespaceType)(typeToFindStringFor) && parentTypeName) {
|
|
2137
|
+
const chainItemTypeName = typeToFindStringFor.toString();
|
|
2138
|
+
typeString = parentTypeName + '.' + chainItemTypeName;
|
|
2139
|
+
if (chainItemTypeName.toLowerCase().startsWith(parentTypeName.toLowerCase())) {
|
|
2140
|
+
// the following namespace already knows...
|
|
2141
|
+
typeString = chainItemTypeName;
|
|
2142
|
+
}
|
|
2143
|
+
break;
|
|
2144
|
+
}
|
|
2145
|
+
else {
|
|
2146
|
+
typeString = typeToFindStringFor === null || typeToFindStringFor === void 0 ? void 0 : typeToFindStringFor.toString();
|
|
2147
|
+
break;
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
previousTypeName = typeString !== null && typeString !== void 0 ? typeString : '';
|
|
2151
|
+
itemName = chainItem.name;
|
|
2152
|
+
astNode = chainItem.astNode;
|
|
2153
|
+
containsDynamic = containsDynamic || ((0, reflection_1.isDynamicType)(chainItem.type) && !(0, reflection_1.isAnyReferenceType)(chainItem.type));
|
|
2154
|
+
crossedCallFunc = crossedCallFunc || ((_e = chainItem.data) === null || _e === void 0 ? void 0 : _e.isFromCallFunc);
|
|
2155
|
+
if (!chainItem.isResolved) {
|
|
2156
|
+
errorLocation = chainItem.location;
|
|
2157
|
+
continueResolvingAllItems = false;
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
return {
|
|
2162
|
+
itemName: itemName,
|
|
2163
|
+
itemTypeKind: itemTypeKind,
|
|
2164
|
+
itemParentTypeName: parentTypeName,
|
|
2165
|
+
itemParentTypeKind: parentTypeKind,
|
|
2166
|
+
fullNameOfItem: fullErrorName,
|
|
2167
|
+
fullChainName: fullChainName,
|
|
2168
|
+
location: errorLocation,
|
|
2169
|
+
containsDynamic: containsDynamic,
|
|
2170
|
+
astNode: astNode,
|
|
2171
|
+
crossedCallFunc: crossedCallFunc
|
|
2172
|
+
};
|
|
2173
|
+
}
|
|
2174
|
+
getCircularReferenceDiagnosticDetail(circularReferenceInfo, defaultName = '') {
|
|
2175
|
+
if (!circularReferenceInfo || !circularReferenceInfo.referenceChainNames) {
|
|
2176
|
+
if (defaultName) {
|
|
2177
|
+
return [defaultName];
|
|
2178
|
+
}
|
|
2179
|
+
return [];
|
|
2180
|
+
}
|
|
2181
|
+
if (circularReferenceInfo.referenceChainNames[0] === circularReferenceInfo.referenceChainNames[circularReferenceInfo.referenceChainNames.length - 1]) {
|
|
2182
|
+
// last element is same as first it will read okay
|
|
2183
|
+
return circularReferenceInfo.referenceChainNames;
|
|
2184
|
+
}
|
|
2185
|
+
return [...circularReferenceInfo.referenceChainNames, circularReferenceInfo.referenceChainNames[0]];
|
|
2186
|
+
}
|
|
2187
|
+
isInTypeExpression(expression) {
|
|
2188
|
+
//TODO: this is much faster than node.findAncestor(), but may need to be updated for "complicated" type expressions
|
|
2189
|
+
if ((0, reflection_1.isTypeExpression)(expression) ||
|
|
2190
|
+
(0, reflection_1.isTypeExpression)(expression === null || expression === void 0 ? void 0 : expression.parent) ||
|
|
2191
|
+
(0, reflection_1.isTypedArrayExpression)(expression) ||
|
|
2192
|
+
(0, reflection_1.isTypedArrayExpression)(expression === null || expression === void 0 ? void 0 : expression.parent)) {
|
|
2193
|
+
return true;
|
|
2194
|
+
}
|
|
2195
|
+
if ((0, reflection_1.isBinaryExpression)(expression === null || expression === void 0 ? void 0 : expression.parent)) {
|
|
2196
|
+
let currentExpr = expression.parent;
|
|
2197
|
+
while ((0, reflection_1.isBinaryExpression)(currentExpr) && (currentExpr.tokens.operator.kind === TokenKind_1.TokenKind.Or || currentExpr.tokens.operator.kind === TokenKind_1.TokenKind.And)) {
|
|
2198
|
+
currentExpr = currentExpr.parent;
|
|
2199
|
+
}
|
|
2200
|
+
return (0, reflection_1.isTypeExpression)(currentExpr) || (0, reflection_1.isTypedArrayExpression)(currentExpr);
|
|
2201
|
+
}
|
|
2202
|
+
return false;
|
|
2203
|
+
}
|
|
2204
|
+
isGenericNodeType(type) {
|
|
2205
|
+
if ((0, reflection_1.isComponentType)(type)) {
|
|
2206
|
+
const lowerName = type.toString().toLowerCase();
|
|
2207
|
+
if (lowerName === 'rosgnode' || lowerName === 'rosgnodenode') {
|
|
2208
|
+
return true;
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
return false;
|
|
2212
|
+
}
|
|
2213
|
+
hasAnyRequiredSymbolChanged(requiredSymbols, changedSymbols) {
|
|
2214
|
+
if (!requiredSymbols || !changedSymbols) {
|
|
2215
|
+
return false;
|
|
2216
|
+
}
|
|
2217
|
+
const runTimeChanges = changedSymbols.get(1 /* SymbolTypeFlag.runtime */);
|
|
2218
|
+
const typeTimeChanges = changedSymbols.get(2 /* SymbolTypeFlag.typetime */);
|
|
2219
|
+
for (const symbol of requiredSymbols) {
|
|
2220
|
+
if (this.setContainsUnresolvedSymbol(runTimeChanges, symbol) || this.setContainsUnresolvedSymbol(typeTimeChanges, symbol)) {
|
|
2221
|
+
return true;
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
return false;
|
|
2225
|
+
}
|
|
2226
|
+
setContainsUnresolvedSymbol(symbolLowerNameSet, symbol) {
|
|
2227
|
+
if (!symbolLowerNameSet || symbolLowerNameSet.size === 0) {
|
|
2228
|
+
return false;
|
|
2229
|
+
}
|
|
2230
|
+
for (const possibleNameLower of symbol.lookups) {
|
|
2231
|
+
if (symbolLowerNameSet.has(possibleNameLower)) {
|
|
2232
|
+
return true;
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
return false;
|
|
2236
|
+
}
|
|
2237
|
+
getCustomTypesInSymbolTree(setToFill, type, filter) {
|
|
2238
|
+
var _a, _b;
|
|
2239
|
+
const subSymbolTypes = (0, reflection_1.isCompoundType)(type)
|
|
2240
|
+
? type.types
|
|
2241
|
+
: (_b = (_a = type.getMemberTable()) === null || _a === void 0 ? void 0 : _a.getAllSymbols(1 /* SymbolTypeFlag.runtime */).map(sym => sym.type)) !== null && _b !== void 0 ? _b : [];
|
|
2242
|
+
for (const subSymbolType of subSymbolTypes) {
|
|
2243
|
+
if (!(subSymbolType === null || subSymbolType === void 0 ? void 0 : subSymbolType.isBuiltIn) && !setToFill.has(subSymbolType)) {
|
|
2244
|
+
if (filter && !filter(subSymbolType)) {
|
|
2245
|
+
continue;
|
|
2246
|
+
}
|
|
2247
|
+
// if this is a custom type, and we haven't added it to the types to check to see if can add it to the additional types
|
|
2248
|
+
// add the type, and investigate any members
|
|
2249
|
+
setToFill.add(subSymbolType);
|
|
2250
|
+
this.getCustomTypesInSymbolTree(setToFill, subSymbolType, filter);
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
truncate(options) {
|
|
2255
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2256
|
+
let leadingText = options.leadingText;
|
|
2257
|
+
let items = (_a = options === null || options === void 0 ? void 0 : options.items) !== null && _a !== void 0 ? _a : [];
|
|
2258
|
+
let trailingText = (_b = options === null || options === void 0 ? void 0 : options.trailingText) !== null && _b !== void 0 ? _b : '';
|
|
2259
|
+
let maxLength = (_c = options === null || options === void 0 ? void 0 : options.maxLength) !== null && _c !== void 0 ? _c : 160;
|
|
2260
|
+
let itemSeparator = (_d = options === null || options === void 0 ? void 0 : options.itemSeparator) !== null && _d !== void 0 ? _d : ', ';
|
|
2261
|
+
let partBuilder = (_e = options === null || options === void 0 ? void 0 : options.partBuilder) !== null && _e !== void 0 ? _e : ((x) => x.toString());
|
|
2262
|
+
let parts = [];
|
|
2263
|
+
let length = leadingText.length + ((_f = trailingText === null || trailingText === void 0 ? void 0 : trailingText.length) !== null && _f !== void 0 ? _f : 0);
|
|
2264
|
+
//calculate the max number of items we could fit in the given space
|
|
2265
|
+
for (let i = 0; i < items.length; i++) {
|
|
2266
|
+
let part = partBuilder(items[i]);
|
|
2267
|
+
if (i > 0) {
|
|
2268
|
+
part = itemSeparator + part;
|
|
2269
|
+
}
|
|
2270
|
+
parts.push(part);
|
|
2271
|
+
length += part.length;
|
|
2272
|
+
//exit the loop if we've maxed out our length
|
|
2273
|
+
if (length >= maxLength) {
|
|
2274
|
+
break;
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
let message;
|
|
2278
|
+
//we have enough space to include all the parts
|
|
2279
|
+
if (parts.length >= items.length) {
|
|
2280
|
+
message = leadingText + parts.join('') + trailingText;
|
|
2281
|
+
//we require truncation
|
|
2282
|
+
}
|
|
2283
|
+
else {
|
|
2284
|
+
//account for truncation message length including max possible "more" items digits, trailing text length, and the separator between last item and trailing text
|
|
2285
|
+
length = leadingText.length + `...and ${items.length} more`.length + itemSeparator.length + ((_g = trailingText === null || trailingText === void 0 ? void 0 : trailingText.length) !== null && _g !== void 0 ? _g : 0);
|
|
2286
|
+
message = leadingText;
|
|
2287
|
+
for (let i = 0; i < parts.length; i++) {
|
|
2288
|
+
//always include at least 2 items. if this part would overflow the max, then skip it and finalize the message
|
|
2289
|
+
if (i > 1 && length + parts[i].length > maxLength) {
|
|
2290
|
+
message += itemSeparator + `...and ${items.length - i} more` + trailingText;
|
|
2291
|
+
return message;
|
|
2292
|
+
}
|
|
2293
|
+
else {
|
|
2294
|
+
message += parts[i];
|
|
2295
|
+
length += parts[i].length;
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
return message;
|
|
2300
|
+
}
|
|
2301
|
+
getAstNodeFriendlyName(node) {
|
|
2302
|
+
return node === null || node === void 0 ? void 0 : node.kind.replace(/Statement|Expression/g, '');
|
|
2303
|
+
}
|
|
2304
|
+
hasLeadingComments(input) {
|
|
2305
|
+
var _a;
|
|
2306
|
+
const leadingTrivia = (0, Token_1.isToken)(input) ? input === null || input === void 0 ? void 0 : input.leadingTrivia : (_a = input === null || input === void 0 ? void 0 : input.leadingTrivia) !== null && _a !== void 0 ? _a : [];
|
|
2307
|
+
return !!leadingTrivia.find(t => (t === null || t === void 0 ? void 0 : t.kind) === TokenKind_1.TokenKind.Comment);
|
|
2308
|
+
}
|
|
2309
|
+
getLeadingComments(input) {
|
|
2310
|
+
var _a;
|
|
2311
|
+
const leadingTrivia = (0, Token_1.isToken)(input) ? input === null || input === void 0 ? void 0 : input.leadingTrivia : (_a = input === null || input === void 0 ? void 0 : input.leadingTrivia) !== null && _a !== void 0 ? _a : [];
|
|
2312
|
+
return leadingTrivia.filter(t => (t === null || t === void 0 ? void 0 : t.kind) === TokenKind_1.TokenKind.Comment);
|
|
2313
|
+
}
|
|
2314
|
+
isLeadingCommentOnSameLine(line, input) {
|
|
2315
|
+
var _a;
|
|
2316
|
+
const leadingCommentRange = (_a = this.getLeadingComments(input)) === null || _a === void 0 ? void 0 : _a[0];
|
|
2317
|
+
if (leadingCommentRange) {
|
|
2318
|
+
return this.linesTouch(line, leadingCommentRange === null || leadingCommentRange === void 0 ? void 0 : leadingCommentRange.location);
|
|
2319
|
+
}
|
|
2320
|
+
return false;
|
|
2321
|
+
}
|
|
2322
|
+
isClassUsedAsFunction(potentialClassType, expression, options) {
|
|
2323
|
+
var _a, _b, _c;
|
|
2324
|
+
// eslint-disable-next-line no-bitwise
|
|
2325
|
+
if (((_a = options === null || options === void 0 ? void 0 : options.flags) !== null && _a !== void 0 ? _a : 0) & 1 /* SymbolTypeFlag.runtime */ &&
|
|
2326
|
+
(0, reflection_1.isClassType)(potentialClassType) &&
|
|
2327
|
+
!options.isExistenceTest &&
|
|
2328
|
+
((_b = potentialClassType.name) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === ((_c = this.getAllDottedGetPartsAsString(expression)) === null || _c === void 0 ? void 0 : _c.toLowerCase()) &&
|
|
2329
|
+
!(expression === null || expression === void 0 ? void 0 : expression.findAncestor(reflection_1.isNewExpression))) {
|
|
2330
|
+
return true;
|
|
2331
|
+
}
|
|
2332
|
+
return false;
|
|
2333
|
+
}
|
|
2334
|
+
getSpecialCaseCallExpressionReturnType(callExpr, options) {
|
|
2335
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
2336
|
+
if ((0, reflection_1.isVariableExpression)(callExpr.callee) && callExpr.callee.tokens.name.text.toLowerCase() === 'createobject') {
|
|
2337
|
+
const componentName = (0, reflection_1.isLiteralString)(callExpr.args[0]) ? (_b = (_a = callExpr.args[0].tokens.value) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.replace(/"/g, '') : '';
|
|
2338
|
+
const nodeType = componentName.toLowerCase() === 'rosgnode' && (0, reflection_1.isLiteralString)(callExpr.args[1]) ? (_d = (_c = callExpr.args[1].tokens.value) === null || _c === void 0 ? void 0 : _c.text) === null || _d === void 0 ? void 0 : _d.replace(/"/g, '') : '';
|
|
2339
|
+
if (componentName === null || componentName === void 0 ? void 0 : componentName.toLowerCase().startsWith('ro')) {
|
|
2340
|
+
let fullName = componentName + nodeType;
|
|
2341
|
+
if (nodeType.includes(':')) {
|
|
2342
|
+
// This node has a colon in its name, most likely from a component Library
|
|
2343
|
+
// This componentType is most likely unknown, so return `roSGNode`
|
|
2344
|
+
fullName = 'roSGNode';
|
|
2345
|
+
}
|
|
2346
|
+
const data = {};
|
|
2347
|
+
const symbolTable = callExpr.getSymbolTable();
|
|
2348
|
+
const foundType = symbolTable.getSymbolType(fullName, {
|
|
2349
|
+
flags: 2 /* SymbolTypeFlag.typetime */,
|
|
2350
|
+
data: data,
|
|
2351
|
+
tableProvider: () => callExpr === null || callExpr === void 0 ? void 0 : callExpr.getSymbolTable(),
|
|
2352
|
+
fullName: fullName
|
|
1209
2353
|
});
|
|
2354
|
+
if (foundType) {
|
|
2355
|
+
return foundType;
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
else if ((0, reflection_1.isDottedGetExpression)(callExpr.callee) &&
|
|
2360
|
+
((_g = (_f = (_e = callExpr.callee.tokens) === null || _e === void 0 ? void 0 : _e.name) === null || _f === void 0 ? void 0 : _f.text) === null || _g === void 0 ? void 0 : _g.toLowerCase()) === 'callfunc' &&
|
|
2361
|
+
(0, reflection_1.isLiteralString)((_h = callExpr.args) === null || _h === void 0 ? void 0 : _h[0])) {
|
|
2362
|
+
return this.getCallFuncType(callExpr, (_k = (_j = callExpr.args) === null || _j === void 0 ? void 0 : _j[0]) === null || _k === void 0 ? void 0 : _k.tokens.value, options);
|
|
2363
|
+
}
|
|
2364
|
+
else if ((0, reflection_1.isDottedGetExpression)(callExpr.callee) &&
|
|
2365
|
+
((_o = (_m = (_l = callExpr.callee.tokens) === null || _l === void 0 ? void 0 : _l.name) === null || _m === void 0 ? void 0 : _m.text) === null || _o === void 0 ? void 0 : _o.toLowerCase()) === 'createchild' &&
|
|
2366
|
+
(0, reflection_1.isComponentType)((_p = callExpr.callee.obj) === null || _p === void 0 ? void 0 : _p.getType({ flags: 1 /* SymbolTypeFlag.runtime */ })) &&
|
|
2367
|
+
(0, reflection_1.isLiteralString)((_q = callExpr.args) === null || _q === void 0 ? void 0 : _q[0])) {
|
|
2368
|
+
const fullName = `roSGNode${(_u = (_t = (_s = (_r = callExpr.args) === null || _r === void 0 ? void 0 : _r[0].tokens) === null || _s === void 0 ? void 0 : _s.value) === null || _t === void 0 ? void 0 : _t.text) === null || _u === void 0 ? void 0 : _u.replace(/"/g, '')}`;
|
|
2369
|
+
const data = {};
|
|
2370
|
+
const symbolTable = callExpr.getSymbolTable();
|
|
2371
|
+
return symbolTable.getSymbolType(fullName, {
|
|
2372
|
+
flags: 2 /* SymbolTypeFlag.typetime */,
|
|
2373
|
+
data: data,
|
|
2374
|
+
tableProvider: () => callExpr === null || callExpr === void 0 ? void 0 : callExpr.getSymbolTable(),
|
|
2375
|
+
fullName: fullName
|
|
2376
|
+
});
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
getCallFuncType(callExpr, methodNameToken, options) {
|
|
2380
|
+
var _a, _b, _c, _d;
|
|
2381
|
+
let result;
|
|
2382
|
+
let methodName = (_a = methodNameToken === null || methodNameToken === void 0 ? void 0 : methodNameToken.text) === null || _a === void 0 ? void 0 : _a.replace(/"/g, ''); // remove quotes if it was the first arg of .callFunc()
|
|
2383
|
+
// a little hacky here with checking options.ignoreCall because callFuncExpression has the method name
|
|
2384
|
+
// It's nicer for CallExpression, because it's a call on any expression.
|
|
2385
|
+
let calleeType;
|
|
2386
|
+
if ((0, reflection_1.isCallfuncExpression)(callExpr)) {
|
|
2387
|
+
calleeType = callExpr.callee.getType(Object.assign(Object.assign({}, options), { flags: 1 /* SymbolTypeFlag.runtime */, ignoreCall: false }));
|
|
2388
|
+
}
|
|
2389
|
+
else if ((0, reflection_1.isCallExpression)(callExpr) && (0, reflection_1.isDottedGetExpression)(callExpr.callee)) {
|
|
2390
|
+
calleeType = callExpr.callee.obj.getType(Object.assign(Object.assign({}, options), { flags: 1 /* SymbolTypeFlag.runtime */, ignoreCall: false }));
|
|
2391
|
+
}
|
|
2392
|
+
const funcType = (_b = calleeType.getCallFuncType) === null || _b === void 0 ? void 0 : _b.call(calleeType, methodName, options);
|
|
2393
|
+
if (funcType) {
|
|
2394
|
+
(_c = options.typeChain) === null || _c === void 0 ? void 0 : _c.push(new interfaces_1.TypeChainEntry({
|
|
2395
|
+
name: methodName,
|
|
2396
|
+
type: funcType,
|
|
2397
|
+
data: options.data,
|
|
2398
|
+
location: methodNameToken.location,
|
|
2399
|
+
separatorToken: (0, creators_1.createToken)(TokenKind_1.TokenKind.Callfunc),
|
|
2400
|
+
astNode: callExpr
|
|
2401
|
+
}));
|
|
2402
|
+
if (options.ignoreCall) {
|
|
2403
|
+
result = funcType;
|
|
2404
|
+
}
|
|
2405
|
+
else if ((0, reflection_1.isCallableType)(funcType) && (!(0, reflection_1.isReferenceType)(funcType.returnType) || funcType.returnType.isResolvable())) {
|
|
2406
|
+
result = funcType.returnType;
|
|
2407
|
+
}
|
|
2408
|
+
else if (!(0, reflection_1.isReferenceType)(funcType) && ((_d = funcType === null || funcType === void 0 ? void 0 : funcType.returnType) === null || _d === void 0 ? void 0 : _d.isResolvable())) {
|
|
2409
|
+
result = funcType.returnType;
|
|
2410
|
+
}
|
|
2411
|
+
else if (this.isUnionOfFunctions(funcType)) {
|
|
2412
|
+
result = this.getReturnTypeOfUnionOfFunctions(funcType);
|
|
1210
2413
|
}
|
|
1211
|
-
|
|
2414
|
+
else {
|
|
2415
|
+
result = new ReferenceType_1.TypePropertyReferenceType(funcType, 'returnType');
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
if ((0, reflection_1.isVoidType)(result)) {
|
|
2419
|
+
// CallFunc will always return invalid, even if function called is `as void`
|
|
2420
|
+
result = DynamicType_1.DynamicType.instance;
|
|
2421
|
+
}
|
|
2422
|
+
if (options.data && !options.ignoreCall) {
|
|
2423
|
+
options.data.isFromCallFunc = true;
|
|
1212
2424
|
}
|
|
1213
2425
|
return result;
|
|
1214
2426
|
}
|
|
2427
|
+
isUnionOfFunctions(type, allowReferenceTypes = false) {
|
|
2428
|
+
if ((0, reflection_1.isUnionType)(type)) {
|
|
2429
|
+
const callablesInUnion = type.types.filter(t => (0, reflection_1.isCallableType)(t) || (allowReferenceTypes && (0, reflection_1.isReferenceType)(t)));
|
|
2430
|
+
return callablesInUnion.length === type.types.length && callablesInUnion.length > 0;
|
|
2431
|
+
}
|
|
2432
|
+
return false;
|
|
2433
|
+
}
|
|
2434
|
+
isIntersectionOfFunctions(type, allowReferenceTypes = false) {
|
|
2435
|
+
if ((0, reflection_1.isIntersectionType)(type)) {
|
|
2436
|
+
const callablesInUnion = type.types.filter(t => (0, reflection_1.isCallableType)(t) || (allowReferenceTypes && (0, reflection_1.isReferenceType)(t)));
|
|
2437
|
+
return callablesInUnion.length === type.types.length && callablesInUnion.length > 0;
|
|
2438
|
+
}
|
|
2439
|
+
return false;
|
|
2440
|
+
}
|
|
2441
|
+
getFunctionTypeFromUnion(type) {
|
|
2442
|
+
if (this.isUnionOfFunctions(type)) {
|
|
2443
|
+
const typedFuncsInUnion = type.types.filter(reflection_1.isTypedFunctionType);
|
|
2444
|
+
if (typedFuncsInUnion.length < type.types.length) {
|
|
2445
|
+
// has non-typedFuncs in union
|
|
2446
|
+
return FunctionType_1.FunctionType.instance;
|
|
2447
|
+
}
|
|
2448
|
+
const exampleFunc = typedFuncsInUnion[0];
|
|
2449
|
+
const cumulativeFunction = new types_1.TypedFunctionType((0, helpers_1.getUniqueType)(typedFuncsInUnion.map(f => f.returnType), (types) => new UnionType_1.UnionType(types)))
|
|
2450
|
+
.setName(exampleFunc.name)
|
|
2451
|
+
.setSub(exampleFunc.isSub);
|
|
2452
|
+
for (const param of exampleFunc.params) {
|
|
2453
|
+
cumulativeFunction.addParameter(param.name, param.type, param.isOptional);
|
|
2454
|
+
}
|
|
2455
|
+
return cumulativeFunction;
|
|
2456
|
+
}
|
|
2457
|
+
return undefined;
|
|
2458
|
+
}
|
|
2459
|
+
getFunctionTypeFromIntersection(type) {
|
|
2460
|
+
if (this.isIntersectionOfFunctions(type)) {
|
|
2461
|
+
const typedFuncsInUnion = type.types.filter(reflection_1.isTypedFunctionType);
|
|
2462
|
+
if (typedFuncsInUnion.length < type.types.length) {
|
|
2463
|
+
// has non-typedFuncs in union
|
|
2464
|
+
return FunctionType_1.FunctionType.instance;
|
|
2465
|
+
}
|
|
2466
|
+
const exampleFunc = typedFuncsInUnion[0];
|
|
2467
|
+
const cumulativeFunction = new types_1.TypedFunctionType((0, helpers_1.getUniqueType)(typedFuncsInUnion.map(f => f.returnType), (types) => new IntersectionType_1.IntersectionType(types)))
|
|
2468
|
+
.setName(exampleFunc.name)
|
|
2469
|
+
.setSub(exampleFunc.isSub);
|
|
2470
|
+
for (const param of exampleFunc.params) {
|
|
2471
|
+
cumulativeFunction.addParameter(param.name, param.type, param.isOptional);
|
|
2472
|
+
}
|
|
2473
|
+
return cumulativeFunction;
|
|
2474
|
+
}
|
|
2475
|
+
return undefined;
|
|
2476
|
+
}
|
|
2477
|
+
getReturnTypeOfUnionOfFunctions(type) {
|
|
2478
|
+
if (this.isUnionOfFunctions(type, true)) {
|
|
2479
|
+
const typedFuncsInUnion = type.types.filter(t => (0, reflection_1.isTypedFunctionType)(t) || (0, reflection_1.isReferenceType)(t));
|
|
2480
|
+
if (typedFuncsInUnion.length < type.types.length) {
|
|
2481
|
+
// is non-typedFuncs in union
|
|
2482
|
+
return DynamicType_1.DynamicType.instance;
|
|
2483
|
+
}
|
|
2484
|
+
const funcReturns = typedFuncsInUnion.map(f => f.returnType);
|
|
2485
|
+
return (0, helpers_1.getUniqueType)(funcReturns, (types) => new UnionType_1.UnionType(types));
|
|
2486
|
+
}
|
|
2487
|
+
return InvalidType_1.InvalidType.instance;
|
|
2488
|
+
}
|
|
2489
|
+
getReturnTypeOfIntersectionOfFunctions(type) {
|
|
2490
|
+
if (this.isIntersectionOfFunctions(type, true)) {
|
|
2491
|
+
const typedFuncsInUnion = type.types.filter(t => (0, reflection_1.isTypedFunctionType)(t) || (0, reflection_1.isReferenceType)(t));
|
|
2492
|
+
if (typedFuncsInUnion.length < type.types.length) {
|
|
2493
|
+
// is non-typedFuncs in union
|
|
2494
|
+
return DynamicType_1.DynamicType.instance;
|
|
2495
|
+
}
|
|
2496
|
+
const funcReturns = typedFuncsInUnion.map(f => f.returnType);
|
|
2497
|
+
return new IntersectionType_1.IntersectionType(funcReturns); //getUniqueType(funcReturns, (types) => new UnionType(types));
|
|
2498
|
+
}
|
|
2499
|
+
return InvalidType_1.InvalidType.instance;
|
|
2500
|
+
}
|
|
2501
|
+
symbolComesFromSameNode(symbolName, definingNode, symbolTable) {
|
|
2502
|
+
let nsData = {};
|
|
2503
|
+
let foundType = symbolTable === null || symbolTable === void 0 ? void 0 : symbolTable.getSymbolType(symbolName, { flags: 1 /* SymbolTypeFlag.runtime */, data: nsData });
|
|
2504
|
+
if (foundType && definingNode === (nsData === null || nsData === void 0 ? void 0 : nsData.definingNode)) {
|
|
2505
|
+
return true;
|
|
2506
|
+
}
|
|
2507
|
+
return false;
|
|
2508
|
+
}
|
|
2509
|
+
isCalleeMemberOfNamespace(symbolName, nodeWhereUsed, namespace) {
|
|
2510
|
+
namespace = namespace !== null && namespace !== void 0 ? namespace : nodeWhereUsed.findAncestor(reflection_1.isNamespaceStatement);
|
|
2511
|
+
if (!this.isVariableMemberOfNamespace(symbolName, nodeWhereUsed, namespace)) {
|
|
2512
|
+
return false;
|
|
2513
|
+
}
|
|
2514
|
+
const exprType = nodeWhereUsed.getType({ flags: 1 /* SymbolTypeFlag.runtime */ });
|
|
2515
|
+
if ((0, reflection_1.isCallableType)(exprType) || (0, reflection_1.isClassType)(exprType)) {
|
|
2516
|
+
return true;
|
|
2517
|
+
}
|
|
2518
|
+
return false;
|
|
2519
|
+
}
|
|
2520
|
+
isVariableMemberOfNamespace(symbolName, nodeWhereUsed, namespace) {
|
|
2521
|
+
namespace = namespace !== null && namespace !== void 0 ? namespace : nodeWhereUsed.findAncestor(reflection_1.isNamespaceStatement);
|
|
2522
|
+
if (!(0, reflection_1.isNamespaceStatement)(namespace)) {
|
|
2523
|
+
return false;
|
|
2524
|
+
}
|
|
2525
|
+
const namespaceParts = namespace.getNameParts();
|
|
2526
|
+
let namespaceType;
|
|
2527
|
+
let symbolTable = namespace.getSymbolTable();
|
|
2528
|
+
for (const part of namespaceParts) {
|
|
2529
|
+
namespaceType = symbolTable.getSymbolType(part.text, { flags: 1 /* SymbolTypeFlag.runtime */ });
|
|
2530
|
+
if (namespaceType) {
|
|
2531
|
+
symbolTable = namespaceType.getMemberTable();
|
|
2532
|
+
}
|
|
2533
|
+
else {
|
|
2534
|
+
return false;
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
let varData = {};
|
|
2538
|
+
nodeWhereUsed.getType({ flags: 1 /* SymbolTypeFlag.runtime */, data: varData });
|
|
2539
|
+
const isFromSameNodeInMemberTable = this.symbolComesFromSameNode(symbolName, varData === null || varData === void 0 ? void 0 : varData.definingNode, namespaceType === null || namespaceType === void 0 ? void 0 : namespaceType.getMemberTable());
|
|
2540
|
+
return isFromSameNodeInMemberTable;
|
|
2541
|
+
}
|
|
2542
|
+
isVariableShadowingSomething(symbolName, nodeWhereUsed) {
|
|
2543
|
+
let varData = {};
|
|
2544
|
+
let exprType = nodeWhereUsed.getType({ flags: 1 /* SymbolTypeFlag.runtime */, data: varData });
|
|
2545
|
+
if ((0, reflection_1.isReferenceType)(exprType)) {
|
|
2546
|
+
exprType = exprType.getTarget();
|
|
2547
|
+
}
|
|
2548
|
+
const namespace = nodeWhereUsed === null || nodeWhereUsed === void 0 ? void 0 : nodeWhereUsed.findAncestor(reflection_1.isNamespaceStatement);
|
|
2549
|
+
if ((0, reflection_1.isNamespaceStatement)(namespace)) {
|
|
2550
|
+
let namespaceHasSymbol = namespace.getSymbolTable().hasSymbol(symbolName, 1 /* SymbolTypeFlag.runtime */);
|
|
2551
|
+
// check if the namespace has a symbol with the same name, but different definiton
|
|
2552
|
+
if (namespaceHasSymbol && !this.symbolComesFromSameNode(symbolName, varData.definingNode, namespace.getSymbolTable())) {
|
|
2553
|
+
return true;
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
const bodyTable = nodeWhereUsed.getRoot().getSymbolTable();
|
|
2557
|
+
const hasSymbolAtFileLevel = bodyTable.hasSymbol(symbolName, 1 /* SymbolTypeFlag.runtime */);
|
|
2558
|
+
if (hasSymbolAtFileLevel && !this.symbolComesFromSameNode(symbolName, varData.definingNode, bodyTable)) {
|
|
2559
|
+
return true;
|
|
2560
|
+
}
|
|
2561
|
+
return false;
|
|
2562
|
+
}
|
|
2563
|
+
chooseTypeFromCodeOrDocComment(codeType, docType, options) {
|
|
2564
|
+
let returnType;
|
|
2565
|
+
if (options.preferDocType && docType) {
|
|
2566
|
+
returnType = docType;
|
|
2567
|
+
if (options.data) {
|
|
2568
|
+
options.data.isFromDocComment = true;
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
else {
|
|
2572
|
+
returnType = codeType;
|
|
2573
|
+
if (!returnType && docType) {
|
|
2574
|
+
returnType = docType;
|
|
2575
|
+
if (options.data) {
|
|
2576
|
+
options.data.isFromDocComment = true;
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
return returnType;
|
|
2581
|
+
}
|
|
2582
|
+
/**
|
|
2583
|
+
* Gets the type for a default value (eg. as a function param, class member or typed array)
|
|
2584
|
+
*/
|
|
2585
|
+
getDefaultTypeFromValueType(valueType) {
|
|
2586
|
+
var _a;
|
|
2587
|
+
if (!valueType) {
|
|
2588
|
+
return undefined;
|
|
2589
|
+
}
|
|
2590
|
+
let resultType = DynamicType_1.DynamicType.instance;
|
|
2591
|
+
if (Array.isArray(valueType)) {
|
|
2592
|
+
// passed an array opf types, potential from ArrayType.innerTypes
|
|
2593
|
+
if (valueType.length > 0) {
|
|
2594
|
+
//at least one, use it
|
|
2595
|
+
resultType = valueType[0];
|
|
2596
|
+
if ((valueType === null || valueType === void 0 ? void 0 : valueType.length) > 1) {
|
|
2597
|
+
// more than 1, find union
|
|
2598
|
+
resultType = (0, helpers_1.getUniqueType)(valueType, UnionType_1.unionTypeFactory);
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
|
+
else {
|
|
2603
|
+
resultType = valueType;
|
|
2604
|
+
}
|
|
2605
|
+
if (!resultType.isResolvable()) {
|
|
2606
|
+
if ((0, reflection_1.isUnionType)(resultType)) {
|
|
2607
|
+
resultType = DynamicType_1.DynamicType.instance;
|
|
2608
|
+
}
|
|
2609
|
+
else {
|
|
2610
|
+
resultType = new ReferenceType_1.ParamTypeFromValueReferenceType(resultType);
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
else if ((0, reflection_1.isEnumMemberType)(resultType)) {
|
|
2614
|
+
// the type was an enum member... Try to get the parent enum type
|
|
2615
|
+
resultType = (_a = resultType.parentEnumType) !== null && _a !== void 0 ? _a : resultType;
|
|
2616
|
+
}
|
|
2617
|
+
else if ((0, reflection_1.isUnionType)(resultType)) {
|
|
2618
|
+
// it was a union -- I wonder if they're resolvable now?
|
|
2619
|
+
const moddedTypes = resultType.types.map(t => {
|
|
2620
|
+
var _a;
|
|
2621
|
+
if ((0, reflection_1.isEnumMemberType)(t)) {
|
|
2622
|
+
// the type was an enum member... Try to get the parent enum type
|
|
2623
|
+
return (_a = t.parentEnumType) !== null && _a !== void 0 ? _a : resultType;
|
|
2624
|
+
}
|
|
2625
|
+
return t;
|
|
2626
|
+
});
|
|
2627
|
+
resultType = (0, helpers_1.getUniqueType)(moddedTypes, UnionType_1.unionTypeFactory);
|
|
2628
|
+
}
|
|
2629
|
+
return resultType;
|
|
2630
|
+
}
|
|
2631
|
+
/**
|
|
2632
|
+
* Get the default type for an iterator of the given type
|
|
2633
|
+
* Used for `for each` loops
|
|
2634
|
+
*/
|
|
2635
|
+
getIteratorDefaultType(iteratorType) {
|
|
2636
|
+
if ((0, reflection_1.isArrayType)(iteratorType)) {
|
|
2637
|
+
return iteratorType.defaultType;
|
|
2638
|
+
}
|
|
2639
|
+
else if ((0, reflection_1.isAssociativeArrayTypeLike)(iteratorType)) {
|
|
2640
|
+
return StringType_1.StringType.instance;
|
|
2641
|
+
}
|
|
2642
|
+
else if ((0, reflection_1.isBuiltInType)(iteratorType, 'roByteArray')) {
|
|
2643
|
+
return IntegerType_1.IntegerType.instance;
|
|
2644
|
+
}
|
|
2645
|
+
return DynamicType_1.DynamicType.instance;
|
|
2646
|
+
}
|
|
2647
|
+
/**
|
|
2648
|
+
* Get a short name that can be used to reference the project in logs. (typically something like `prj1`, `prj8`, etc...)
|
|
2649
|
+
*/
|
|
2650
|
+
getProjectLogName(config) {
|
|
2651
|
+
//if we have a project number, use it
|
|
2652
|
+
if ((config === null || config === void 0 ? void 0 : config.projectNumber) !== undefined) {
|
|
2653
|
+
return `prj${config.projectNumber}`;
|
|
2654
|
+
}
|
|
2655
|
+
//just return empty string so log functions don't crash with undefined project numbers
|
|
2656
|
+
return '';
|
|
2657
|
+
}
|
|
1215
2658
|
}
|
|
1216
2659
|
exports.Util = Util;
|
|
1217
2660
|
/**
|
|
@@ -1220,7 +2663,7 @@ exports.Util = Util;
|
|
|
1220
2663
|
*/
|
|
1221
2664
|
function standardizePath(stringParts, ...expressions) {
|
|
1222
2665
|
let result = [];
|
|
1223
|
-
for (let i = 0; i < stringParts.length; i++) {
|
|
2666
|
+
for (let i = 0; i < (stringParts === null || stringParts === void 0 ? void 0 : stringParts.length); i++) {
|
|
1224
2667
|
result.push(stringParts[i], expressions[i]);
|
|
1225
2668
|
}
|
|
1226
2669
|
return exports.util.standardizePath(result.join(''));
|