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
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.failStatementType = exports.rangeToArray = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
3
|
+
exports.failStatementType = exports.rangeToArray = exports.parse = void 0;
|
|
4
|
+
const chai_config_spec_1 = require("../chai-config.spec");
|
|
5
|
+
const Lexer_1 = require("../lexer/Lexer");
|
|
6
|
+
const TokenKind_1 = require("../lexer/TokenKind");
|
|
6
7
|
const Expression_1 = require("./Expression");
|
|
7
8
|
const Parser_1 = require("./Parser");
|
|
8
9
|
const Statement_1 = require("./Statement");
|
|
@@ -10,96 +11,19 @@ const vscode_languageserver_1 = require("vscode-languageserver");
|
|
|
10
11
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
11
12
|
const reflection_1 = require("../astUtils/reflection");
|
|
12
13
|
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
13
|
-
const
|
|
14
|
-
const FunctionType_1 = require("../types/FunctionType");
|
|
15
|
-
const StringType_1 = require("../types/StringType");
|
|
16
|
-
const CustomType_1 = require("../types/CustomType");
|
|
14
|
+
const visitors_1 = require("../astUtils/visitors");
|
|
17
15
|
const IntegerType_1 = require("../types/IntegerType");
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const DynamicType_1 = require("../types/DynamicType");
|
|
16
|
+
const FloatType_1 = require("../types/FloatType");
|
|
17
|
+
const StringType_1 = require("../types/StringType");
|
|
18
|
+
const types_1 = require("../types");
|
|
22
19
|
const util_1 = require("../util");
|
|
20
|
+
const InlineInterfaceType_1 = require("../types/InlineInterfaceType");
|
|
23
21
|
describe('parser', () => {
|
|
24
22
|
it('emits empty object when empty token list is provided', () => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
30
|
-
describe('findReferences', () => {
|
|
31
|
-
it('recomputes localVars', () => {
|
|
32
|
-
const parser = Parser_1.Parser.parse(`
|
|
33
|
-
sub main(herd)
|
|
34
|
-
for each zombie in herd
|
|
35
|
-
isAlive = false
|
|
36
|
-
end for
|
|
37
|
-
for i = 0 to 10 step 1
|
|
38
|
-
j = i
|
|
39
|
-
end for
|
|
40
|
-
humansAreAlive = false
|
|
41
|
-
end sub
|
|
42
|
-
`);
|
|
43
|
-
chai_1.expect(parser.references.functionExpressions[0].symbolTable.ownSymbols.map(x => x.name).sort()).to.eql([
|
|
44
|
-
'herd',
|
|
45
|
-
'humansAreAlive',
|
|
46
|
-
'i',
|
|
47
|
-
'isAlive',
|
|
48
|
-
'j',
|
|
49
|
-
'zombie'
|
|
50
|
-
]);
|
|
51
|
-
parser.invalidateReferences();
|
|
52
|
-
chai_1.expect(parser.references.functionExpressions[0].symbolTable.ownSymbols.map(x => x.name).sort()).to.eql([
|
|
53
|
-
'herd',
|
|
54
|
-
'humansAreAlive',
|
|
55
|
-
'i',
|
|
56
|
-
'isAlive',
|
|
57
|
-
'j',
|
|
58
|
-
'zombie'
|
|
59
|
-
]);
|
|
60
|
-
});
|
|
61
|
-
it('assigns localVars to correct function expression bucket', () => {
|
|
62
|
-
const parser = Parser_1.Parser.parse(`
|
|
63
|
-
sub main()
|
|
64
|
-
outerName = "bob"
|
|
65
|
-
speak = sub()
|
|
66
|
-
innerName = "innerBob"
|
|
67
|
-
end sub
|
|
68
|
-
age = 12
|
|
69
|
-
end sub
|
|
70
|
-
`);
|
|
71
|
-
parser.invalidateReferences();
|
|
72
|
-
chai_1.expect(parser.references.functionExpressions[0].symbolTable.ownSymbols.map(x => x.name)).to.eql([
|
|
73
|
-
'outerName',
|
|
74
|
-
'speak',
|
|
75
|
-
'age'
|
|
76
|
-
]);
|
|
77
|
-
chai_1.expect(parser.references.functionExpressions[1].symbolTable.ownSymbols.map(x => x.name)).to.eql([
|
|
78
|
-
'innerName'
|
|
79
|
-
]);
|
|
80
|
-
});
|
|
81
|
-
it('gets called if references are missing', () => {
|
|
82
|
-
const parser = Parser_1.Parser.parse(`
|
|
83
|
-
sub main()
|
|
84
|
-
end sub
|
|
85
|
-
|
|
86
|
-
sub UnusedFunction()
|
|
87
|
-
end sub
|
|
88
|
-
`);
|
|
89
|
-
chai_1.expect(parser.references.functionStatements.map(x => x.name.text)).to.eql([
|
|
90
|
-
'main',
|
|
91
|
-
'UnusedFunction'
|
|
92
|
-
]);
|
|
93
|
-
//simulate a tree-shaking plugin by removing the `UnusedFunction`
|
|
94
|
-
parser.ast.statements.splice(1);
|
|
95
|
-
//tell the parser we modified the AST and need to regenerate references
|
|
96
|
-
parser.invalidateReferences();
|
|
97
|
-
chai_1.expect(parser['_references']).not.to.exist;
|
|
98
|
-
//calling `references` automatically regenerates the references
|
|
99
|
-
chai_1.expect(parser.references.functionStatements.map(x => x.name.text)).to.eql([
|
|
100
|
-
'main'
|
|
101
|
-
]);
|
|
102
|
-
});
|
|
23
|
+
let { ast, diagnostics } = Parser_1.Parser.parse([]);
|
|
24
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBody)(ast)).to.be.true;
|
|
25
|
+
(0, chai_config_spec_1.expect)(ast.statements).to.be.empty;
|
|
26
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.empty;
|
|
103
27
|
});
|
|
104
28
|
describe('callfunc operator', () => {
|
|
105
29
|
it('is not allowed in brightscript mode', () => {
|
|
@@ -109,7 +33,7 @@ describe('parser', () => {
|
|
|
109
33
|
node@.doSomething(1, 2)
|
|
110
34
|
end sub
|
|
111
35
|
`, Parser_1.ParseMode.BrightScript);
|
|
112
|
-
|
|
36
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('callfunc operator').message);
|
|
113
37
|
});
|
|
114
38
|
it('does not cause parse errors', () => {
|
|
115
39
|
var _a, _b, _c, _d, _e;
|
|
@@ -118,17 +42,118 @@ describe('parser', () => {
|
|
|
118
42
|
node@.doSomething(1, 2)
|
|
119
43
|
end sub
|
|
120
44
|
`, Parser_1.ParseMode.BrighterScript);
|
|
121
|
-
|
|
122
|
-
|
|
45
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
46
|
+
(0, chai_config_spec_1.expect)((_e = (_d = (_c = (_b = parser.ast.statements[0]) === null || _b === void 0 ? void 0 : _b.func) === null || _c === void 0 ? void 0 : _c.body) === null || _d === void 0 ? void 0 : _d.statements[0]) === null || _e === void 0 ? void 0 : _e.expression).to.be.instanceof(Expression_1.CallfuncExpression);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
it('flags function names with invalid characters', () => {
|
|
50
|
+
const { diagnostics } = Parser_1.Parser.parse(`
|
|
51
|
+
function alpha$() : end function
|
|
52
|
+
function beta%() : end function
|
|
53
|
+
function charlie!() : end function
|
|
54
|
+
function delta#() : end function
|
|
55
|
+
function echo&() : end function
|
|
56
|
+
`);
|
|
57
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
58
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('alpha$', '$'),
|
|
59
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('beta%', '%'),
|
|
60
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('charlie!', '!'),
|
|
61
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('delta#', '#'),
|
|
62
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('echo&', '&')
|
|
63
|
+
]);
|
|
64
|
+
});
|
|
65
|
+
describe('optional chaining operator', () => {
|
|
66
|
+
function getExpression(text, options) {
|
|
67
|
+
const parser = parse(text, options === null || options === void 0 ? void 0 : options.parseMode);
|
|
68
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
69
|
+
const expressions = parser.ast.findChildren(reflection_1.isExpression);
|
|
70
|
+
if (options === null || options === void 0 ? void 0 : options.matcher) {
|
|
71
|
+
return expressions.find(options.matcher);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return expressions[0];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
it('works for ?.', () => {
|
|
78
|
+
const expression = getExpression(`value = person?.name`);
|
|
79
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.DottedGetExpression);
|
|
80
|
+
(0, chai_config_spec_1.expect)(expression.tokens.dot.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
|
|
81
|
+
});
|
|
82
|
+
it('works for ?[', () => {
|
|
83
|
+
const expression = getExpression(`value = person?["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
84
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
|
|
85
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftSquare);
|
|
86
|
+
(0, chai_config_spec_1.expect)(expression.tokens.questionDot).not.to.exist;
|
|
87
|
+
});
|
|
88
|
+
it('works for ?.[', () => {
|
|
89
|
+
var _a;
|
|
90
|
+
const expression = getExpression(`value = person?.["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
91
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
|
|
92
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.LeftSquareBracket);
|
|
93
|
+
(0, chai_config_spec_1.expect)((_a = expression.tokens.questionDot) === null || _a === void 0 ? void 0 : _a.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
|
|
94
|
+
});
|
|
95
|
+
it('works for ?@', () => {
|
|
96
|
+
const expression = getExpression(`value = someXml?@someAttr`);
|
|
97
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.XmlAttributeGetExpression);
|
|
98
|
+
(0, chai_config_spec_1.expect)(expression.tokens.at.kind).to.eql(TokenKind_1.TokenKind.QuestionAt);
|
|
99
|
+
});
|
|
100
|
+
it('works for ?(', () => {
|
|
101
|
+
const expression = getExpression(`value = person.getName?()`);
|
|
102
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
|
|
103
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
104
|
+
});
|
|
105
|
+
it('works for print statements using question mark', () => {
|
|
106
|
+
const { ast } = parse(`
|
|
107
|
+
?[1]
|
|
108
|
+
?(1+1)
|
|
109
|
+
`);
|
|
110
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceOf(Statement_1.PrintStatement);
|
|
111
|
+
(0, chai_config_spec_1.expect)(ast.statements[1]).to.be.instanceOf(Statement_1.PrintStatement);
|
|
112
|
+
});
|
|
113
|
+
//TODO enable this once we properly parse IIFEs
|
|
114
|
+
it.skip('works for ?( in anonymous function', () => {
|
|
115
|
+
const expression = getExpression(`thing = (function() : end function)?()`);
|
|
116
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
|
|
117
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
118
|
+
});
|
|
119
|
+
it('works for ?( in new call', () => {
|
|
120
|
+
const expression = getExpression(`thing = new Person?()`, { parseMode: Parser_1.ParseMode.BrighterScript });
|
|
121
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.NewExpression);
|
|
122
|
+
(0, chai_config_spec_1.expect)(expression.call.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
123
|
+
});
|
|
124
|
+
it('distinguishes between optional chaining and ternary expression', () => {
|
|
125
|
+
const parser = parse(`
|
|
126
|
+
sub main()
|
|
127
|
+
name = person?["name"]
|
|
128
|
+
isTrue = true
|
|
129
|
+
key = isTrue ? ["name"] : ["age"]
|
|
130
|
+
end sub
|
|
131
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
132
|
+
const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
|
|
133
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
|
|
134
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[2].value).is.instanceof(Expression_1.TernaryExpression);
|
|
135
|
+
});
|
|
136
|
+
it('distinguishes between optional chaining and ternary expression', () => {
|
|
137
|
+
const parser = parse(`
|
|
138
|
+
sub main()
|
|
139
|
+
'optional chain. the lack of whitespace between ? and [ matters
|
|
140
|
+
key = isTrue ?["name"] : getDefault()
|
|
141
|
+
'ternary
|
|
142
|
+
key = isTrue ? ["name"] : getDefault()
|
|
143
|
+
end sub
|
|
144
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
145
|
+
const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
|
|
146
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
|
|
147
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[1].value).is.instanceof(Expression_1.TernaryExpression);
|
|
123
148
|
});
|
|
124
149
|
});
|
|
125
150
|
describe('diagnostic locations', () => {
|
|
126
151
|
it('tracks basic diagnostic locations', () => {
|
|
127
|
-
|
|
152
|
+
(0, chai_config_spec_1.expect)(parse(`
|
|
128
153
|
sub main()
|
|
129
154
|
call()a
|
|
130
155
|
end sub
|
|
131
|
-
`).diagnostics.map(x => rangeToArray(x.range))).to.eql([
|
|
156
|
+
`).diagnostics.map(x => rangeToArray(x.location.range))).to.eql([
|
|
132
157
|
[2, 26, 2, 27],
|
|
133
158
|
[2, 27, 2, 28]
|
|
134
159
|
]);
|
|
@@ -140,8 +165,8 @@ describe('parser', () => {
|
|
|
140
165
|
return "6c5cdf1"
|
|
141
166
|
end functionasdf
|
|
142
167
|
`).diagnostics;
|
|
143
|
-
|
|
144
|
-
|
|
168
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist.and.to.eql(DiagnosticMessages_1.DiagnosticMessages.expectedStatement().message);
|
|
169
|
+
(0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.location.range).to.eql(vscode_languageserver_1.Range.create(3, 20, 3, 32));
|
|
145
170
|
});
|
|
146
171
|
});
|
|
147
172
|
describe('parse', () => {
|
|
@@ -154,7 +179,7 @@ describe('parser', () => {
|
|
|
154
179
|
end function()
|
|
155
180
|
end sub
|
|
156
181
|
`);
|
|
157
|
-
testHelpers_spec_1.expectZeroDiagnostics(parser);
|
|
182
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
158
183
|
});
|
|
159
184
|
it('supports grouped iife in assignment', () => {
|
|
160
185
|
const parser = parse(`
|
|
@@ -165,7 +190,7 @@ describe('parser', () => {
|
|
|
165
190
|
end function)()
|
|
166
191
|
end sub
|
|
167
192
|
`);
|
|
168
|
-
testHelpers_spec_1.expectZeroDiagnostics(parser);
|
|
193
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
169
194
|
});
|
|
170
195
|
it('supports returning iife call', () => {
|
|
171
196
|
const parser = parse(`
|
|
@@ -174,45 +199,143 @@ describe('parser', () => {
|
|
|
174
199
|
end sub)()
|
|
175
200
|
end sub
|
|
176
201
|
`);
|
|
177
|
-
testHelpers_spec_1.expectZeroDiagnostics(parser);
|
|
202
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
178
203
|
});
|
|
179
204
|
it('supports using "interface" as parameter name', () => {
|
|
180
205
|
var _a;
|
|
181
|
-
|
|
206
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
182
207
|
sub main(interface as object)
|
|
183
208
|
end sub
|
|
184
209
|
`, Parser_1.ParseMode.BrighterScript).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
185
210
|
});
|
|
211
|
+
it('does not scrap the entire function when encountering unknown parameter type', () => {
|
|
212
|
+
const parser = parse(`
|
|
213
|
+
sub test(param1 as unknownType)
|
|
214
|
+
end sub
|
|
215
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
216
|
+
// type validation happens at scope validation, not at the parser
|
|
217
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
218
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(parser.ast.statements[0])).to.be.true;
|
|
219
|
+
});
|
|
220
|
+
it('does not scrap the entire function when encountering unknown parameter type in brightscript mode', () => {
|
|
221
|
+
const parser = parse(`
|
|
222
|
+
sub test(param1 as unknownType)
|
|
223
|
+
end sub
|
|
224
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
225
|
+
// type validation happens at scope validation, not at the parser
|
|
226
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types'));
|
|
227
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(parser.ast.statements[0])).to.be.true;
|
|
228
|
+
});
|
|
229
|
+
it('adds diagnostics when missing end for statements', () => {
|
|
230
|
+
let parser = parse(`
|
|
231
|
+
sub test1(x)
|
|
232
|
+
for each item in x
|
|
233
|
+
print item
|
|
234
|
+
end sub
|
|
235
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
236
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
|
|
237
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop('for each')
|
|
238
|
+
]);
|
|
239
|
+
parser = parse(`
|
|
240
|
+
sub test2()
|
|
241
|
+
for i = 0 to 10
|
|
242
|
+
print i
|
|
243
|
+
end sub
|
|
244
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
245
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
|
|
246
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop('for')
|
|
247
|
+
]);
|
|
248
|
+
parser = parse(`
|
|
249
|
+
sub test3(x )
|
|
250
|
+
for each item in x
|
|
251
|
+
print item
|
|
252
|
+
next
|
|
253
|
+
|
|
254
|
+
for i = 0 to 10
|
|
255
|
+
print i
|
|
256
|
+
next ' next works the same as "end for"
|
|
257
|
+
end sub
|
|
258
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
259
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
260
|
+
});
|
|
261
|
+
it('does not allow return type as invalid', () => {
|
|
262
|
+
let parser = parse(`
|
|
263
|
+
function test(x) as invalid
|
|
264
|
+
return invalid
|
|
265
|
+
end function
|
|
266
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
267
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
|
|
268
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('as').message
|
|
269
|
+
]);
|
|
270
|
+
});
|
|
271
|
+
it('does not allow param type as invalid', () => {
|
|
272
|
+
let parser = parse(`
|
|
273
|
+
function test(x as invalid)
|
|
274
|
+
return invalid
|
|
275
|
+
end function
|
|
276
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
277
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
|
|
278
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('as').message
|
|
279
|
+
]);
|
|
280
|
+
});
|
|
281
|
+
it('validates when theres a fraction hex', () => {
|
|
282
|
+
let parser = parse(`
|
|
283
|
+
function test()
|
|
284
|
+
x = &HFF.01234
|
|
285
|
+
return x
|
|
286
|
+
end function
|
|
287
|
+
`);
|
|
288
|
+
(0, testHelpers_spec_1.expectDiagnostics)(parser, [
|
|
289
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedStatement(),
|
|
290
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon()
|
|
291
|
+
]);
|
|
292
|
+
});
|
|
293
|
+
it('allows print statement with hex followed by dot <number>', () => {
|
|
294
|
+
let parser = parse(`
|
|
295
|
+
function test()
|
|
296
|
+
print &HFF.01234
|
|
297
|
+
end function
|
|
298
|
+
`);
|
|
299
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
300
|
+
});
|
|
186
301
|
describe('namespace', () => {
|
|
187
|
-
it('
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
302
|
+
it('allows namespaces declared inside other namespaces', () => {
|
|
303
|
+
const parser = parse(`
|
|
304
|
+
namespace Level1
|
|
305
|
+
namespace Level2.Level3
|
|
306
|
+
sub main()
|
|
307
|
+
end sub
|
|
192
308
|
end namespace
|
|
193
|
-
end
|
|
194
|
-
`, Parser_1.ParseMode.BrighterScript)
|
|
309
|
+
end namespace
|
|
310
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
311
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
312
|
+
// We expect these names to be "as given" in this context, because we aren't evaluating a full program.
|
|
313
|
+
const namespaceStatements = parser.ast.findChildren(reflection_1.isNamespaceStatement);
|
|
314
|
+
(0, chai_config_spec_1.expect)(namespaceStatements.map(statement => statement.getName(Parser_1.ParseMode.BrighterScript))).to.have.deep.members([
|
|
315
|
+
'Level1.Level2.Level3',
|
|
316
|
+
'Level1'
|
|
317
|
+
]);
|
|
195
318
|
});
|
|
196
319
|
it('parses empty namespace', () => {
|
|
197
320
|
var _a;
|
|
198
|
-
let {
|
|
321
|
+
let { ast, diagnostics } = parse(`
|
|
199
322
|
namespace Name.Space
|
|
200
323
|
end namespace
|
|
201
324
|
`, Parser_1.ParseMode.BrighterScript);
|
|
202
|
-
|
|
203
|
-
|
|
325
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
326
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
204
327
|
});
|
|
205
328
|
it('includes body', () => {
|
|
206
329
|
var _a;
|
|
207
|
-
let {
|
|
330
|
+
let { ast, diagnostics } = parse(`
|
|
208
331
|
namespace Name.Space
|
|
209
332
|
sub main()
|
|
210
333
|
end sub
|
|
211
334
|
end namespace
|
|
212
335
|
`, Parser_1.ParseMode.BrighterScript);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
336
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
337
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
338
|
+
(0, chai_config_spec_1.expect)(ast.statements[0].body.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
216
339
|
});
|
|
217
340
|
it('supports comments and newlines', () => {
|
|
218
341
|
var _a;
|
|
@@ -228,7 +351,7 @@ describe('parser', () => {
|
|
|
228
351
|
'comment
|
|
229
352
|
end namespace 'comment
|
|
230
353
|
`, Parser_1.ParseMode.BrighterScript);
|
|
231
|
-
|
|
354
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
232
355
|
});
|
|
233
356
|
it('catches missing name', () => {
|
|
234
357
|
var _a;
|
|
@@ -236,7 +359,7 @@ describe('parser', () => {
|
|
|
236
359
|
namespace
|
|
237
360
|
end namespace
|
|
238
361
|
`, Parser_1.ParseMode.BrighterScript);
|
|
239
|
-
|
|
362
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('namespace').message);
|
|
240
363
|
});
|
|
241
364
|
it('recovers after missing `end namespace`', () => {
|
|
242
365
|
var _a, _b, _c;
|
|
@@ -245,9 +368,9 @@ describe('parser', () => {
|
|
|
245
368
|
sub main()
|
|
246
369
|
end sub
|
|
247
370
|
`, Parser_1.ParseMode.BrighterScript);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
371
|
+
(0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
372
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('namespace').message);
|
|
373
|
+
(0, chai_config_spec_1.expect)((_c = (_b = parser.ast.statements[0]) === null || _b === void 0 ? void 0 : _b.body) === null || _c === void 0 ? void 0 : _c.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
251
374
|
});
|
|
252
375
|
it('adds diagnostic when encountering namespace in brightscript mode', () => {
|
|
253
376
|
var _a;
|
|
@@ -255,47 +378,12 @@ describe('parser', () => {
|
|
|
255
378
|
namespace Name.Space
|
|
256
379
|
end namespace
|
|
257
380
|
`);
|
|
258
|
-
|
|
259
|
-
});
|
|
260
|
-
it('declares a symbol table for the namespace', () => {
|
|
261
|
-
let parser = parse(`
|
|
262
|
-
namespace Name.Space
|
|
263
|
-
function funcInt() as integer
|
|
264
|
-
return 3
|
|
265
|
-
end function
|
|
266
|
-
|
|
267
|
-
function funcStr() as string
|
|
268
|
-
return "hello"
|
|
269
|
-
end function
|
|
270
|
-
end namespace
|
|
271
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
272
|
-
chai_1.expect(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
273
|
-
const namespaceStmt = parser.ast.statements[0];
|
|
274
|
-
chai_1.expect(namespaceStmt.symbolTable).to.be.instanceof(SymbolTable_1.SymbolTable);
|
|
275
|
-
chai_1.expect(namespaceStmt.symbolTable.getSymbolType('funcInt').toString()).to.equal('function funcInt() as integer');
|
|
276
|
-
chai_1.expect(namespaceStmt.symbolTable.getSymbolType('funcStr')).to.be.instanceof(FunctionType_1.FunctionType);
|
|
277
|
-
const strFunctionType = namespaceStmt.symbolTable.getSymbolType('funcStr');
|
|
278
|
-
chai_1.expect(strFunctionType.returnType.toString()).to.equal('string');
|
|
279
|
-
});
|
|
280
|
-
it('adds a fully qualified name of a function in a namespace to the parsers symbol table', () => {
|
|
281
|
-
let parser = parse(`
|
|
282
|
-
namespace Name.Space
|
|
283
|
-
function funcInt() as integer
|
|
284
|
-
return 3
|
|
285
|
-
end function
|
|
286
|
-
|
|
287
|
-
function funcStr() as string
|
|
288
|
-
return "hello"
|
|
289
|
-
end function
|
|
290
|
-
end namespace
|
|
291
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
292
|
-
chai_1.expect(parser.symbolTable.getSymbolType('Name.Space.funcInt')).to.be.instanceof(FunctionType_1.FunctionType);
|
|
293
|
-
chai_1.expect(parser.symbolTable.getSymbolType('Name.Space.funcStr')).to.be.instanceof(FunctionType_1.FunctionType);
|
|
381
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('namespace').message);
|
|
294
382
|
});
|
|
295
383
|
});
|
|
296
384
|
it('supports << operator', () => {
|
|
297
385
|
var _a;
|
|
298
|
-
|
|
386
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
299
387
|
sub main()
|
|
300
388
|
print ((r << 24) + (g << 16) + (b << 8) + a)
|
|
301
389
|
end sub
|
|
@@ -303,7 +391,7 @@ describe('parser', () => {
|
|
|
303
391
|
});
|
|
304
392
|
it('supports >> operator', () => {
|
|
305
393
|
var _a;
|
|
306
|
-
|
|
394
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
307
395
|
sub main()
|
|
308
396
|
print ((r >> 24) + (g >> 16) + (b >> 8) + a)
|
|
309
397
|
end sub
|
|
@@ -311,7 +399,7 @@ describe('parser', () => {
|
|
|
311
399
|
});
|
|
312
400
|
it('allows global function names with same as token to be called', () => {
|
|
313
401
|
var _a;
|
|
314
|
-
|
|
402
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
315
403
|
sub main()
|
|
316
404
|
print string(123)
|
|
317
405
|
end sub
|
|
@@ -325,18 +413,18 @@ describe('parser', () => {
|
|
|
325
413
|
age = personXml.firstChild@age
|
|
326
414
|
end sub
|
|
327
415
|
`);
|
|
328
|
-
|
|
329
|
-
let
|
|
330
|
-
let first =
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
let second =
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
416
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
417
|
+
let assignments = parser.ast.statements[0].func.body.statements;
|
|
418
|
+
let first = assignments[0].value;
|
|
419
|
+
(0, chai_config_spec_1.expect)(first).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
|
|
420
|
+
(0, chai_config_spec_1.expect)(first.tokens.name.text).to.equal('firstName');
|
|
421
|
+
(0, chai_config_spec_1.expect)(first.tokens.at.text).to.equal('@');
|
|
422
|
+
(0, chai_config_spec_1.expect)(first.obj.tokens.name.text).to.equal('personXml');
|
|
423
|
+
let second = assignments[1].value;
|
|
424
|
+
(0, chai_config_spec_1.expect)(second).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
|
|
425
|
+
(0, chai_config_spec_1.expect)(second.tokens.name.text).to.equal('age');
|
|
426
|
+
(0, chai_config_spec_1.expect)(second.tokens.at.text).to.equal('@');
|
|
427
|
+
(0, chai_config_spec_1.expect)(second.obj.tokens.name.text).to.equal('firstChild');
|
|
340
428
|
});
|
|
341
429
|
it('does not allow chaining of @ symbols', () => {
|
|
342
430
|
let parser = parse(`
|
|
@@ -345,58 +433,58 @@ describe('parser', () => {
|
|
|
345
433
|
name = personXml@name@age@shoeSize
|
|
346
434
|
end sub
|
|
347
435
|
`);
|
|
348
|
-
|
|
436
|
+
(0, chai_config_spec_1.expect)(parser.diagnostics).not.to.be.empty;
|
|
349
437
|
});
|
|
350
438
|
it('unknown function type does not invalidate rest of function', () => {
|
|
351
|
-
let {
|
|
439
|
+
let { ast, diagnostics } = parse(`
|
|
352
440
|
function log() as UNKNOWN_TYPE
|
|
353
441
|
end function
|
|
354
442
|
`, Parser_1.ParseMode.BrightScript);
|
|
355
|
-
|
|
356
|
-
|
|
443
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types').message); // type validation happens at scope validation step
|
|
444
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
357
445
|
});
|
|
358
446
|
it('unknown function type is not a problem in Brighterscript mode', () => {
|
|
359
|
-
let {
|
|
447
|
+
let { ast, diagnostics } = parse(`
|
|
360
448
|
function log() as UNKNOWN_TYPE
|
|
361
449
|
end function
|
|
362
450
|
`, Parser_1.ParseMode.BrighterScript);
|
|
363
|
-
|
|
364
|
-
|
|
451
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
452
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
365
453
|
});
|
|
366
454
|
it('allows namespaced function type in Brighterscript mode', () => {
|
|
367
|
-
let {
|
|
455
|
+
let { ast, diagnostics } = parse(`
|
|
368
456
|
function log() as SOME_NAMESPACE.UNKNOWN_TYPE
|
|
369
457
|
end function
|
|
370
458
|
`, Parser_1.ParseMode.BrighterScript);
|
|
371
|
-
|
|
372
|
-
|
|
459
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
460
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
373
461
|
});
|
|
374
462
|
it('allows custom parameter types in BrighterscriptMode', () => {
|
|
375
|
-
let {
|
|
463
|
+
let { ast, diagnostics } = parse(`
|
|
376
464
|
sub foo(value as UNKNOWN_TYPE)
|
|
377
465
|
end sub
|
|
378
466
|
`, Parser_1.ParseMode.BrighterScript);
|
|
379
|
-
|
|
380
|
-
|
|
467
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
468
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
381
469
|
});
|
|
382
|
-
it('does
|
|
470
|
+
it('does cause diagnostics when custom parameter types are used in Brightscript Mode', () => {
|
|
383
471
|
let { diagnostics } = parse(`
|
|
384
472
|
sub foo(value as UNKNOWN_TYPE)
|
|
385
473
|
end sub
|
|
386
474
|
`, Parser_1.ParseMode.BrightScript);
|
|
387
|
-
|
|
475
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types').message);
|
|
388
476
|
});
|
|
389
477
|
it('allows custom namespaced parameter types in BrighterscriptMode', () => {
|
|
390
|
-
let {
|
|
478
|
+
let { ast, diagnostics } = parse(`
|
|
391
479
|
sub foo(value as SOME_NAMESPACE.UNKNOWN_TYPE)
|
|
392
480
|
end sub
|
|
393
481
|
`, Parser_1.ParseMode.BrighterScript);
|
|
394
|
-
|
|
395
|
-
|
|
482
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
483
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
396
484
|
});
|
|
397
485
|
it('works with conditionals', () => {
|
|
398
486
|
var _a;
|
|
399
|
-
|
|
487
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
400
488
|
function printNumber()
|
|
401
489
|
if true then
|
|
402
490
|
print 1
|
|
@@ -408,11 +496,11 @@ describe('parser', () => {
|
|
|
408
496
|
});
|
|
409
497
|
it('supports single-line if statements', () => {
|
|
410
498
|
var _a;
|
|
411
|
-
|
|
499
|
+
(0, chai_config_spec_1.expect)((_a = parse(`If true Then print "error" : Stop`).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
412
500
|
});
|
|
413
501
|
it('works with excess newlines', () => {
|
|
414
502
|
var _a;
|
|
415
|
-
let { tokens } =
|
|
503
|
+
let { tokens } = Lexer_1.Lexer.scan('function boolToNumber() as string\n\n' +
|
|
416
504
|
' if true then\n\n' +
|
|
417
505
|
' print 1\n\n' +
|
|
418
506
|
' elseif true then\n\n' +
|
|
@@ -421,112 +509,230 @@ describe('parser', () => {
|
|
|
421
509
|
' print 1\n\n' +
|
|
422
510
|
' end if\n\n' +
|
|
423
511
|
'end function\n\n');
|
|
424
|
-
|
|
512
|
+
(0, chai_config_spec_1.expect)((_a = Parser_1.Parser.parse(tokens).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
425
513
|
});
|
|
426
514
|
it('does not invalidate entire file when line ends with a period', () => {
|
|
427
|
-
let { tokens } =
|
|
515
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
428
516
|
sub main()
|
|
429
517
|
person.a
|
|
430
518
|
end sub
|
|
431
519
|
|
|
432
520
|
`);
|
|
433
521
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
434
|
-
|
|
522
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1, 'Error count should be 0');
|
|
435
523
|
});
|
|
436
|
-
it
|
|
437
|
-
let { tokens } =
|
|
438
|
-
let {
|
|
439
|
-
let printStatement = statements[0];
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
524
|
+
it('allows printing object with trailing period', () => {
|
|
525
|
+
let { tokens } = Lexer_1.Lexer.scan(`print a.`);
|
|
526
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
527
|
+
let printStatement = ast.statements[0];
|
|
528
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier());
|
|
529
|
+
(0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
|
|
530
|
+
(0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.VariableExpression);
|
|
531
|
+
});
|
|
532
|
+
it('allows printing object with trailing period with multiple dotted gets', () => {
|
|
533
|
+
let { tokens } = Lexer_1.Lexer.scan(`print a.b.`);
|
|
534
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
535
|
+
let printStatement = ast.statements[0];
|
|
536
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier());
|
|
537
|
+
(0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
|
|
538
|
+
(0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.DottedGetExpression);
|
|
539
|
+
});
|
|
540
|
+
describe('incomplete statements in the ast', () => {
|
|
541
|
+
it('adds variable expressions to the ast', () => {
|
|
542
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
543
|
+
function a()
|
|
544
|
+
NameA.
|
|
545
|
+
end function
|
|
546
|
+
|
|
547
|
+
namespace NameA
|
|
548
|
+
sub noop()
|
|
549
|
+
end sub
|
|
550
|
+
end namespace
|
|
551
|
+
`);
|
|
552
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
553
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedStatement());
|
|
554
|
+
let stmt = ast.statements[0].func.body.statements[0];
|
|
555
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
556
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)((stmt).expression)).to.be.true;
|
|
557
|
+
(0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('NameA');
|
|
558
|
+
});
|
|
559
|
+
it('adds unended call statements', () => {
|
|
560
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
561
|
+
function a()
|
|
562
|
+
lcase(
|
|
563
|
+
end function
|
|
564
|
+
`);
|
|
565
|
+
let { ast } = Parser_1.Parser.parse(tokens);
|
|
566
|
+
let stmt = ast.statements[0].func.body.statements[0];
|
|
567
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
568
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)((stmt).expression)).to.be.true;
|
|
569
|
+
(0, chai_config_spec_1.expect)(stmt.expression.callee.tokens.name.text).to.equal('lcase');
|
|
570
|
+
});
|
|
571
|
+
it('adds unended indexed get statements', () => {
|
|
572
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
573
|
+
function a()
|
|
574
|
+
nums[
|
|
575
|
+
end function
|
|
576
|
+
|
|
577
|
+
const nums = [1, 2, 3]
|
|
578
|
+
`);
|
|
579
|
+
let { ast } = Parser_1.Parser.parse(tokens);
|
|
580
|
+
let stmt = ast.statements[0].func.body.statements[0];
|
|
581
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
582
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isIndexedGetExpression)((stmt).expression)).to.be.true;
|
|
583
|
+
(0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('nums');
|
|
584
|
+
});
|
|
585
|
+
it('adds dotted gets', () => {
|
|
586
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
587
|
+
function foo(a as KlassA)
|
|
588
|
+
a.b.
|
|
589
|
+
end function
|
|
590
|
+
|
|
591
|
+
class KlassA
|
|
592
|
+
b as KlassB
|
|
593
|
+
end class
|
|
594
|
+
|
|
595
|
+
class KlassB
|
|
596
|
+
sub noop()
|
|
597
|
+
end sub
|
|
598
|
+
end class
|
|
599
|
+
`);
|
|
600
|
+
let { ast } = Parser_1.Parser.parse(tokens);
|
|
601
|
+
let stmt = ast.statements[0].func.body.statements[0];
|
|
602
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
603
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)((stmt).expression)).to.be.true;
|
|
604
|
+
(0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('a');
|
|
605
|
+
(0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('b');
|
|
606
|
+
});
|
|
607
|
+
it('adds function statement with missing type after as', () => {
|
|
608
|
+
var _a;
|
|
609
|
+
let parser = parse(`
|
|
610
|
+
sub foo(thing as )
|
|
611
|
+
print thing
|
|
612
|
+
end sub
|
|
613
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
614
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
615
|
+
(0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
616
|
+
});
|
|
617
|
+
it('adds binary expressions to the ast', () => {
|
|
618
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
619
|
+
function a(x, y)
|
|
620
|
+
1 or 2
|
|
621
|
+
x * y
|
|
622
|
+
x + y
|
|
623
|
+
x - y
|
|
624
|
+
end function
|
|
625
|
+
`);
|
|
626
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
627
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedStatement());
|
|
628
|
+
for (const stmt of ast.statements[0].func.body.statements) {
|
|
629
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
630
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)((stmt).expression)).to.be.true;
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
it('adds callfunc expressions', () => {
|
|
634
|
+
var _a;
|
|
635
|
+
let parser = parse(`
|
|
636
|
+
sub foo(thing)
|
|
637
|
+
thing@.
|
|
638
|
+
end sub
|
|
639
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
640
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
641
|
+
let body = parser.ast.statements[0].func.body;
|
|
642
|
+
let callFunc = body.findChild(reflection_1.isCallfuncExpression);
|
|
643
|
+
(0, chai_config_spec_1.expect)(callFunc).to.exist;
|
|
644
|
+
});
|
|
645
|
+
it('adds if statements', () => {
|
|
646
|
+
var _a;
|
|
647
|
+
let parser = parse(`
|
|
648
|
+
sub foo(thing)
|
|
649
|
+
if thing.
|
|
650
|
+
end sub
|
|
651
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
652
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
653
|
+
let body = parser.ast.statements[0].func.body;
|
|
654
|
+
let ifStmt = body.findChild(reflection_1.isIfStatement);
|
|
655
|
+
(0, chai_config_spec_1.expect)(ifStmt).to.exist;
|
|
656
|
+
});
|
|
443
657
|
});
|
|
444
658
|
describe('comments', () => {
|
|
445
|
-
it('
|
|
446
|
-
let { tokens } =
|
|
659
|
+
it('does not include comments', () => {
|
|
660
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
447
661
|
'line 1
|
|
448
662
|
'line 2
|
|
449
663
|
'line 3
|
|
450
664
|
`);
|
|
451
|
-
let {
|
|
452
|
-
|
|
453
|
-
|
|
665
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
666
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
667
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.equal(0);
|
|
454
668
|
});
|
|
455
|
-
it('does
|
|
456
|
-
let { tokens } =
|
|
669
|
+
it('does matter if comments separated by newlines', () => {
|
|
670
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
457
671
|
'line 1
|
|
458
672
|
|
|
459
673
|
'line 2
|
|
460
674
|
|
|
461
675
|
'line 3
|
|
462
676
|
`);
|
|
463
|
-
let {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
chai_1.expect(statements[0].text).to.equal(`'line 1`);
|
|
467
|
-
chai_1.expect(statements[1].text).to.equal(`'line 2`);
|
|
468
|
-
chai_1.expect(statements[2].text).to.equal(`'line 3`);
|
|
677
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
678
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
679
|
+
(0, chai_config_spec_1.expect)(ast.statements).to.be.lengthOf(0);
|
|
469
680
|
});
|
|
470
681
|
it('works after print statement', () => {
|
|
471
|
-
let { tokens } =
|
|
682
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
472
683
|
sub main()
|
|
473
684
|
print "hi" 'comment 1
|
|
474
685
|
end sub
|
|
475
686
|
`);
|
|
476
|
-
let {
|
|
477
|
-
|
|
478
|
-
|
|
687
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
688
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
689
|
+
(0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements.length).to.equal(1);
|
|
479
690
|
});
|
|
480
|
-
it('declaration-level', () => {
|
|
481
|
-
let { tokens } =
|
|
691
|
+
it('declaration-level should be set as leading trivia', () => {
|
|
692
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
482
693
|
'comment 1
|
|
483
694
|
function a()
|
|
484
695
|
end function
|
|
485
696
|
'comment 2
|
|
486
697
|
`);
|
|
487
|
-
let {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
chai_1.expect(statements[2].text).to.equal(`'comment 2`);
|
|
698
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
699
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
700
|
+
(0, chai_config_spec_1.expect)(ast.statements[0].leadingTrivia[2].text).to.equal(`'comment 1`);
|
|
491
701
|
});
|
|
492
702
|
it('works in aa literal as its own statement', () => {
|
|
493
|
-
let { tokens } =
|
|
703
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
494
704
|
obj = {
|
|
495
705
|
"name": true,
|
|
496
706
|
'comment
|
|
497
707
|
}
|
|
498
708
|
`);
|
|
499
709
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
500
|
-
|
|
710
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
501
711
|
});
|
|
502
712
|
it('parses after function call', () => {
|
|
503
|
-
let { tokens } =
|
|
713
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
504
714
|
sub Main()
|
|
505
715
|
name = "Hello"
|
|
506
716
|
DoSomething(name) 'comment 1
|
|
507
717
|
end sub
|
|
508
718
|
`);
|
|
509
|
-
let { diagnostics
|
|
510
|
-
|
|
511
|
-
chai_1.expect(statements[0].func.body.statements[2].text).to.equal(`'comment 1`);
|
|
719
|
+
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
720
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
512
721
|
});
|
|
513
722
|
it('function', () => {
|
|
514
|
-
let { tokens } =
|
|
723
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
515
724
|
function a() 'comment 1
|
|
516
725
|
'comment 2
|
|
517
726
|
num = 1
|
|
518
727
|
'comment 3
|
|
519
728
|
end function 'comment 4
|
|
520
729
|
`);
|
|
521
|
-
let {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 2`);
|
|
525
|
-
chai_1.expect(statements[0].func.body.statements[3].text).to.equal(`'comment 3`);
|
|
526
|
-
chai_1.expect(statements[1].text).to.equal(`'comment 4`);
|
|
730
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
731
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
732
|
+
(0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].leadingTrivia.filter(x => x.kind === TokenKind_1.TokenKind.Comment).map(x => x.text)).members([`'comment 1`, `'comment 2`]);
|
|
527
733
|
});
|
|
528
734
|
it('if statement`', () => {
|
|
529
|
-
let { tokens } =
|
|
735
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
530
736
|
function a()
|
|
531
737
|
if true then 'comment 1
|
|
532
738
|
'comment 2
|
|
@@ -543,25 +749,19 @@ describe('parser', () => {
|
|
|
543
749
|
end if 'comment 10
|
|
544
750
|
end function
|
|
545
751
|
`);
|
|
546
|
-
let {
|
|
547
|
-
|
|
548
|
-
let fnSmt = statements[0];
|
|
549
|
-
if (reflection_1.isFunctionStatement(fnSmt)) {
|
|
752
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
753
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
754
|
+
let fnSmt = ast.statements[0];
|
|
755
|
+
if ((0, reflection_1.isFunctionStatement)(fnSmt)) {
|
|
550
756
|
let ifStmt = fnSmt.func.body.statements[0];
|
|
551
|
-
if (reflection_1.isIfStatement(ifStmt)) {
|
|
552
|
-
expectCommentWithText(ifStmt.thenBranch.statements[0], `'comment 1`);
|
|
553
|
-
expectCommentWithText(ifStmt.thenBranch.statements[1], `'comment 2`);
|
|
554
|
-
expectCommentWithText(ifStmt.thenBranch.statements[3], `'comment 3`);
|
|
757
|
+
if ((0, reflection_1.isIfStatement)(ifStmt)) {
|
|
758
|
+
expectCommentWithText(ifStmt.thenBranch.statements[0], `'comment 1\n'comment 2`);
|
|
555
759
|
let elseIfBranch = ifStmt.elseBranch;
|
|
556
|
-
if (reflection_1.isIfStatement(elseIfBranch)) {
|
|
557
|
-
expectCommentWithText(elseIfBranch.thenBranch.statements[0], `'comment 4`);
|
|
558
|
-
expectCommentWithText(elseIfBranch.thenBranch.statements[1], `'comment 5`);
|
|
559
|
-
expectCommentWithText(elseIfBranch.thenBranch.statements[3], `'comment 6`);
|
|
760
|
+
if ((0, reflection_1.isIfStatement)(elseIfBranch)) {
|
|
761
|
+
expectCommentWithText(elseIfBranch.thenBranch.statements[0], `'comment 4\n'comment 5`);
|
|
560
762
|
let elseBranch = elseIfBranch.elseBranch;
|
|
561
|
-
if (reflection_1.isBlock(elseBranch)) {
|
|
562
|
-
expectCommentWithText(elseBranch.statements[0], `'comment 7`);
|
|
563
|
-
expectCommentWithText(elseBranch.statements[1], `'comment 8`);
|
|
564
|
-
expectCommentWithText(elseBranch.statements[3], `'comment 9`);
|
|
763
|
+
if ((0, reflection_1.isBlock)(elseBranch)) {
|
|
764
|
+
expectCommentWithText(elseBranch.statements[0], `'comment 7\n'comment 8`);
|
|
565
765
|
}
|
|
566
766
|
else {
|
|
567
767
|
failStatementType(elseBranch, 'Block');
|
|
@@ -570,7 +770,6 @@ describe('parser', () => {
|
|
|
570
770
|
else {
|
|
571
771
|
failStatementType(elseIfBranch, 'If');
|
|
572
772
|
}
|
|
573
|
-
expectCommentWithText(fnSmt.func.body.statements[1], `'comment 10`);
|
|
574
773
|
}
|
|
575
774
|
else {
|
|
576
775
|
failStatementType(ifStmt, 'If');
|
|
@@ -581,7 +780,7 @@ describe('parser', () => {
|
|
|
581
780
|
}
|
|
582
781
|
});
|
|
583
782
|
it('while', () => {
|
|
584
|
-
let { tokens } =
|
|
783
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
585
784
|
function a()
|
|
586
785
|
while true 'comment 1
|
|
587
786
|
'comment 2
|
|
@@ -590,16 +789,13 @@ describe('parser', () => {
|
|
|
590
789
|
end while 'comment 4
|
|
591
790
|
end function
|
|
592
791
|
`);
|
|
593
|
-
let {
|
|
594
|
-
|
|
595
|
-
let stmt = statements[0].func.body.statements[0];
|
|
596
|
-
|
|
597
|
-
chai_1.expect(stmt.body.statements[1].text).to.equal(`'comment 2`);
|
|
598
|
-
chai_1.expect(stmt.body.statements[3].text).to.equal(`'comment 3`);
|
|
599
|
-
chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
|
|
792
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
793
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
794
|
+
let stmt = ast.statements[0].func.body.statements[0];
|
|
795
|
+
expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
|
|
600
796
|
});
|
|
601
797
|
it('for', () => {
|
|
602
|
-
let { tokens } =
|
|
798
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
603
799
|
function a()
|
|
604
800
|
for i = 0 to 10 step 1 'comment 1
|
|
605
801
|
'comment 2
|
|
@@ -608,16 +804,13 @@ describe('parser', () => {
|
|
|
608
804
|
end for 'comment 4
|
|
609
805
|
end function
|
|
610
806
|
`);
|
|
611
|
-
let {
|
|
612
|
-
|
|
613
|
-
let stmt = statements[0].func.body.statements[0];
|
|
614
|
-
|
|
615
|
-
chai_1.expect(stmt.body.statements[1].text).to.equal(`'comment 2`);
|
|
616
|
-
chai_1.expect(stmt.body.statements[3].text).to.equal(`'comment 3`);
|
|
617
|
-
chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
|
|
807
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
808
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
809
|
+
let stmt = ast.statements[0].func.body.statements[0];
|
|
810
|
+
expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
|
|
618
811
|
});
|
|
619
812
|
it('for each', () => {
|
|
620
|
-
let { tokens } =
|
|
813
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
621
814
|
function a()
|
|
622
815
|
for each val in [1,2,3] 'comment 1
|
|
623
816
|
'comment 2
|
|
@@ -626,13 +819,10 @@ describe('parser', () => {
|
|
|
626
819
|
end for 'comment 4
|
|
627
820
|
end function
|
|
628
821
|
`);
|
|
629
|
-
let {
|
|
630
|
-
|
|
631
|
-
let stmt = statements[0].func.body.statements[0];
|
|
632
|
-
|
|
633
|
-
chai_1.expect(stmt.body.statements[1].text).to.equal(`'comment 2`);
|
|
634
|
-
chai_1.expect(stmt.body.statements[3].text).to.equal(`'comment 3`);
|
|
635
|
-
chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
|
|
822
|
+
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
823
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
824
|
+
let stmt = ast.statements[0].func.body.statements[0];
|
|
825
|
+
expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
|
|
636
826
|
});
|
|
637
827
|
});
|
|
638
828
|
});
|
|
@@ -644,7 +834,7 @@ describe('parser', () => {
|
|
|
644
834
|
then = true
|
|
645
835
|
end sub
|
|
646
836
|
`);
|
|
647
|
-
|
|
837
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1);
|
|
648
838
|
});
|
|
649
839
|
it('is allowed as an AA property name', () => {
|
|
650
840
|
var _a;
|
|
@@ -657,7 +847,39 @@ describe('parser', () => {
|
|
|
657
847
|
print person.then
|
|
658
848
|
end sub
|
|
659
849
|
`);
|
|
660
|
-
|
|
850
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
851
|
+
});
|
|
852
|
+
it('allows `mod` as an AA literal property', () => {
|
|
853
|
+
const parser = parse(`
|
|
854
|
+
sub main()
|
|
855
|
+
person = {
|
|
856
|
+
mod: true
|
|
857
|
+
}
|
|
858
|
+
person.mod = false
|
|
859
|
+
print person.mod
|
|
860
|
+
end sub
|
|
861
|
+
`);
|
|
862
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
863
|
+
});
|
|
864
|
+
it('converts aa literal property TokenKind to Identifier', () => {
|
|
865
|
+
const parser = parse(`
|
|
866
|
+
sub main()
|
|
867
|
+
person = {
|
|
868
|
+
mod: true
|
|
869
|
+
and: true
|
|
870
|
+
}
|
|
871
|
+
end sub
|
|
872
|
+
`);
|
|
873
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
874
|
+
const elements = [];
|
|
875
|
+
parser.ast.walk((0, visitors_1.createVisitor)({
|
|
876
|
+
AAMemberExpression: (node) => {
|
|
877
|
+
elements.push(node);
|
|
878
|
+
}
|
|
879
|
+
}), {
|
|
880
|
+
walkMode: visitors_1.WalkMode.visitAllRecursive
|
|
881
|
+
});
|
|
882
|
+
(0, chai_config_spec_1.expect)(elements.map(x => x.tokens.key.kind)).to.eql([TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.Identifier]);
|
|
661
883
|
});
|
|
662
884
|
});
|
|
663
885
|
it('"end" is not allowed as a local identifier', () => {
|
|
@@ -666,47 +888,47 @@ describe('parser', () => {
|
|
|
666
888
|
end = true
|
|
667
889
|
end sub
|
|
668
890
|
`);
|
|
669
|
-
|
|
891
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.length.greaterThan(0);
|
|
670
892
|
});
|
|
671
893
|
it('none of them can be used as local variables', () => {
|
|
672
|
-
let reservedWords = new Set(
|
|
894
|
+
let reservedWords = new Set(TokenKind_1.ReservedWords);
|
|
673
895
|
//remove the rem keyword because it's a comment...won't cause error
|
|
674
896
|
reservedWords.delete('rem');
|
|
675
897
|
for (let reservedWord of reservedWords) {
|
|
676
|
-
let { tokens } =
|
|
898
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
677
899
|
sub main()
|
|
678
900
|
${reservedWord} = true
|
|
679
901
|
end sub
|
|
680
902
|
`);
|
|
681
903
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
682
|
-
|
|
904
|
+
(0, chai_config_spec_1.expect)(diagnostics, `assigning to reserved word "${reservedWord}" should have been an error`).to.be.length.greaterThan(0);
|
|
683
905
|
}
|
|
684
906
|
});
|
|
685
907
|
});
|
|
686
908
|
describe('import keyword', () => {
|
|
687
909
|
it('parses without errors', () => {
|
|
688
910
|
var _a;
|
|
689
|
-
let {
|
|
911
|
+
let { ast, diagnostics } = parse(`
|
|
690
912
|
import "somePath"
|
|
691
913
|
`, Parser_1.ParseMode.BrighterScript);
|
|
692
|
-
|
|
693
|
-
|
|
914
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
915
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
694
916
|
});
|
|
695
917
|
it('catches import statements used in brightscript files', () => {
|
|
696
918
|
var _a;
|
|
697
|
-
let {
|
|
919
|
+
let { ast, diagnostics } = parse(`
|
|
698
920
|
import "somePath"
|
|
699
921
|
`, Parser_1.ParseMode.BrightScript);
|
|
700
|
-
|
|
701
|
-
|
|
922
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.eql(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('import statements').message);
|
|
923
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
702
924
|
});
|
|
703
925
|
it('catchs missing file path', () => {
|
|
704
926
|
var _a;
|
|
705
|
-
let {
|
|
927
|
+
let { ast, diagnostics } = parse(`
|
|
706
928
|
import
|
|
707
929
|
`, Parser_1.ParseMode.BrighterScript);
|
|
708
|
-
|
|
709
|
-
|
|
930
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import').message);
|
|
931
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
710
932
|
});
|
|
711
933
|
});
|
|
712
934
|
describe('Annotations', () => {
|
|
@@ -717,7 +939,7 @@ describe('parser', () => {
|
|
|
717
939
|
sub main()
|
|
718
940
|
end sub
|
|
719
941
|
`, Parser_1.ParseMode.BrighterScript);
|
|
720
|
-
|
|
942
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('@').message);
|
|
721
943
|
});
|
|
722
944
|
it('properly handles empty annotation above class method', () => {
|
|
723
945
|
var _a;
|
|
@@ -729,7 +951,7 @@ describe('parser', () => {
|
|
|
729
951
|
end sub
|
|
730
952
|
end class
|
|
731
953
|
`, Parser_1.ParseMode.BrighterScript);
|
|
732
|
-
|
|
954
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier().message);
|
|
733
955
|
});
|
|
734
956
|
it('parses with error if annotation is not followed by a statement', () => {
|
|
735
957
|
var _a, _b, _c, _d;
|
|
@@ -743,15 +965,15 @@ describe('parser', () => {
|
|
|
743
965
|
end class
|
|
744
966
|
@meta1
|
|
745
967
|
`, Parser_1.ParseMode.BrighterScript);
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
968
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(4);
|
|
969
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
970
|
+
(0, chai_config_spec_1.expect)((_b = diagnostics[1]) === null || _b === void 0 ? void 0 : _b.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
971
|
+
(0, chai_config_spec_1.expect)((_c = diagnostics[2]) === null || _c === void 0 ? void 0 : _c.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
972
|
+
(0, chai_config_spec_1.expect)((_d = diagnostics[3]) === null || _d === void 0 ? void 0 : _d.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
751
973
|
});
|
|
752
974
|
it('attaches an annotation to next statement', () => {
|
|
753
975
|
var _a;
|
|
754
|
-
let {
|
|
976
|
+
let { ast, diagnostics } = parse(`
|
|
755
977
|
@meta1
|
|
756
978
|
function main()
|
|
757
979
|
end function
|
|
@@ -759,69 +981,69 @@ describe('parser', () => {
|
|
|
759
981
|
@meta2 sub init()
|
|
760
982
|
end sub
|
|
761
983
|
`, Parser_1.ParseMode.BrighterScript);
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
let fn = statements[0];
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
fn = statements[1];
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
984
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
985
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
986
|
+
let fn = ast.statements[0];
|
|
987
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
988
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
989
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
|
|
990
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].name).to.equal('meta1');
|
|
991
|
+
(0, chai_config_spec_1.expect)(ast.statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
992
|
+
fn = ast.statements[1];
|
|
993
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
994
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
995
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta2');
|
|
774
996
|
});
|
|
775
997
|
it('attaches annotations inside a function body', () => {
|
|
776
998
|
var _a, _b;
|
|
777
|
-
let {
|
|
999
|
+
let { ast, diagnostics } = parse(`
|
|
778
1000
|
function main()
|
|
779
1001
|
@meta1
|
|
780
1002
|
print "hello"
|
|
781
1003
|
end function
|
|
782
1004
|
`, Parser_1.ParseMode.BrighterScript);
|
|
783
|
-
|
|
784
|
-
let fn = statements[0];
|
|
1005
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1006
|
+
let fn = ast.statements[0];
|
|
785
1007
|
let fnStatements = fn.func.body.statements;
|
|
786
1008
|
let stat = fnStatements[0];
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
1009
|
+
(0, chai_config_spec_1.expect)(stat).to.exist;
|
|
1010
|
+
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1011
|
+
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
790
1012
|
});
|
|
791
1013
|
it('attaches multiple annotations to next statement', () => {
|
|
792
1014
|
var _a;
|
|
793
|
-
let {
|
|
1015
|
+
let { ast, diagnostics } = parse(`
|
|
794
1016
|
@meta1
|
|
795
1017
|
@meta2 @meta3
|
|
796
1018
|
function main()
|
|
797
1019
|
end function
|
|
798
1020
|
`, Parser_1.ParseMode.BrighterScript);
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
let fn = statements[0];
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
1021
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1022
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1023
|
+
let fn = ast.statements[0];
|
|
1024
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1025
|
+
(0, chai_config_spec_1.expect)(fn.annotations.length).to.equal(3);
|
|
1026
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1027
|
+
(0, chai_config_spec_1.expect)(fn.annotations[1]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1028
|
+
(0, chai_config_spec_1.expect)(fn.annotations[2]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
807
1029
|
});
|
|
808
1030
|
it('allows annotations with parameters', () => {
|
|
809
1031
|
var _a;
|
|
810
|
-
let {
|
|
1032
|
+
let { ast, diagnostics } = parse(`
|
|
811
1033
|
@meta1("arg", 2, true, { prop: "value" })
|
|
812
1034
|
function main()
|
|
813
1035
|
end function
|
|
814
1036
|
`, Parser_1.ParseMode.BrighterScript);
|
|
815
|
-
|
|
816
|
-
let fn = statements[0];
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
1037
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1038
|
+
let fn = ast.statements[0];
|
|
1039
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1040
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1041
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
|
|
1042
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].call).to.be.instanceof(Expression_1.CallExpression);
|
|
821
1043
|
});
|
|
822
1044
|
it('attaches annotations to a class', () => {
|
|
823
1045
|
var _a, _b;
|
|
824
|
-
let {
|
|
1046
|
+
let { ast, diagnostics } = parse(`
|
|
825
1047
|
@meta1
|
|
826
1048
|
class MyClass
|
|
827
1049
|
function main()
|
|
@@ -829,14 +1051,14 @@ describe('parser', () => {
|
|
|
829
1051
|
end function
|
|
830
1052
|
end class
|
|
831
1053
|
`, Parser_1.ParseMode.BrighterScript);
|
|
832
|
-
|
|
833
|
-
let cs = statements[0];
|
|
834
|
-
|
|
835
|
-
|
|
1054
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1055
|
+
let cs = ast.statements[0];
|
|
1056
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1057
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
836
1058
|
});
|
|
837
1059
|
it('attaches annotations to multiple clases', () => {
|
|
838
1060
|
var _a, _b, _c;
|
|
839
|
-
let {
|
|
1061
|
+
let { ast, diagnostics } = parse(`
|
|
840
1062
|
@meta1
|
|
841
1063
|
class MyClass
|
|
842
1064
|
function main()
|
|
@@ -850,19 +1072,19 @@ describe('parser', () => {
|
|
|
850
1072
|
end function
|
|
851
1073
|
end class
|
|
852
1074
|
`, Parser_1.ParseMode.BrighterScript);
|
|
853
|
-
|
|
854
|
-
let cs = statements[0];
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
let cs2 = statements[1];
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
1075
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1076
|
+
let cs = ast.statements[0];
|
|
1077
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1078
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1079
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
|
|
1080
|
+
let cs2 = ast.statements[1];
|
|
1081
|
+
(0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
|
|
1082
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1083
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
|
|
862
1084
|
});
|
|
863
1085
|
it('attaches annotations to a namespaced class', () => {
|
|
864
1086
|
var _a, _b;
|
|
865
|
-
let {
|
|
1087
|
+
let { ast, diagnostics } = parse(`
|
|
866
1088
|
namespace ns
|
|
867
1089
|
@meta1
|
|
868
1090
|
class MyClass
|
|
@@ -872,15 +1094,15 @@ describe('parser', () => {
|
|
|
872
1094
|
end class
|
|
873
1095
|
end namespace
|
|
874
1096
|
`, Parser_1.ParseMode.BrighterScript);
|
|
875
|
-
|
|
876
|
-
let ns = statements[0];
|
|
1097
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1098
|
+
let ns = ast.statements[0];
|
|
877
1099
|
let cs = ns.body.statements[0];
|
|
878
|
-
|
|
879
|
-
|
|
1100
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1101
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
880
1102
|
});
|
|
881
1103
|
it('attaches annotations to a namespaced class - multiple', () => {
|
|
882
1104
|
var _a, _b, _c;
|
|
883
|
-
let {
|
|
1105
|
+
let { ast, diagnostics } = parse(`
|
|
884
1106
|
namespace ns
|
|
885
1107
|
@meta1
|
|
886
1108
|
class MyClass
|
|
@@ -896,20 +1118,20 @@ describe('parser', () => {
|
|
|
896
1118
|
end class
|
|
897
1119
|
end namespace
|
|
898
1120
|
`, Parser_1.ParseMode.BrighterScript);
|
|
899
|
-
|
|
900
|
-
let ns = statements[0];
|
|
1121
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1122
|
+
let ns = ast.statements[0];
|
|
901
1123
|
let cs = ns.body.statements[0];
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
1124
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1125
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1126
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
|
|
905
1127
|
let cs2 = ns.body.statements[1];
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
1128
|
+
(0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
|
|
1129
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1130
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
|
|
909
1131
|
});
|
|
910
1132
|
it('attaches annotations to a class constructor', () => {
|
|
911
1133
|
var _a, _b;
|
|
912
|
-
let {
|
|
1134
|
+
let { ast, diagnostics } = parse(`
|
|
913
1135
|
class MyClass
|
|
914
1136
|
@meta1
|
|
915
1137
|
function new()
|
|
@@ -920,15 +1142,15 @@ describe('parser', () => {
|
|
|
920
1142
|
end function
|
|
921
1143
|
end class
|
|
922
1144
|
`, Parser_1.ParseMode.BrighterScript);
|
|
923
|
-
|
|
924
|
-
let cs = statements[0];
|
|
1145
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1146
|
+
let cs = ast.statements[0];
|
|
925
1147
|
let stat = cs.body[0];
|
|
926
|
-
|
|
927
|
-
|
|
1148
|
+
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1149
|
+
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
928
1150
|
});
|
|
929
1151
|
it('attaches annotations to a class methods', () => {
|
|
930
1152
|
var _a, _b;
|
|
931
|
-
let {
|
|
1153
|
+
let { ast, diagnostics } = parse(`
|
|
932
1154
|
class MyClass
|
|
933
1155
|
function new()
|
|
934
1156
|
print "hello"
|
|
@@ -939,15 +1161,15 @@ describe('parser', () => {
|
|
|
939
1161
|
end function
|
|
940
1162
|
end class
|
|
941
1163
|
`, Parser_1.ParseMode.BrighterScript);
|
|
942
|
-
|
|
943
|
-
let cs = statements[0];
|
|
1164
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1165
|
+
let cs = ast.statements[0];
|
|
944
1166
|
let stat = cs.body[1];
|
|
945
|
-
|
|
946
|
-
|
|
1167
|
+
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1168
|
+
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
947
1169
|
});
|
|
948
1170
|
it('attaches annotations to a class methods, fields and constructor', () => {
|
|
949
1171
|
var _a, _b, _c, _d, _e;
|
|
950
|
-
let {
|
|
1172
|
+
let { ast, diagnostics } = parse(`
|
|
951
1173
|
@meta2
|
|
952
1174
|
@meta1
|
|
953
1175
|
class MyClass
|
|
@@ -967,36 +1189,36 @@ describe('parser', () => {
|
|
|
967
1189
|
public foo="bar"
|
|
968
1190
|
end class
|
|
969
1191
|
`, Parser_1.ParseMode.BrighterScript);
|
|
970
|
-
|
|
971
|
-
let cs = statements[0];
|
|
972
|
-
|
|
973
|
-
|
|
1192
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1193
|
+
let cs = ast.statements[0];
|
|
1194
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(2);
|
|
1195
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
974
1196
|
let stat1 = cs.body[0];
|
|
975
1197
|
let stat2 = cs.body[1];
|
|
976
1198
|
let f1 = cs.body[2];
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1199
|
+
(0, chai_config_spec_1.expect)((_c = stat1.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
|
|
1200
|
+
(0, chai_config_spec_1.expect)(stat1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1201
|
+
(0, chai_config_spec_1.expect)((_d = stat2.annotations) === null || _d === void 0 ? void 0 : _d.length).to.equal(2);
|
|
1202
|
+
(0, chai_config_spec_1.expect)(stat2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1203
|
+
(0, chai_config_spec_1.expect)((_e = f1.annotations) === null || _e === void 0 ? void 0 : _e.length).to.equal(2);
|
|
1204
|
+
(0, chai_config_spec_1.expect)(f1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
983
1205
|
});
|
|
984
1206
|
it('ignores annotations on commented out lines', () => {
|
|
985
1207
|
var _a;
|
|
986
|
-
let {
|
|
1208
|
+
let { ast, diagnostics } = parse(`
|
|
987
1209
|
'@meta1
|
|
988
1210
|
' @meta1
|
|
989
1211
|
function new()
|
|
990
1212
|
print "hello"
|
|
991
1213
|
end function
|
|
992
1214
|
`, Parser_1.ParseMode.BrighterScript);
|
|
993
|
-
|
|
994
|
-
let cs = statements[0];
|
|
995
|
-
|
|
1215
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1216
|
+
let cs = ast.statements[0];
|
|
1217
|
+
(0, chai_config_spec_1.expect)(cs.annotations).to.be.undefined;
|
|
996
1218
|
});
|
|
997
1219
|
it('can convert argument of an annotation to JS types', () => {
|
|
998
1220
|
var _a;
|
|
999
|
-
let {
|
|
1221
|
+
let { ast, diagnostics } = parse(`
|
|
1000
1222
|
@meta1
|
|
1001
1223
|
function main()
|
|
1002
1224
|
end function
|
|
@@ -1010,26 +1232,26 @@ describe('parser', () => {
|
|
|
1010
1232
|
sub init()
|
|
1011
1233
|
end sub
|
|
1012
1234
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
let fn = statements[0];
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
fn = statements[1];
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1235
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1236
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1237
|
+
let fn = ast.statements[0];
|
|
1238
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1239
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([]);
|
|
1240
|
+
(0, chai_config_spec_1.expect)(ast.statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1241
|
+
fn = ast.statements[1];
|
|
1242
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1243
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1244
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([
|
|
1023
1245
|
'arg', 2, true,
|
|
1024
1246
|
{ prop: 'value' }, [1, 2],
|
|
1025
1247
|
null
|
|
1026
1248
|
]);
|
|
1027
1249
|
let allArgs = fn.annotations[0].getArguments(false);
|
|
1028
|
-
|
|
1250
|
+
(0, chai_config_spec_1.expect)(allArgs.pop()).to.be.instanceOf(Expression_1.FunctionExpression);
|
|
1029
1251
|
});
|
|
1030
1252
|
it('can handle negative numbers', () => {
|
|
1031
1253
|
var _a;
|
|
1032
|
-
let {
|
|
1254
|
+
let { ast, diagnostics } = parse(`
|
|
1033
1255
|
@meta(-100)
|
|
1034
1256
|
function main()
|
|
1035
1257
|
end function
|
|
@@ -1037,161 +1259,1523 @@ describe('parser', () => {
|
|
|
1037
1259
|
sub init()
|
|
1038
1260
|
end sub
|
|
1039
1261
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
let fn = statements[0];
|
|
1043
|
-
|
|
1044
|
-
|
|
1262
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1263
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1264
|
+
let fn = ast.statements[0];
|
|
1265
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1266
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([-100]);
|
|
1045
1267
|
});
|
|
1046
1268
|
});
|
|
1047
|
-
describe('
|
|
1048
|
-
it('
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
end sub
|
|
1269
|
+
describe('type casts', () => {
|
|
1270
|
+
it('is not allowed in brightscript mode', () => {
|
|
1271
|
+
var _a;
|
|
1272
|
+
let parser = parse(`
|
|
1273
|
+
sub main(node as dynamic)
|
|
1274
|
+
print lcase((node as string))
|
|
1054
1275
|
end sub
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
const type = Parser_1.getBscTypeFromExpression(func.body.statements[0].value, func);
|
|
1058
|
-
chai_1.expect(type.returnType).to.be.instanceof(VoidType_1.VoidType);
|
|
1276
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1277
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('type cast').message);
|
|
1059
1278
|
});
|
|
1060
|
-
it('
|
|
1061
|
-
|
|
1279
|
+
it('allows type casts after function calls', () => {
|
|
1280
|
+
var _a;
|
|
1281
|
+
let { ast, diagnostics } = parse(`
|
|
1062
1282
|
sub main()
|
|
1063
|
-
|
|
1064
|
-
return "hello"
|
|
1065
|
-
end sub
|
|
1283
|
+
value = getValue() as integer
|
|
1066
1284
|
end sub
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1285
|
+
|
|
1286
|
+
function getValue()
|
|
1287
|
+
return 123
|
|
1288
|
+
end function
|
|
1289
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1290
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1291
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1292
|
+
let fn = ast.statements[0];
|
|
1293
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1294
|
+
let assignment = fn.func.body.statements[0];
|
|
1295
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
|
|
1296
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(assignment.value)).to.be.true;
|
|
1297
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value.obj)).to.be.true;
|
|
1298
|
+
(0, testHelpers_spec_1.expectTypeToBe)(assignment.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), IntegerType_1.IntegerType);
|
|
1071
1299
|
});
|
|
1072
|
-
it('
|
|
1073
|
-
|
|
1300
|
+
it('allows type casts in the middle of expressions', () => {
|
|
1301
|
+
var _a;
|
|
1302
|
+
let { ast, diagnostics } = parse(`
|
|
1074
1303
|
sub main()
|
|
1075
|
-
|
|
1076
|
-
return new Person()
|
|
1077
|
-
end sub
|
|
1304
|
+
value = (getValue() as integer).toStr()
|
|
1078
1305
|
end sub
|
|
1079
1306
|
|
|
1080
|
-
|
|
1081
|
-
|
|
1307
|
+
function getValue()
|
|
1308
|
+
return 123
|
|
1309
|
+
end function
|
|
1082
1310
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1311
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1312
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1313
|
+
let fn = ast.statements[0];
|
|
1314
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1315
|
+
let assignment = fn.func.body.statements[0];
|
|
1316
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
|
|
1317
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value)).to.be.true;
|
|
1318
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)(assignment.value.callee)).to.be.true;
|
|
1319
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(assignment.value.callee.obj)).to.be.true;
|
|
1320
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(assignment.value.callee.obj.expression)).to.be.true;
|
|
1321
|
+
//grouping expression is an integer
|
|
1322
|
+
(0, testHelpers_spec_1.expectTypeToBe)(assignment.value.callee.obj.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), IntegerType_1.IntegerType);
|
|
1087
1323
|
});
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
const parser = parse(`
|
|
1324
|
+
it('allows type casts in a function call', () => {
|
|
1325
|
+
var _a;
|
|
1326
|
+
let { ast, diagnostics } = parse(`
|
|
1092
1327
|
sub main()
|
|
1093
|
-
|
|
1094
|
-
someString = "hello world"
|
|
1095
|
-
someObj = {foo: "bar"}
|
|
1096
|
-
someCustom = new CustomKlass()
|
|
1328
|
+
print cos(getAngle() as float)
|
|
1097
1329
|
end sub
|
|
1098
1330
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1331
|
+
function getAngle()
|
|
1332
|
+
return 123
|
|
1333
|
+
end function
|
|
1101
1334
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1335
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1336
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1337
|
+
let fn = ast.statements[0];
|
|
1338
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1339
|
+
let print = fn.func.body.statements[0];
|
|
1340
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
|
|
1341
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(print.expressions[0])).to.be.true;
|
|
1342
|
+
let fnCall = print.expressions[0];
|
|
1343
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(fnCall.args[0])).to.be.true;
|
|
1344
|
+
let arg = fnCall.args[0];
|
|
1345
|
+
//argument type is float
|
|
1346
|
+
(0, testHelpers_spec_1.expectTypeToBe)(arg.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), FloatType_1.FloatType);
|
|
1108
1347
|
});
|
|
1109
|
-
it('
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1348
|
+
it('allows multiple type casts', () => {
|
|
1349
|
+
var _a;
|
|
1350
|
+
let { ast, diagnostics } = parse(`
|
|
1351
|
+
sub main()
|
|
1352
|
+
print getData() as dynamic as float as string
|
|
1113
1353
|
end sub
|
|
1114
1354
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1355
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1356
|
+
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1357
|
+
let fn = ast.statements[0];
|
|
1358
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1359
|
+
let print = fn.func.body.statements[0];
|
|
1360
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
|
|
1361
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(print.expressions[0])).to.be.true;
|
|
1362
|
+
//argument type is float
|
|
1363
|
+
(0, testHelpers_spec_1.expectTypeToBe)(print.expressions[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), StringType_1.StringType);
|
|
1120
1364
|
});
|
|
1121
|
-
it('
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1365
|
+
it('flags invalid type cast syntax - multiple as', () => {
|
|
1366
|
+
var _a;
|
|
1367
|
+
let { diagnostics } = parse(`
|
|
1368
|
+
sub foo(key)
|
|
1369
|
+
getData(key as as string)
|
|
1125
1370
|
end sub
|
|
1126
|
-
|
|
1127
|
-
function foo() as string
|
|
1128
|
-
return "foo"
|
|
1129
|
-
end function
|
|
1130
1371
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1131
|
-
|
|
1132
|
-
const someFuncSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1133
|
-
chai_1.expect(someFuncSymbolTable.getSymbolType('temp')).to.be.instanceof(LazyType_1.LazyType);
|
|
1134
|
-
chai_1.expect(someFuncSymbolTable.getSymbolType('temp').toTypeString()).to.eq('string');
|
|
1372
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1135
1373
|
});
|
|
1136
|
-
it('
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
oldVal = count
|
|
1142
|
-
end sub
|
|
1374
|
+
it('flags invalid type cast syntax - no type after as', () => {
|
|
1375
|
+
var _a;
|
|
1376
|
+
let { diagnostics } = parse(`
|
|
1377
|
+
sub foo(key)
|
|
1378
|
+
getData(key as)
|
|
1143
1379
|
end sub
|
|
1144
1380
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1145
|
-
|
|
1146
|
-
const addOneSymbolTable = parser.references.functionExpressions[0].childFunctionExpressions[0].symbolTable;
|
|
1147
|
-
chai_1.expect(addOneSymbolTable.getSymbolType('oldVal').toString()).to.eq('uninitialized');
|
|
1381
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1148
1382
|
});
|
|
1149
|
-
it('
|
|
1150
|
-
|
|
1151
|
-
sub
|
|
1383
|
+
it('allows declaring types on assignment in Brighterscript mode', () => {
|
|
1384
|
+
let { diagnostics } = parse(`
|
|
1385
|
+
sub foo()
|
|
1386
|
+
x as string = formatJson("some string")
|
|
1152
1387
|
end sub
|
|
1153
1388
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1154
|
-
testHelpers_spec_1.expectZeroDiagnostics(
|
|
1155
|
-
testHelpers_spec_1.expectSymbolTableEquals(parser.references.functionExpressions[0].symbolTable, [
|
|
1156
|
-
['p1', new DynamicType_1.DynamicType(), util_1.default.createRange(1, 26, 1, 28)],
|
|
1157
|
-
['p2', new StringType_1.StringType(), util_1.default.createRange(1, 30, 1, 32)],
|
|
1158
|
-
['p3', new IntegerType_1.IntegerType(), util_1.default.createRange(1, 44, 1, 46)]
|
|
1159
|
-
]);
|
|
1389
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1160
1390
|
});
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
sub
|
|
1165
|
-
|
|
1166
|
-
print i
|
|
1167
|
-
end for
|
|
1391
|
+
it('does not allow declaring types on assignment in brightscript mode', () => {
|
|
1392
|
+
var _a, _b;
|
|
1393
|
+
let { diagnostics } = parse(`
|
|
1394
|
+
sub foo()
|
|
1395
|
+
x as string = formatJson("some string")
|
|
1168
1396
|
end sub
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
end for
|
|
1397
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1398
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1399
|
+
(0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.message).to.include('typed assignment');
|
|
1400
|
+
});
|
|
1401
|
+
});
|
|
1402
|
+
describe('grouped type expressions', () => {
|
|
1403
|
+
it('is not allowed in brightscript mode', () => {
|
|
1404
|
+
let parser = parse(`
|
|
1405
|
+
sub main(param as (string or integer))
|
|
1406
|
+
print param
|
|
1180
1407
|
end sub
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
}
|
|
1408
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1409
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')]);
|
|
1410
|
+
});
|
|
1411
|
+
it('allows group type expressions in parameters', () => {
|
|
1412
|
+
let { diagnostics } = parse(`
|
|
1413
|
+
sub main(param as (string or integer))
|
|
1414
|
+
print param
|
|
1415
|
+
end sub
|
|
1416
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1417
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1418
|
+
});
|
|
1419
|
+
it('allows group type expressions in type casts', () => {
|
|
1420
|
+
let { diagnostics } = parse(`
|
|
1421
|
+
sub main(val)
|
|
1422
|
+
printThing(val as (string or integer))
|
|
1423
|
+
end sub
|
|
1424
|
+
sub printThing(thing as (string or integer))
|
|
1425
|
+
print thing
|
|
1426
|
+
end sub
|
|
1427
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1428
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1429
|
+
});
|
|
1430
|
+
it('allows union of grouped type expressions', () => {
|
|
1431
|
+
let { diagnostics } = parse(`
|
|
1432
|
+
sub main(param as (string or integer) or (float or dynamic))
|
|
1433
|
+
print param
|
|
1434
|
+
end sub
|
|
1435
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1436
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1437
|
+
});
|
|
1438
|
+
it('allows nested grouped type expressions', () => {
|
|
1439
|
+
let { diagnostics } = parse(`
|
|
1440
|
+
sub main(param as ((string or integer) or (float or dynamic)))
|
|
1441
|
+
print param
|
|
1442
|
+
end sub
|
|
1443
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1444
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1445
|
+
});
|
|
1446
|
+
it('allows complicated grouped type expression', () => {
|
|
1447
|
+
let { diagnostics } = parse(`
|
|
1448
|
+
sub main(param as (({name as string} and {age as integer}) or (string and SomeInterface) or Klass and roAssociativeArray) )
|
|
1449
|
+
print param
|
|
1450
|
+
end sub
|
|
1451
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1452
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1186
1453
|
});
|
|
1187
1454
|
});
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1455
|
+
describe('union types', () => {
|
|
1456
|
+
it('is not allowed in brightscript mode', () => {
|
|
1457
|
+
let parser = parse(`
|
|
1458
|
+
sub main(param as string or integer)
|
|
1459
|
+
print param
|
|
1460
|
+
end sub
|
|
1461
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1462
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')]);
|
|
1463
|
+
});
|
|
1464
|
+
it('allows union types in parameters', () => {
|
|
1465
|
+
let { diagnostics } = parse(`
|
|
1466
|
+
sub main(param as string or integer)
|
|
1467
|
+
print param
|
|
1468
|
+
end sub
|
|
1469
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1470
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1471
|
+
});
|
|
1472
|
+
it('allows union types in type casts', () => {
|
|
1473
|
+
let { diagnostics } = parse(`
|
|
1474
|
+
sub main(val)
|
|
1475
|
+
printThing(val as string or integer)
|
|
1476
|
+
end sub
|
|
1477
|
+
sub printThing(thing as string or integer)
|
|
1478
|
+
print thing
|
|
1479
|
+
end sub
|
|
1480
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1481
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1482
|
+
});
|
|
1483
|
+
});
|
|
1484
|
+
describe('intersection types', () => {
|
|
1485
|
+
it('is not allowed in brightscript mode', () => {
|
|
1486
|
+
let parser = parse(`
|
|
1487
|
+
sub main(param as string and integer)
|
|
1488
|
+
print param
|
|
1489
|
+
end sub
|
|
1490
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1491
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')]);
|
|
1492
|
+
});
|
|
1493
|
+
it('allows intersection types in parameters', () => {
|
|
1494
|
+
let { diagnostics } = parse(`
|
|
1495
|
+
sub main(param as string and integer)
|
|
1496
|
+
print param
|
|
1497
|
+
end sub
|
|
1498
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1499
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1500
|
+
});
|
|
1501
|
+
it('allows intersection types in type casts', () => {
|
|
1502
|
+
let { diagnostics } = parse(`
|
|
1503
|
+
sub main(val)
|
|
1504
|
+
printThing(val as string and integer)
|
|
1505
|
+
end sub
|
|
1506
|
+
sub printThing(thing as string and integer)
|
|
1507
|
+
print thing
|
|
1508
|
+
end sub
|
|
1509
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1510
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1511
|
+
});
|
|
1512
|
+
it('follows order of operations with "or" first lexically', () => {
|
|
1513
|
+
let { ast, diagnostics } = parse(`
|
|
1514
|
+
sub main(param as string or integer and float)
|
|
1515
|
+
print param
|
|
1516
|
+
end sub
|
|
1517
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1518
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1519
|
+
const func = ast.statements[0].func;
|
|
1520
|
+
const paramExpr = func.parameters[0];
|
|
1521
|
+
let binExpr = paramExpr.typeExpression.expression;
|
|
1522
|
+
//first level should be 'or'
|
|
1523
|
+
(0, chai_config_spec_1.expect)(binExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.Or);
|
|
1524
|
+
//right side should be 'and'
|
|
1525
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(binExpr.right)).to.be.true;
|
|
1526
|
+
const rightAndExpr = binExpr.right;
|
|
1527
|
+
(0, chai_config_spec_1.expect)(rightAndExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.And);
|
|
1528
|
+
});
|
|
1529
|
+
it('follows order of operations with "and" first lexically', () => {
|
|
1530
|
+
let { ast, diagnostics } = parse(`
|
|
1531
|
+
sub main(param as string and integer or float)
|
|
1532
|
+
print param
|
|
1533
|
+
end sub
|
|
1534
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1535
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1536
|
+
const func = ast.statements[0].func;
|
|
1537
|
+
const paramExpr = func.parameters[0];
|
|
1538
|
+
let binExpr = paramExpr.typeExpression.expression;
|
|
1539
|
+
//first level should be 'or'
|
|
1540
|
+
(0, chai_config_spec_1.expect)(binExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.Or);
|
|
1541
|
+
//left side should be 'and'
|
|
1542
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(binExpr.left)).to.be.true;
|
|
1543
|
+
const leftAndExpr = binExpr.left;
|
|
1544
|
+
(0, chai_config_spec_1.expect)(leftAndExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.And);
|
|
1545
|
+
});
|
|
1546
|
+
it('allows grouped expression to override order of operations', () => {
|
|
1547
|
+
let { ast, diagnostics } = parse(`
|
|
1548
|
+
sub main(param as string and (integer or float))
|
|
1549
|
+
print param
|
|
1550
|
+
end sub
|
|
1551
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1552
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1553
|
+
const func = ast.statements[0].func;
|
|
1554
|
+
const paramExpr = func.parameters[0];
|
|
1555
|
+
let binExpr = paramExpr.typeExpression.expression;
|
|
1556
|
+
//first level should be 'and'
|
|
1557
|
+
(0, chai_config_spec_1.expect)(binExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.And);
|
|
1558
|
+
//right side should be 'or'
|
|
1559
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(binExpr.right)).to.be.true;
|
|
1560
|
+
const groupedExpr = binExpr.right;
|
|
1561
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(groupedExpr)).to.be.true;
|
|
1562
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeExpression)(groupedExpr.expression)).to.be.true;
|
|
1563
|
+
const rightOrExpr = groupedExpr.expression.expression;
|
|
1564
|
+
(0, chai_config_spec_1.expect)(rightOrExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.Or);
|
|
1565
|
+
});
|
|
1566
|
+
describe('invalid syntax', () => {
|
|
1567
|
+
it('flags union type with missing sides', () => {
|
|
1568
|
+
let { diagnostics } = parse(`
|
|
1569
|
+
sub main(param as Thing or )
|
|
1570
|
+
print param
|
|
1571
|
+
end sub
|
|
1572
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1573
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('or').message);
|
|
1574
|
+
});
|
|
1575
|
+
it('flags missing type inside binary type', () => {
|
|
1576
|
+
var _a;
|
|
1577
|
+
let { diagnostics } = parse(`
|
|
1578
|
+
sub main(param as string or and float)
|
|
1579
|
+
print param
|
|
1580
|
+
end sub
|
|
1581
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1582
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1583
|
+
});
|
|
1584
|
+
it('flags missing group paren', () => {
|
|
1585
|
+
var _a;
|
|
1586
|
+
let { diagnostics } = parse(`
|
|
1587
|
+
sub main(param as (string or float)
|
|
1588
|
+
print param
|
|
1589
|
+
end sub
|
|
1590
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1591
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1592
|
+
});
|
|
1593
|
+
});
|
|
1594
|
+
});
|
|
1595
|
+
describe('typed arrays', () => {
|
|
1596
|
+
it('is not allowed in brightscript mode', () => {
|
|
1597
|
+
let parser = parse(`
|
|
1598
|
+
sub main(things as string[])
|
|
1599
|
+
print things
|
|
1600
|
+
end sub
|
|
1601
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1602
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typed arrays')]);
|
|
1603
|
+
});
|
|
1604
|
+
it('is allowed in brighterscript mode', () => {
|
|
1605
|
+
let { ast, diagnostics } = parse(`
|
|
1606
|
+
sub main(things as string[])
|
|
1607
|
+
print things
|
|
1608
|
+
end sub
|
|
1609
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1610
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1611
|
+
const paramType = ast.statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1612
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1613
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, StringType_1.StringType);
|
|
1614
|
+
});
|
|
1615
|
+
it('allows multi dimensional arrays', () => {
|
|
1616
|
+
let { ast, diagnostics } = parse(`
|
|
1617
|
+
sub main(things as string[][])
|
|
1618
|
+
print things
|
|
1619
|
+
end sub
|
|
1620
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1621
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1622
|
+
const paramType = ast.statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1623
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1624
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, types_1.ArrayType);
|
|
1625
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType.defaultType, StringType_1.StringType);
|
|
1626
|
+
});
|
|
1627
|
+
it('allows arrays as return types', () => {
|
|
1628
|
+
let { ast, diagnostics } = parse(`
|
|
1629
|
+
function getFourPrimes() as integer[]
|
|
1630
|
+
return [2, 3, 5, 7]
|
|
1631
|
+
end function
|
|
1632
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1633
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1634
|
+
const paramType = ast.statements[0].func.returnTypeExpression.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1635
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1636
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, IntegerType_1.IntegerType);
|
|
1637
|
+
});
|
|
1638
|
+
it('allows arrays in union types', () => {
|
|
1639
|
+
let { ast, diagnostics } = parse(`
|
|
1640
|
+
sub foo(x as integer or integer[] or string or string[])
|
|
1641
|
+
print x
|
|
1642
|
+
end sub
|
|
1643
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1644
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1645
|
+
const paramType = ast.statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1646
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.UnionType);
|
|
1647
|
+
(0, chai_config_spec_1.expect)(paramType.toString().includes('Array<string>')).to.be.true;
|
|
1648
|
+
(0, chai_config_spec_1.expect)(paramType.toString().includes('Array<integer>')).to.be.true;
|
|
1649
|
+
});
|
|
1650
|
+
});
|
|
1651
|
+
describe('interfaces', () => {
|
|
1652
|
+
it('allows fields and methods', () => {
|
|
1653
|
+
let { ast, diagnostics } = parse(`
|
|
1654
|
+
interface SomeIFace
|
|
1655
|
+
name as string
|
|
1656
|
+
height as integer
|
|
1657
|
+
function getValue(thing as float) as object
|
|
1658
|
+
function getMe() as SomeIFace
|
|
1659
|
+
sub noop()
|
|
1660
|
+
end interface
|
|
1661
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1662
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1663
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1664
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1665
|
+
});
|
|
1666
|
+
it('allows untyped fields', () => {
|
|
1667
|
+
let { ast, diagnostics } = parse(`
|
|
1668
|
+
interface HasUntyped
|
|
1669
|
+
name
|
|
1670
|
+
end interface
|
|
1671
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1672
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1673
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1674
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1675
|
+
});
|
|
1676
|
+
it('allows optional fields', () => {
|
|
1677
|
+
let { ast, diagnostics } = parse(`
|
|
1678
|
+
interface HasOptional
|
|
1679
|
+
optional name as string
|
|
1680
|
+
optional height
|
|
1681
|
+
end interface
|
|
1682
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1683
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1684
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1685
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1686
|
+
const iface = ast.statements[0];
|
|
1687
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1688
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1689
|
+
// eslint-disable-next-line no-bitwise
|
|
1690
|
+
ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1691
|
+
});
|
|
1692
|
+
it('allows fields named optional', () => {
|
|
1693
|
+
let { ast, diagnostics } = parse(`
|
|
1694
|
+
interface IsJustOptional
|
|
1695
|
+
optional
|
|
1696
|
+
someThingElse
|
|
1697
|
+
end interface
|
|
1698
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1699
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1700
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1701
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1702
|
+
const iface = ast.statements[0];
|
|
1703
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
|
|
1704
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1705
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1706
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(2);
|
|
1707
|
+
// eslint-disable-next-line no-bitwise
|
|
1708
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(0));
|
|
1709
|
+
});
|
|
1710
|
+
it('allows fields named optional that are also optional', () => {
|
|
1711
|
+
let { ast, diagnostics } = parse(`
|
|
1712
|
+
interface IsJustOptional
|
|
1713
|
+
optional optional
|
|
1714
|
+
end interface
|
|
1715
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1716
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1717
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1718
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1719
|
+
const iface = ast.statements[0];
|
|
1720
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1721
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1722
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1723
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1724
|
+
// eslint-disable-next-line no-bitwise
|
|
1725
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1726
|
+
});
|
|
1727
|
+
it('allows optional methods', () => {
|
|
1728
|
+
let { ast, diagnostics } = parse(`
|
|
1729
|
+
interface HasOptional
|
|
1730
|
+
optional function getValue() as boolean
|
|
1731
|
+
optional sub noop()
|
|
1732
|
+
optional function process()
|
|
1733
|
+
end interface
|
|
1734
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1735
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1736
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1737
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1738
|
+
const iface = ast.statements[0];
|
|
1739
|
+
iface.methods.forEach(m => (0, chai_config_spec_1.expect)(m.isOptional).to.equal(true));
|
|
1740
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1741
|
+
// eslint-disable-next-line no-bitwise
|
|
1742
|
+
ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1743
|
+
});
|
|
1744
|
+
it('allows fields named `as` that are also optional', () => {
|
|
1745
|
+
let { ast, diagnostics } = parse(`
|
|
1746
|
+
interface IsJustOptional
|
|
1747
|
+
optional as
|
|
1748
|
+
end interface
|
|
1749
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1750
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1751
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1752
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1753
|
+
const iface = ast.statements[0];
|
|
1754
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1755
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1756
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1757
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1758
|
+
// eslint-disable-next-line no-bitwise
|
|
1759
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1760
|
+
});
|
|
1761
|
+
it('allows fields named `as` that are also typed', () => {
|
|
1762
|
+
let { ast, diagnostics } = parse(`
|
|
1763
|
+
interface IsJustOptional
|
|
1764
|
+
optional as as string
|
|
1765
|
+
end interface
|
|
1766
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1767
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1768
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1769
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1770
|
+
const iface = ast.statements[0];
|
|
1771
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1772
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1773
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1774
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1775
|
+
// eslint-disable-next-line no-bitwise
|
|
1776
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1777
|
+
});
|
|
1778
|
+
it('allows fields named `optional` that are also typed', () => {
|
|
1779
|
+
let { ast, diagnostics } = parse(`
|
|
1780
|
+
interface IsJustOptional
|
|
1781
|
+
optional as string
|
|
1782
|
+
end interface
|
|
1783
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1784
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1785
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1786
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1787
|
+
const iface = ast.statements[0];
|
|
1788
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
|
|
1789
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1790
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1791
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1792
|
+
// eslint-disable-next-line no-bitwise
|
|
1793
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(0));
|
|
1794
|
+
});
|
|
1795
|
+
});
|
|
1796
|
+
describe('leadingTrivia', () => {
|
|
1797
|
+
it('gets leading trivia from functions', () => {
|
|
1798
|
+
let { ast } = parse(`
|
|
1799
|
+
' Nice function, bro
|
|
1800
|
+
function foo()
|
|
1801
|
+
return 1
|
|
1802
|
+
end function
|
|
1803
|
+
`);
|
|
1804
|
+
const funcStatements = ast.statements.filter(reflection_1.isFunctionStatement);
|
|
1805
|
+
const fooTrivia = funcStatements[0].leadingTrivia;
|
|
1806
|
+
(0, chai_config_spec_1.expect)(fooTrivia.length).to.be.greaterThan(0);
|
|
1807
|
+
(0, chai_config_spec_1.expect)(fooTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1808
|
+
});
|
|
1809
|
+
it('gets multiple lines of leading trivia', () => {
|
|
1810
|
+
let { ast, diagnostics } = parse(`
|
|
1811
|
+
' Say hello to someone
|
|
1812
|
+
'
|
|
1813
|
+
' @param {string} name the person you want to say hello to.
|
|
1814
|
+
sub sayHello(name = "world" as string)
|
|
1815
|
+
end sub
|
|
1816
|
+
`);
|
|
1817
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1818
|
+
const funcStatements = ast.statements.filter(reflection_1.isFunctionStatement);
|
|
1819
|
+
const helloTrivia = funcStatements[0].leadingTrivia;
|
|
1820
|
+
(0, chai_config_spec_1.expect)(helloTrivia.length).to.be.greaterThan(0);
|
|
1821
|
+
(0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(3);
|
|
1822
|
+
});
|
|
1823
|
+
it('gets leading trivia from classes', () => {
|
|
1824
|
+
let { ast } = parse(`
|
|
1825
|
+
' hello
|
|
1826
|
+
' classes
|
|
1827
|
+
class Hello
|
|
1828
|
+
end class
|
|
1829
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1830
|
+
const classStatements = ast.statements.filter(reflection_1.isClassStatement);
|
|
1831
|
+
const trivia = classStatements[0].leadingTrivia;
|
|
1832
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1833
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1834
|
+
});
|
|
1835
|
+
it('gets leading trivia from functions with annotations', () => {
|
|
1836
|
+
let { ast } = parse(`
|
|
1837
|
+
' hello comment 1
|
|
1838
|
+
' hello comment 2
|
|
1839
|
+
@annotation
|
|
1840
|
+
' hello comment 3
|
|
1841
|
+
@otherAnnotation
|
|
1842
|
+
sub sayHello(name = "world" as string)
|
|
1843
|
+
end sub
|
|
1844
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1845
|
+
const funcStatements = ast.statements.filter(reflection_1.isFunctionStatement);
|
|
1846
|
+
const helloTrivia = funcStatements[0].leadingTrivia;
|
|
1847
|
+
(0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(0);
|
|
1848
|
+
const helloAnnotationTrivia = funcStatements[0].annotations[0].leadingTrivia;
|
|
1849
|
+
(0, chai_config_spec_1.expect)(helloAnnotationTrivia.length).to.be.greaterThan(0);
|
|
1850
|
+
(0, chai_config_spec_1.expect)(helloAnnotationTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1851
|
+
const otherAnnotationTrivia = funcStatements[0].annotations[1].leadingTrivia;
|
|
1852
|
+
(0, chai_config_spec_1.expect)(otherAnnotationTrivia.length).to.be.greaterThan(0);
|
|
1853
|
+
(0, chai_config_spec_1.expect)(otherAnnotationTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1854
|
+
});
|
|
1855
|
+
it('gets leading trivia from class methods', () => {
|
|
1856
|
+
let { ast } = parse(`
|
|
1857
|
+
' hello
|
|
1858
|
+
' classes
|
|
1859
|
+
class Hello
|
|
1860
|
+
|
|
1861
|
+
' Gets the value of PI
|
|
1862
|
+
' Not a dessert
|
|
1863
|
+
function getPi() as float
|
|
1864
|
+
return 3.14
|
|
1865
|
+
end function
|
|
1866
|
+
|
|
1867
|
+
' Gets a dessert
|
|
1868
|
+
function getPie() as string
|
|
1869
|
+
return "Apple Pie"
|
|
1870
|
+
end function
|
|
1871
|
+
end class
|
|
1872
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1873
|
+
const classStatement = ast.statements.filter(reflection_1.isClassStatement)[0];
|
|
1874
|
+
const methodStatements = classStatement.methods;
|
|
1875
|
+
// function getPi()
|
|
1876
|
+
let trivia = methodStatements[0].leadingTrivia;
|
|
1877
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1878
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1879
|
+
// function getPie()
|
|
1880
|
+
trivia = methodStatements[1].leadingTrivia;
|
|
1881
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1882
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1883
|
+
});
|
|
1884
|
+
it('gets leading trivia from class fields', () => {
|
|
1885
|
+
let { ast } = parse(`
|
|
1886
|
+
' hello
|
|
1887
|
+
' classes
|
|
1888
|
+
class Thing
|
|
1889
|
+
' like the sky
|
|
1890
|
+
' or a blueberry, evn though that's purple
|
|
1891
|
+
color = "blue"
|
|
1892
|
+
|
|
1893
|
+
' My name
|
|
1894
|
+
public name as string
|
|
1895
|
+
|
|
1896
|
+
' Only I know how old I am
|
|
1897
|
+
private age = 42
|
|
1898
|
+
end class
|
|
1899
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1900
|
+
const classStatement = ast.statements.filter(reflection_1.isClassStatement)[0];
|
|
1901
|
+
const fieldStatements = classStatement.fields;
|
|
1902
|
+
// color = "blue"
|
|
1903
|
+
let trivia = fieldStatements[0].leadingTrivia;
|
|
1904
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1905
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1906
|
+
// public name as string
|
|
1907
|
+
trivia = fieldStatements[1].leadingTrivia;
|
|
1908
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1909
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1910
|
+
// private age = 42
|
|
1911
|
+
trivia = fieldStatements[2].leadingTrivia;
|
|
1912
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1913
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1914
|
+
});
|
|
1915
|
+
it('gets leading trivia from interfaces', () => {
|
|
1916
|
+
let { ast } = parse(`
|
|
1917
|
+
' Description of interface
|
|
1918
|
+
interface myIface
|
|
1919
|
+
' comment
|
|
1920
|
+
someField as integer
|
|
1921
|
+
|
|
1922
|
+
'comment
|
|
1923
|
+
function someFunc() as string
|
|
1924
|
+
end interface
|
|
1925
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1926
|
+
const ifaceStatement = ast.statements.filter(reflection_1.isInterfaceStatement)[0];
|
|
1927
|
+
const fieldStatements = ifaceStatement.fields;
|
|
1928
|
+
const methodStatements = ifaceStatement.methods;
|
|
1929
|
+
// interface myIface
|
|
1930
|
+
let trivia = ifaceStatement.leadingTrivia;
|
|
1931
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1932
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1933
|
+
// someField as integer
|
|
1934
|
+
trivia = fieldStatements[0].leadingTrivia;
|
|
1935
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1936
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1937
|
+
// function someFunc() as string
|
|
1938
|
+
trivia = methodStatements[0].leadingTrivia;
|
|
1939
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1940
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1941
|
+
});
|
|
1942
|
+
it('gets leading trivia from namespaces', () => {
|
|
1943
|
+
let { ast } = parse(`
|
|
1944
|
+
' Description of interface
|
|
1945
|
+
namespace Nested.Name.Space
|
|
1946
|
+
|
|
1947
|
+
end namespace
|
|
1948
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1949
|
+
const nameSpaceStatement = ast.statements.filter(reflection_1.isNamespaceStatement)[0];
|
|
1950
|
+
// namespace Nested.Name.Space
|
|
1951
|
+
let trivia = nameSpaceStatement.leadingTrivia;
|
|
1952
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1953
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1954
|
+
});
|
|
1955
|
+
});
|
|
1956
|
+
describe('unary/binary ordering', () => {
|
|
1957
|
+
it('creates the correct operator order for `not x = x` code', () => {
|
|
1958
|
+
let { ast, diagnostics } = parse(`
|
|
1959
|
+
function isStrNotEmpty(myStr as string) as boolean
|
|
1960
|
+
return not myStr = ""
|
|
1961
|
+
end function
|
|
1962
|
+
`);
|
|
1963
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1964
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
1965
|
+
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
1966
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1967
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
|
|
1968
|
+
});
|
|
1969
|
+
it('creates the correct operator order for `not x + x` code', () => {
|
|
1970
|
+
let { ast, diagnostics } = parse(`
|
|
1971
|
+
function tryStuff() as integer
|
|
1972
|
+
return not 1 + 3 ' same as "not (3)" ... eg. the "flipped bits" of 3 (0000 0011) -> 1111 1100, or -4
|
|
1973
|
+
end function
|
|
1974
|
+
`);
|
|
1975
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1976
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
1977
|
+
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
1978
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1979
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
|
|
1980
|
+
});
|
|
1981
|
+
it('creates the correct operator order for `x = not x` code', () => {
|
|
1982
|
+
let { ast, diagnostics } = parse(`
|
|
1983
|
+
function tryStuff() as boolean
|
|
1984
|
+
return 4 = not -5 ' same as "4 = 4"
|
|
1985
|
+
end function
|
|
1986
|
+
`);
|
|
1987
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1988
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
1989
|
+
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
1990
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn)).to.be.true;
|
|
1991
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(insideReturn.left)).to.be.true;
|
|
1992
|
+
const right = insideReturn.right;
|
|
1993
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right)).to.be.true;
|
|
1994
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right.right)).to.be.true; // not ( - ( 5))
|
|
1995
|
+
});
|
|
1996
|
+
it('allows multiple nots', () => {
|
|
1997
|
+
let { ast, diagnostics } = parse(`
|
|
1998
|
+
function tryStuff() as integer
|
|
1999
|
+
return not not not 4
|
|
2000
|
+
end function
|
|
2001
|
+
`);
|
|
2002
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2003
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
2004
|
+
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
2005
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
2006
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
|
|
2007
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
|
|
2008
|
+
});
|
|
2009
|
+
it('allows multiple -', () => {
|
|
2010
|
+
let { ast, diagnostics } = parse(`
|
|
2011
|
+
function tryStuff() as integer
|
|
2012
|
+
return - - - 4
|
|
2013
|
+
end function
|
|
2014
|
+
`);
|
|
2015
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2016
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
2017
|
+
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
2018
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
2019
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
|
|
2020
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
|
|
2021
|
+
});
|
|
2022
|
+
});
|
|
2023
|
+
describe('typecast statement', () => {
|
|
2024
|
+
it('allows typecast statement ', () => {
|
|
2025
|
+
let { ast, diagnostics } = parse(`
|
|
2026
|
+
typeCAST m AS roAssociativeArray
|
|
2027
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2028
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2029
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastStatement)(ast.statements[0])).to.be.true;
|
|
2030
|
+
const stmt = ast.statements[0];
|
|
2031
|
+
(0, chai_config_spec_1.expect)(stmt.tokens.typecast.text).to.eq('typeCAST');
|
|
2032
|
+
(0, chai_config_spec_1.expect)(stmt.typecastExpression).to.exist;
|
|
2033
|
+
});
|
|
2034
|
+
it('is disallowed in brightscript mode', () => {
|
|
2035
|
+
let { diagnostics } = parse(`
|
|
2036
|
+
typecast m AS roAssociativeArray
|
|
2037
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2038
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2039
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typecast statements')
|
|
2040
|
+
]);
|
|
2041
|
+
});
|
|
2042
|
+
it('allows `typecast` for function name', () => {
|
|
2043
|
+
let { ast, diagnostics } = parse(`
|
|
2044
|
+
function typecast() as integer
|
|
2045
|
+
return 1
|
|
2046
|
+
end function
|
|
2047
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2048
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2049
|
+
(0, chai_config_spec_1.expect)(ast.statements[0].tokens.name.text).to.eq('typecast');
|
|
2050
|
+
});
|
|
2051
|
+
it('allows `typecast` for variable name', () => {
|
|
2052
|
+
let { ast, diagnostics } = parse(`
|
|
2053
|
+
function foo() as integer
|
|
2054
|
+
typecast = 1
|
|
2055
|
+
return typecast
|
|
2056
|
+
end function
|
|
2057
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2058
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2059
|
+
(0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].tokens.name.text).to.eq('typecast');
|
|
2060
|
+
});
|
|
2061
|
+
it('is allowed in function', () => {
|
|
2062
|
+
let { diagnostics } = parse(`
|
|
2063
|
+
function foo() as integer
|
|
2064
|
+
typecast m as MyObject
|
|
2065
|
+
return m.getNum()
|
|
2066
|
+
end function
|
|
2067
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2068
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2069
|
+
});
|
|
2070
|
+
it('is allowed in function literal', () => {
|
|
2071
|
+
let { diagnostics } = parse(`
|
|
2072
|
+
interface PiGetter
|
|
2073
|
+
pi as float
|
|
2074
|
+
function getPi() as float
|
|
2075
|
+
end interface
|
|
2076
|
+
|
|
2077
|
+
function makePiGetter() as object
|
|
2078
|
+
x = {
|
|
2079
|
+
pi: 3.14,
|
|
2080
|
+
getPi: function() as float
|
|
2081
|
+
typecast m as PiGetter
|
|
2082
|
+
return m.pi
|
|
2083
|
+
end function
|
|
2084
|
+
}
|
|
2085
|
+
return x
|
|
2086
|
+
end function
|
|
2087
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2088
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2089
|
+
});
|
|
2090
|
+
});
|
|
2091
|
+
describe('conditional compilation', () => {
|
|
2092
|
+
it('contains code from conditional compile blocks', () => {
|
|
2093
|
+
let { ast, diagnostics } = parse(`
|
|
2094
|
+
sub foo()
|
|
2095
|
+
#if DEBUG
|
|
2096
|
+
print "hello"
|
|
2097
|
+
#end if
|
|
2098
|
+
end sub
|
|
2099
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: true });
|
|
2100
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2101
|
+
const funcBlock = ast.statements[0].func.body;
|
|
2102
|
+
(0, chai_config_spec_1.expect)(funcBlock.statements.length).to.eq(1);
|
|
2103
|
+
const ccStmt = funcBlock.statements[0];
|
|
2104
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2105
|
+
const printStmt = ccStmt.thenBranch.statements[0];
|
|
2106
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
|
|
2107
|
+
});
|
|
2108
|
+
it('contains code from conditional compile else blocks', () => {
|
|
2109
|
+
let { ast, diagnostics } = parse(`
|
|
2110
|
+
sub foo()
|
|
2111
|
+
#if DEBUG
|
|
2112
|
+
m.pi = 3.14
|
|
2113
|
+
#else
|
|
2114
|
+
print "hello"
|
|
2115
|
+
#end if
|
|
2116
|
+
end sub
|
|
2117
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2118
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2119
|
+
const funcBlock = ast.statements[0].func.body;
|
|
2120
|
+
const ccStmt = funcBlock.statements[0];
|
|
2121
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2122
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
|
|
2123
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBlock)(ccStmt.elseBranch)).to.true;
|
|
2124
|
+
const printStmt = ccStmt.elseBranch.statements[0];
|
|
2125
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
|
|
2126
|
+
});
|
|
2127
|
+
it('contains code from conditional compile else if blocks', () => {
|
|
2128
|
+
let { ast, diagnostics } = parse(`
|
|
2129
|
+
sub foo()
|
|
2130
|
+
#if DEBUG
|
|
2131
|
+
m.pi = 3.14
|
|
2132
|
+
#else if PROD
|
|
2133
|
+
print "hello"
|
|
2134
|
+
#end if
|
|
2135
|
+
end sub
|
|
2136
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2137
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2138
|
+
const funcBlock = ast.statements[0].func.body;
|
|
2139
|
+
const ccStmt = funcBlock.statements[0];
|
|
2140
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2141
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
|
|
2142
|
+
const elseBranch = ccStmt.elseBranch;
|
|
2143
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2144
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('PROD');
|
|
2145
|
+
const printStmt = elseBranch.thenBranch.statements[0];
|
|
2146
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
|
|
2147
|
+
});
|
|
2148
|
+
it('contains code from multiple conditional compile else if blocks', () => {
|
|
2149
|
+
let { ast, diagnostics } = parse(`
|
|
2150
|
+
sub foo()
|
|
2151
|
+
#if DEBUG
|
|
2152
|
+
m.pi = 3.14
|
|
2153
|
+
#else if PROD
|
|
2154
|
+
print "hello"
|
|
2155
|
+
#else if ABC
|
|
2156
|
+
print "hello"
|
|
2157
|
+
#else if DEF
|
|
2158
|
+
print "hello"
|
|
2159
|
+
#else if HIJ
|
|
2160
|
+
print "hello"
|
|
2161
|
+
#else
|
|
2162
|
+
x = 78
|
|
2163
|
+
#end if
|
|
2164
|
+
end sub
|
|
2165
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2166
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2167
|
+
const funcBlock = ast.statements[0].func.body;
|
|
2168
|
+
const ccStmt = funcBlock.statements[0];
|
|
2169
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2170
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
|
|
2171
|
+
let elseBranch = ccStmt.elseBranch;
|
|
2172
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2173
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('PROD');
|
|
2174
|
+
elseBranch = elseBranch.elseBranch;
|
|
2175
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2176
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('ABC');
|
|
2177
|
+
elseBranch = elseBranch.elseBranch;
|
|
2178
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2179
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('DEF');
|
|
2180
|
+
elseBranch = elseBranch.elseBranch;
|
|
2181
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2182
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('HIJ');
|
|
2183
|
+
let lastElse = elseBranch.elseBranch;
|
|
2184
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBlock)(lastElse)).to.true;
|
|
2185
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(lastElse.statements[0])).to.true;
|
|
2186
|
+
});
|
|
2187
|
+
it('allows empty conditional compilation blocks', () => {
|
|
2188
|
+
let { ast, diagnostics } = parse(`
|
|
2189
|
+
#if DEBUG
|
|
2190
|
+
#else if PROD
|
|
2191
|
+
#else
|
|
2192
|
+
#end if
|
|
2193
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2194
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2195
|
+
const ccStmt = ast.statements[0];
|
|
2196
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2197
|
+
(0, chai_config_spec_1.expect)(ccStmt.thenBranch.statements.length).to.eq(0);
|
|
2198
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.thenBranch.statements.length).to.eq(0);
|
|
2199
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.elseBranch.statements.length).to.eq(0);
|
|
2200
|
+
});
|
|
2201
|
+
it('allows only comments in compilation blocks', () => {
|
|
2202
|
+
let { ast, diagnostics } = parse(`
|
|
2203
|
+
' before if
|
|
2204
|
+
#if DEBUG
|
|
2205
|
+
' this is debug
|
|
2206
|
+
#else if PROD
|
|
2207
|
+
' this is prod
|
|
2208
|
+
#else
|
|
2209
|
+
' this is neither
|
|
2210
|
+
#end if
|
|
2211
|
+
' after if
|
|
2212
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2213
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2214
|
+
const ccStmt = ast.statements[0];
|
|
2215
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2216
|
+
(0, chai_config_spec_1.expect)(ccStmt.thenBranch.statements.length).to.eq(0);
|
|
2217
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.thenBranch.statements.length).to.eq(0);
|
|
2218
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.elseBranch.statements.length).to.eq(0);
|
|
2219
|
+
});
|
|
2220
|
+
it('has no error when safely closing block', () => {
|
|
2221
|
+
let { diagnostics } = parse(`
|
|
2222
|
+
sub foo()
|
|
2223
|
+
#if DEBUG
|
|
2224
|
+
if m.enabled
|
|
2225
|
+
print "hello"
|
|
2226
|
+
end if
|
|
2227
|
+
#end if
|
|
2228
|
+
end sub
|
|
2229
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2230
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2231
|
+
});
|
|
2232
|
+
it('has error when unsafely closing block', () => {
|
|
2233
|
+
let { diagnostics } = parse(`
|
|
2234
|
+
sub foo()
|
|
2235
|
+
if m.enabled
|
|
2236
|
+
#if DEBUG
|
|
2237
|
+
print "hello"
|
|
2238
|
+
end if
|
|
2239
|
+
#end if
|
|
2240
|
+
end sub
|
|
2241
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2242
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2243
|
+
DiagnosticMessages_1.DiagnosticMessages.unsafeUnmatchedTerminatorInConditionalCompileBlock('end if').message
|
|
2244
|
+
]);
|
|
2245
|
+
});
|
|
2246
|
+
it('has error when unsafely opening block', () => {
|
|
2247
|
+
let { diagnostics } = parse(`
|
|
2248
|
+
sub foo()
|
|
2249
|
+
#if DEBUG
|
|
2250
|
+
if m.enabled
|
|
2251
|
+
print "hello"
|
|
2252
|
+
#end if
|
|
2253
|
+
end if
|
|
2254
|
+
end sub
|
|
2255
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: true });
|
|
2256
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2257
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedTerminator('end if', 'if').message,
|
|
2258
|
+
DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('end if').message
|
|
2259
|
+
]);
|
|
2260
|
+
});
|
|
2261
|
+
it('has no diagnostics from false blocks', () => {
|
|
2262
|
+
let { diagnostics } = parse(`
|
|
2263
|
+
sub foo()
|
|
2264
|
+
#if DEBUG
|
|
2265
|
+
blah blah blah
|
|
2266
|
+
#end if
|
|
2267
|
+
|
|
2268
|
+
#if false
|
|
2269
|
+
there are no diagnostics here
|
|
2270
|
+
#end if
|
|
2271
|
+
end sub
|
|
2272
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: false });
|
|
2273
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2274
|
+
});
|
|
2275
|
+
it('allows #if not bs_const', () => {
|
|
2276
|
+
let { diagnostics } = parse(`
|
|
2277
|
+
sub foo()
|
|
2278
|
+
#if not DEBUG
|
|
2279
|
+
print "not debug"
|
|
2280
|
+
#end if
|
|
2281
|
+
end sub
|
|
2282
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: false });
|
|
2283
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2284
|
+
});
|
|
2285
|
+
it('allows #elseif not bs_const', () => {
|
|
2286
|
+
let { diagnostics } = parse(`
|
|
2287
|
+
sub foo()
|
|
2288
|
+
#if DEBUG
|
|
2289
|
+
print "debug"
|
|
2290
|
+
#else if not STAGING
|
|
2291
|
+
print "not debug and not staging"
|
|
2292
|
+
#end if
|
|
2293
|
+
end sub
|
|
2294
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: false, staging: false });
|
|
2295
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2296
|
+
});
|
|
2297
|
+
describe('#const', () => {
|
|
2298
|
+
it('parses #const', () => {
|
|
2299
|
+
let { ast, diagnostics } = parse(`
|
|
2300
|
+
#const test = true
|
|
2301
|
+
sub foo()
|
|
2302
|
+
#const debug = test
|
|
2303
|
+
end sub
|
|
2304
|
+
# const spaces = false
|
|
2305
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2306
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2307
|
+
//#const test = true
|
|
2308
|
+
let ccc = ast.statements[0];
|
|
2309
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
|
|
2310
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('test');
|
|
2311
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(ccc.assignment.value)).to.be.true;
|
|
2312
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.value.text).to.eq('true');
|
|
2313
|
+
//#const debug = test
|
|
2314
|
+
ccc = ast.statements[1].func.body.statements[0];
|
|
2315
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
|
|
2316
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('debug');
|
|
2317
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)(ccc.assignment.value)).to.be.true;
|
|
2318
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.name.text).to.eq('test');
|
|
2319
|
+
//# const spaces = false
|
|
2320
|
+
ccc = ast.statements[2];
|
|
2321
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
|
|
2322
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('spaces');
|
|
2323
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(ccc.assignment.value)).to.be.true;
|
|
2324
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.value.text).to.eq('false');
|
|
2325
|
+
});
|
|
2326
|
+
it('has diagnostic if no lhs', () => {
|
|
2327
|
+
let { diagnostics } = parse(`
|
|
2328
|
+
#const test
|
|
2329
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2330
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2331
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedOperator([TokenKind_1.TokenKind.Equal], 'test').message
|
|
2332
|
+
]);
|
|
2333
|
+
});
|
|
2334
|
+
it('has diagnostic if invalid operator', () => {
|
|
2335
|
+
let { diagnostics } = parse(`
|
|
2336
|
+
#const test += other
|
|
2337
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2338
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2339
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedOperator([TokenKind_1.TokenKind.Equal], 'test').message
|
|
2340
|
+
]);
|
|
2341
|
+
});
|
|
2342
|
+
it('has diagnostic if invalid lhs', () => {
|
|
2343
|
+
let { diagnostics } = parse(`
|
|
2344
|
+
#const test = 4
|
|
2345
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2346
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2347
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidHashConstValue().message
|
|
2348
|
+
]);
|
|
2349
|
+
});
|
|
2350
|
+
});
|
|
2351
|
+
describe('#error', () => {
|
|
2352
|
+
it('parses #error', () => {
|
|
2353
|
+
let { ast, diagnostics } = parse(`
|
|
2354
|
+
#error
|
|
2355
|
+
sub foo()
|
|
2356
|
+
#error this is a LONG "message" :: with colons, etc.
|
|
2357
|
+
end sub
|
|
2358
|
+
# error this one has spaces
|
|
2359
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2360
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2361
|
+
//#error
|
|
2362
|
+
let cce = ast.statements[0];
|
|
2363
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
|
|
2364
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
|
|
2365
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('');
|
|
2366
|
+
//#error this is a long "message" :: with colons, etc.
|
|
2367
|
+
cce = ast.statements[1].func.body.statements[0];
|
|
2368
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
|
|
2369
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
|
|
2370
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('this is a LONG "message" :: with colons, etc.');
|
|
2371
|
+
//# error this one has spaces
|
|
2372
|
+
cce = ast.statements[2];
|
|
2373
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
|
|
2374
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
|
|
2375
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('this one has spaces');
|
|
2376
|
+
});
|
|
2377
|
+
});
|
|
2378
|
+
});
|
|
2379
|
+
describe('alias statement', () => {
|
|
2380
|
+
it('allows alias statement ', () => {
|
|
2381
|
+
let { ast, diagnostics } = parse(`
|
|
2382
|
+
ALIAS x = lcase
|
|
2383
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2384
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2385
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAliasStatement)(ast.statements[0])).to.be.true;
|
|
2386
|
+
const stmt = ast.statements[0];
|
|
2387
|
+
(0, chai_config_spec_1.expect)(stmt.tokens.alias.text).to.eq('ALIAS');
|
|
2388
|
+
(0, chai_config_spec_1.expect)(stmt.value).to.exist;
|
|
2389
|
+
});
|
|
2390
|
+
it('is disallowed in brightscript mode', () => {
|
|
2391
|
+
let { diagnostics } = parse(`
|
|
2392
|
+
alias x = lcase
|
|
2393
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2394
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2395
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('alias statements')
|
|
2396
|
+
]);
|
|
2397
|
+
});
|
|
2398
|
+
it('allows `alias` for function name', () => {
|
|
2399
|
+
let { ast, diagnostics } = parse(`
|
|
2400
|
+
function alias() as integer
|
|
2401
|
+
return 1
|
|
2402
|
+
end function
|
|
2403
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2404
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2405
|
+
(0, chai_config_spec_1.expect)(ast.statements[0].tokens.name.text).to.eq('alias');
|
|
2406
|
+
});
|
|
2407
|
+
it('allows `alias` for variable name', () => {
|
|
2408
|
+
let { ast, diagnostics } = parse(`
|
|
2409
|
+
function foo() as integer
|
|
2410
|
+
alias = 1
|
|
2411
|
+
return alias
|
|
2412
|
+
end function
|
|
2413
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2414
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2415
|
+
(0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].tokens.name.text).to.eq('alias');
|
|
2416
|
+
});
|
|
2417
|
+
});
|
|
2418
|
+
describe('type statement', () => {
|
|
2419
|
+
it('allows type statement ', () => {
|
|
2420
|
+
let { ast, diagnostics } = parse(`
|
|
2421
|
+
TYPE x = string
|
|
2422
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2423
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2424
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
|
|
2425
|
+
const stmt = ast.statements[0];
|
|
2426
|
+
(0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('TYPE');
|
|
2427
|
+
(0, chai_config_spec_1.expect)(stmt.value).to.exist;
|
|
2428
|
+
});
|
|
2429
|
+
it('is disallowed in brightscript mode', () => {
|
|
2430
|
+
let { diagnostics } = parse(`
|
|
2431
|
+
type x = string
|
|
2432
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2433
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2434
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('type statements')
|
|
2435
|
+
]);
|
|
2436
|
+
});
|
|
2437
|
+
it('disallows `type` for function name', () => {
|
|
2438
|
+
let { diagnostics } = parse(`
|
|
2439
|
+
function type() as integer
|
|
2440
|
+
return 1
|
|
2441
|
+
end function
|
|
2442
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2443
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2444
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier('type').message
|
|
2445
|
+
]);
|
|
2446
|
+
});
|
|
2447
|
+
it('disallows `type` for variable name', () => {
|
|
2448
|
+
let { diagnostics } = parse(`
|
|
2449
|
+
function foo() as integer
|
|
2450
|
+
type = 1
|
|
2451
|
+
return type
|
|
2452
|
+
end function
|
|
2453
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2454
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2455
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier('type').message
|
|
2456
|
+
]);
|
|
2457
|
+
});
|
|
2458
|
+
it('has error when rhs is not a type', () => {
|
|
2459
|
+
let { diagnostics } = parse(`
|
|
2460
|
+
type x = 123
|
|
2461
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2462
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2463
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('=').message
|
|
2464
|
+
]);
|
|
2465
|
+
});
|
|
2466
|
+
it('allows type statement with complicated type', () => {
|
|
2467
|
+
let { ast, diagnostics } = parse(`
|
|
2468
|
+
type x = string or CustomKlass or roAssociativeArray
|
|
2469
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2470
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2471
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
|
|
2472
|
+
const stmt = ast.statements[0];
|
|
2473
|
+
(0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('type');
|
|
2474
|
+
(0, chai_config_spec_1.expect)(stmt.value).to.exist;
|
|
2475
|
+
});
|
|
2476
|
+
it('allows grouped expressions in type statement', () => {
|
|
2477
|
+
let { ast, diagnostics } = parse(`
|
|
2478
|
+
type guy = ({name as string} or {age as integer}) and {foo as boolean, age as integer}
|
|
2479
|
+
|
|
2480
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2481
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2482
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
|
|
2483
|
+
const stmt = ast.statements[0];
|
|
2484
|
+
(0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('type');
|
|
2485
|
+
(0, chai_config_spec_1.expect)(stmt.value).to.exist;
|
|
2486
|
+
});
|
|
2487
|
+
});
|
|
2488
|
+
describe('jump statements', () => {
|
|
2489
|
+
it('should recognize `exit for`', () => {
|
|
2490
|
+
let { ast, diagnostics } = parse(`
|
|
2491
|
+
sub main()
|
|
2492
|
+
for i = 1 to 10
|
|
2493
|
+
exit for
|
|
2494
|
+
end for
|
|
2495
|
+
end sub
|
|
2496
|
+
`);
|
|
2497
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2498
|
+
let loop = ast.statements[0].func.body.statements[0];
|
|
2499
|
+
let exitStmt = loop.body.statements[0];
|
|
2500
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
|
|
2501
|
+
(0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('for');
|
|
2502
|
+
});
|
|
2503
|
+
it('should recognize `exit while`', () => {
|
|
2504
|
+
let { ast, diagnostics } = parse(`
|
|
2505
|
+
sub main(i)
|
|
2506
|
+
while i < 10
|
|
2507
|
+
exit while
|
|
2508
|
+
i++
|
|
2509
|
+
end while
|
|
2510
|
+
end sub
|
|
2511
|
+
`);
|
|
2512
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2513
|
+
let loop = ast.statements[0].func.body.statements[0];
|
|
2514
|
+
let exitStmt = loop.body.statements[0];
|
|
2515
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
|
|
2516
|
+
(0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('while');
|
|
2517
|
+
});
|
|
2518
|
+
it('should recognize `exitwhile` (one word)', () => {
|
|
2519
|
+
let { ast, diagnostics } = parse(`
|
|
2520
|
+
sub main(i)
|
|
2521
|
+
while i < 10
|
|
2522
|
+
exitwhile
|
|
2523
|
+
i++
|
|
2524
|
+
end while
|
|
2525
|
+
end sub
|
|
2526
|
+
`);
|
|
2527
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2528
|
+
let loop = ast.statements[0].func.body.statements[0];
|
|
2529
|
+
let exitStmt = loop.body.statements[0];
|
|
2530
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
|
|
2531
|
+
(0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('while');
|
|
2532
|
+
});
|
|
2533
|
+
it('should allow identifiers named `exitfor` (one word)', () => {
|
|
2534
|
+
let { ast, diagnostics } = parse(`
|
|
2535
|
+
sub main()
|
|
2536
|
+
for i = 1 to 10
|
|
2537
|
+
exitfor = 1
|
|
2538
|
+
exit for
|
|
2539
|
+
end for
|
|
2540
|
+
end sub
|
|
2541
|
+
`);
|
|
2542
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2543
|
+
let loop = ast.statements[0].func.body.statements[0];
|
|
2544
|
+
let assignment = loop.body.statements[0];
|
|
2545
|
+
(0, chai_config_spec_1.expect)(assignment.tokens.name.text).to.eq('exitfor');
|
|
2546
|
+
let exitStmt = loop.body.statements[1];
|
|
2547
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
|
|
2548
|
+
(0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('for');
|
|
2549
|
+
});
|
|
2550
|
+
});
|
|
2551
|
+
describe('custom types', () => {
|
|
2552
|
+
it('built-in interface param types disallowed in brightscript mode', () => {
|
|
2553
|
+
let { diagnostics } = parse(`
|
|
2554
|
+
sub test(foo as roAssociativeArray)
|
|
2555
|
+
print foo.x
|
|
2556
|
+
end sub
|
|
2557
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2558
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2559
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2560
|
+
]);
|
|
2561
|
+
});
|
|
2562
|
+
it('built-in interface types disallowed in brightscript mode', () => {
|
|
2563
|
+
let { diagnostics } = parse(`
|
|
2564
|
+
function test(foo) as roAssociativeArray
|
|
2565
|
+
return foo.x
|
|
2566
|
+
end function
|
|
2567
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2568
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2569
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2570
|
+
]);
|
|
2571
|
+
});
|
|
2572
|
+
it('custom param types disallowed in brightscript mode', () => {
|
|
2573
|
+
let { diagnostics } = parse(`
|
|
2574
|
+
sub test(foo as Whatever)
|
|
2575
|
+
print foo.x
|
|
2576
|
+
end sub
|
|
2577
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2578
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2579
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2580
|
+
]);
|
|
2581
|
+
});
|
|
2582
|
+
it('custom return types disallowed in brightscript mode', () => {
|
|
2583
|
+
let { diagnostics } = parse(`
|
|
2584
|
+
function test(foo) as Whatever
|
|
2585
|
+
return foo.x
|
|
2586
|
+
end function
|
|
2587
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2588
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2589
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2590
|
+
]);
|
|
2591
|
+
});
|
|
2592
|
+
it('built-in interface param types allowed in brighterscript mode', () => {
|
|
2593
|
+
let { diagnostics } = parse(`
|
|
2594
|
+
sub test(foo as roAssociativeArray)
|
|
2595
|
+
print foo.x
|
|
2596
|
+
end sub
|
|
2597
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2598
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2599
|
+
});
|
|
2600
|
+
it('built-in interface types allowed in brighterscript mode', () => {
|
|
2601
|
+
let { diagnostics } = parse(`
|
|
2602
|
+
function test(foo) as roAssociativeArray
|
|
2603
|
+
return foo.x
|
|
2604
|
+
end function
|
|
2605
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2606
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2607
|
+
});
|
|
2608
|
+
it('custom param types allowed in brighterscript mode', () => {
|
|
2609
|
+
let { diagnostics } = parse(`
|
|
2610
|
+
sub test(foo as Whatever)
|
|
2611
|
+
print foo.x
|
|
2612
|
+
end sub
|
|
2613
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2614
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2615
|
+
});
|
|
2616
|
+
it('custom return types allowed in brighterscript mode', () => {
|
|
2617
|
+
let { diagnostics } = parse(`
|
|
2618
|
+
function test(foo) as Whatever
|
|
2619
|
+
return foo.x
|
|
2620
|
+
end function
|
|
2621
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2622
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2623
|
+
});
|
|
2624
|
+
});
|
|
2625
|
+
describe('inline interfaces', () => {
|
|
2626
|
+
it('inline interface param types disallowed in brightscript mode', () => {
|
|
2627
|
+
let { diagnostics } = parse(`
|
|
2628
|
+
sub test(foo as {x as string})
|
|
2629
|
+
print foo.x
|
|
2630
|
+
end sub
|
|
2631
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2632
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2633
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2634
|
+
]);
|
|
2635
|
+
});
|
|
2636
|
+
it('inline interface return types disallowed in brightscript mode', () => {
|
|
2637
|
+
let { diagnostics } = parse(`
|
|
2638
|
+
function test() as {x as string}
|
|
2639
|
+
print {x: "hello"}
|
|
2640
|
+
end function
|
|
2641
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2642
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2643
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2644
|
+
]);
|
|
2645
|
+
});
|
|
2646
|
+
it('inline interface as param type', () => {
|
|
2647
|
+
var _a;
|
|
2648
|
+
let { ast, diagnostics } = parse(`
|
|
2649
|
+
sub test(foo as {x as string})
|
|
2650
|
+
print foo.x
|
|
2651
|
+
end sub
|
|
2652
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2653
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2654
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
2655
|
+
const func = ast.statements[0].func;
|
|
2656
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)((_a = func.parameters[0].typeExpression) === null || _a === void 0 ? void 0 : _a.expression)).to.be.true;
|
|
2657
|
+
});
|
|
2658
|
+
it('inline interface as return type', () => {
|
|
2659
|
+
let { ast, diagnostics } = parse(`
|
|
2660
|
+
function test() as {x as string}
|
|
2661
|
+
print {x: "hello"}
|
|
2662
|
+
end function
|
|
2663
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2664
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2665
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
2666
|
+
const func = ast.statements[0].func;
|
|
2667
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)(func.returnTypeExpression.expression)).to.be.true;
|
|
2668
|
+
});
|
|
2669
|
+
it('parses a big inline interface as param type', () => {
|
|
2670
|
+
var _a;
|
|
2671
|
+
let { ast, diagnostics } = parse(`
|
|
2672
|
+
sub test(foo as {
|
|
2673
|
+
x as string,
|
|
2674
|
+
y as {a as integer}
|
|
2675
|
+
z})
|
|
2676
|
+
print foo.x + y.a.toStr()
|
|
2677
|
+
end sub
|
|
2678
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2679
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2680
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
2681
|
+
const func = ast.statements[0].func;
|
|
2682
|
+
const inlineIface = (_a = func.parameters[0].typeExpression) === null || _a === void 0 ? void 0 : _a.expression;
|
|
2683
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)(inlineIface)).to.be.true;
|
|
2684
|
+
(0, chai_config_spec_1.expect)(inlineIface.tokens.open).not.to.be.undefined;
|
|
2685
|
+
(0, chai_config_spec_1.expect)(inlineIface.tokens.close).not.to.be.undefined;
|
|
2686
|
+
(0, chai_config_spec_1.expect)(inlineIface.members).to.have.length(3);
|
|
2687
|
+
const iFaceType = inlineIface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
2688
|
+
(0, testHelpers_spec_1.expectTypeToBe)(iFaceType, InlineInterfaceType_1.InlineInterfaceType);
|
|
2689
|
+
(0, testHelpers_spec_1.expectTypeToBe)(iFaceType.getMemberType('x', { flags: 1 /* SymbolTypeFlag.runtime */ }), StringType_1.StringType);
|
|
2690
|
+
(0, testHelpers_spec_1.expectTypeToBe)(iFaceType.getMemberType('y', { flags: 1 /* SymbolTypeFlag.runtime */ }), InlineInterfaceType_1.InlineInterfaceType);
|
|
2691
|
+
(0, testHelpers_spec_1.expectTypeToBe)(iFaceType.getMemberType('z', { flags: 1 /* SymbolTypeFlag.runtime */ }), types_1.DynamicType);
|
|
2692
|
+
});
|
|
2693
|
+
it('allows optional members', () => {
|
|
2694
|
+
var _a;
|
|
2695
|
+
let { ast, diagnostics } = parse(`
|
|
2696
|
+
sub test(p as {x as string, optional y})
|
|
2697
|
+
end sub
|
|
2698
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2699
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2700
|
+
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
2701
|
+
const func = ast.statements[0].func;
|
|
2702
|
+
const inlineIface = (_a = func.parameters[0].typeExpression) === null || _a === void 0 ? void 0 : _a.expression;
|
|
2703
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)(inlineIface)).to.be.true;
|
|
2704
|
+
(0, chai_config_spec_1.expect)(inlineIface.members).to.have.length(2);
|
|
2705
|
+
(0, chai_config_spec_1.expect)(inlineIface.members[1].isOptional).to.be.true;
|
|
2706
|
+
});
|
|
2707
|
+
it('is allowed as typecast', () => {
|
|
2708
|
+
let { diagnostics } = parse(`
|
|
2709
|
+
sub test(p)
|
|
2710
|
+
print (p as {name as string}).name
|
|
2711
|
+
end sub
|
|
2712
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2713
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2714
|
+
});
|
|
2715
|
+
it('is allowed as class and interface field', () => {
|
|
2716
|
+
let { diagnostics } = parse(`
|
|
2717
|
+
class Klass
|
|
2718
|
+
x as {name as string}
|
|
2719
|
+
end class
|
|
2720
|
+
|
|
2721
|
+
interface Iface
|
|
2722
|
+
y as {age as integer}
|
|
2723
|
+
end interface
|
|
2724
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2725
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2726
|
+
});
|
|
2727
|
+
it('can have custom type as member type', () => {
|
|
2728
|
+
let { diagnostics } = parse(`
|
|
2729
|
+
interface IFace
|
|
2730
|
+
name as string
|
|
2731
|
+
end interface
|
|
2732
|
+
|
|
2733
|
+
function test(z as {foo as IFace})
|
|
2734
|
+
return z.foo.name
|
|
2735
|
+
end function
|
|
2736
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2737
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2738
|
+
});
|
|
2739
|
+
it('can have per-member doc comment', () => {
|
|
2740
|
+
let { diagnostics } = parse(`
|
|
2741
|
+
interface IFace
|
|
2742
|
+
inline as {
|
|
2743
|
+
' comment 1
|
|
2744
|
+
name as string
|
|
2745
|
+
' comment 2
|
|
2746
|
+
age as integer
|
|
2747
|
+
}
|
|
2748
|
+
end interface
|
|
2749
|
+
|
|
2750
|
+
function test(z as {foo as IFace})
|
|
2751
|
+
return z.foo.inline.name
|
|
2752
|
+
end function
|
|
2753
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2754
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2755
|
+
});
|
|
2756
|
+
it('can have string literals as members', () => {
|
|
2757
|
+
let { diagnostics } = parse(`
|
|
2758
|
+
function test(z as {"this is a stringliteral" as string})
|
|
2759
|
+
return z["this is a stringliteral"]
|
|
2760
|
+
end function
|
|
2761
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2762
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2763
|
+
});
|
|
2764
|
+
});
|
|
2765
|
+
});
|
|
2766
|
+
function parse(text, mode, bsConsts = {}) {
|
|
2767
|
+
let { tokens } = Lexer_1.Lexer.scan(text);
|
|
2768
|
+
const bsConstMap = new Map();
|
|
2769
|
+
for (const constName in bsConsts) {
|
|
2770
|
+
bsConstMap.set(constName.toLowerCase(), bsConsts[constName]);
|
|
2771
|
+
}
|
|
1191
2772
|
return Parser_1.Parser.parse(tokens, {
|
|
1192
|
-
|
|
2773
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
|
|
2774
|
+
mode: mode,
|
|
2775
|
+
bsConsts: bsConstMap
|
|
1193
2776
|
});
|
|
1194
2777
|
}
|
|
2778
|
+
exports.parse = parse;
|
|
1195
2779
|
function rangeToArray(range) {
|
|
1196
2780
|
return [
|
|
1197
2781
|
range.start.line,
|
|
@@ -1202,15 +2786,17 @@ function rangeToArray(range) {
|
|
|
1202
2786
|
}
|
|
1203
2787
|
exports.rangeToArray = rangeToArray;
|
|
1204
2788
|
function expectCommentWithText(stat, text) {
|
|
1205
|
-
|
|
1206
|
-
|
|
2789
|
+
const trivia = stat.leadingTrivia;
|
|
2790
|
+
if (trivia) {
|
|
2791
|
+
(0, chai_config_spec_1.expect)(trivia.filter(tok => tok.kind === TokenKind_1.TokenKind.Comment).map(t => t.text).join('\n')).to.equal(text);
|
|
1207
2792
|
}
|
|
1208
2793
|
else {
|
|
1209
2794
|
failStatementType(stat, 'Comment');
|
|
1210
2795
|
}
|
|
1211
2796
|
}
|
|
1212
2797
|
function failStatementType(stat, type) {
|
|
1213
|
-
|
|
2798
|
+
var _a;
|
|
2799
|
+
chai_config_spec_1.assert.fail(`Statement ${stat.constructor.name} line ${(_a = stat.location) === null || _a === void 0 ? void 0 : _a.range.start.line} is not a ${type}`);
|
|
1214
2800
|
}
|
|
1215
2801
|
exports.failStatementType = failStatementType;
|
|
1216
2802
|
//# sourceMappingURL=Parser.spec.js.map
|