brighterscript 1.0.0-alpha.5 → 1.0.0-alpha.51
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 +79 -138
- package/bsconfig.schema.json +196 -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 +161 -43
- 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 +29 -4
- package/dist/CodeActionUtil.js +22 -5
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +20 -15
- package/dist/CommentFlagProcessor.js +143 -58
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/CrossScopeValidator.d.ts +68 -0
- package/dist/CrossScopeValidator.js +650 -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 +83 -0
- package/dist/DiagnosticManager.js +422 -0
- package/dist/DiagnosticManager.js.map +1 -0
- package/dist/DiagnosticMessages.d.ts +602 -196
- package/dist/DiagnosticMessages.js +926 -342
- 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 +136 -104
- package/dist/LanguageServer.js +577 -741
- 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 +302 -98
- package/dist/Program.js +1613 -726
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +39 -22
- package/dist/ProgramBuilder.js +245 -179
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +227 -106
- package/dist/Scope.js +609 -557
- package/dist/Scope.js.map +1 -1
- package/dist/ScopeNamespaceLookup.d.ts +73 -0
- package/dist/ScopeNamespaceLookup.js +242 -0
- package/dist/ScopeNamespaceLookup.js.map +1 -0
- 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 +145 -26
- package/dist/SymbolTable.js +575 -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 +337 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/Editor.d.ts +69 -0
- package/dist/astUtils/Editor.js +245 -0
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/creators.d.ts +54 -19
- package/dist/astUtils/creators.js +242 -42
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +199 -85
- package/dist/astUtils/reflection.js +518 -145
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/stackedVisitor.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +117 -53
- package/dist/astUtils/visitors.js +95 -15
- package/dist/astUtils/visitors.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 +26 -4
- package/dist/bscPlugin/BscPlugin.js +96 -4
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
- package/dist/bscPlugin/CallExpressionInfo.js +142 -0
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
- package/dist/bscPlugin/FileWriter.d.ts +19 -0
- package/dist/bscPlugin/FileWriter.js +79 -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 +109 -7
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +676 -26
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.d.ts +17 -0
- package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.js +66 -0
- package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.js.map +1 -0
- package/dist/bscPlugin/codeActions/codeActionHelpers.d.ts +18 -0
- package/dist/bscPlugin/codeActions/codeActionHelpers.js +31 -0
- package/dist/bscPlugin/codeActions/codeActionHelpers.js.map +1 -0
- 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/definition/DefinitionProvider.d.ts +13 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js +220 -0
- package/dist/bscPlugin/definition/DefinitionProvider.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 +238 -0
- package/dist/bscPlugin/hover/HoverProcessor.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/selectionRanges/SelectionRangesProcessor.d.ts +7 -0
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.js +77 -0
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.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/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 +80 -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/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/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 +34 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +504 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.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 +51 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +714 -0
- package/dist/bscPlugin/validation/BrsFileValidator.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 +158 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +1481 -0
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
- package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js +50 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
- package/dist/cli.js +140 -28
- 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/deferred.d.ts +5 -3
- package/dist/deferred.js +10 -0
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +61 -4
- package/dist/diagnosticUtils.js +285 -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.d.ts +161 -87
- package/dist/files/BrsFile.js +919 -936
- package/dist/files/BrsFile.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/XmlFile.d.ts +80 -41
- package/dist/files/XmlFile.js +162 -137
- package/dist/files/XmlFile.js.map +1 -1
- 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 +987 -125
- package/dist/interfaces.js +21 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +51 -12
- package/dist/lexer/Lexer.js +214 -65
- package/dist/lexer/Lexer.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 +48 -2
- package/dist/lexer/TokenKind.js +167 -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/DocumentManager.d.ts +63 -0
- package/dist/lsp/DocumentManager.js +122 -0
- package/dist/lsp/DocumentManager.js.map +1 -0
- package/dist/lsp/LspProject.d.ts +287 -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/Project.d.ts +200 -0
- package/dist/lsp/Project.js +562 -0
- package/dist/lsp/Project.js.map +1 -0
- package/dist/lsp/ProjectManager.d.ts +288 -0
- package/dist/lsp/ProjectManager.js +967 -0
- package/dist/lsp/ProjectManager.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/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/WorkerThreadProject.d.ts +168 -0
- package/dist/lsp/worker/WorkerThreadProject.js +205 -0
- package/dist/lsp/worker/WorkerThreadProject.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.js +14 -0
- package/dist/lsp/worker/run.js.map +1 -0
- package/dist/parser/AstNode.d.ts +205 -0
- package/dist/parser/AstNode.js +305 -0
- package/dist/parser/AstNode.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/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 +601 -220
- package/dist/parser/Expression.js +1516 -502
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.d.ts +137 -121
- package/dist/parser/Parser.js +1808 -982
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/SGParser.d.ts +30 -13
- package/dist/parser/SGParser.js +94 -56
- package/dist/parser/SGParser.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 +854 -267
- package/dist/parser/Statement.js +2416 -621
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +30 -14
- package/dist/parser/TranspileState.js +124 -27
- package/dist/parser/TranspileState.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/roku-types/data.json +20554 -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 +95 -25
- package/dist/types/ArrayType.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/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/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 +63 -0
- package/dist/types/ClassType.js.map +1 -0
- package/dist/types/ComponentType.d.ts +22 -0
- package/dist/types/ComponentType.js +110 -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/DynamicType.d.ts +13 -5
- package/dist/types/DynamicType.js +26 -5
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/EnumType.d.ts +42 -0
- package/dist/types/EnumType.js +101 -0
- package/dist/types/EnumType.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/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/InterfaceType.d.ts +14 -6
- package/dist/types/InterfaceType.js +30 -15
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/IntersectionType.d.ts +29 -0
- package/dist/types/IntersectionType.js +256 -0
- package/dist/types/IntersectionType.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/LongIntegerType.d.ts +10 -5
- package/dist/types/LongIntegerType.js +21 -17
- package/dist/types/LongIntegerType.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/ReferenceType.d.ts +123 -0
- package/dist/types/ReferenceType.js +726 -0
- package/dist/types/ReferenceType.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/TypeStatementType.d.ts +19 -0
- package/dist/types/TypeStatementType.js +56 -0
- package/dist/types/TypeStatementType.js.map +1 -0
- package/dist/types/TypedFunctionType.d.ts +34 -0
- package/dist/types/TypedFunctionType.js +157 -0
- package/dist/types/TypedFunctionType.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 +196 -0
- package/dist/types/UnionType.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/helpers.d.ts +51 -0
- package/dist/types/helpers.js +329 -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/util.d.ts +325 -185
- package/dist/util.js +2135 -568
- 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 +183 -138
- package/CHANGELOG.md +0 -1188
- package/dist/astUtils/creators.spec.js +0 -21
- package/dist/astUtils/creators.spec.js.map +0 -1
- 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/astUtils/reflection.spec.d.ts +0 -1
- package/dist/astUtils/reflection.spec.js +0 -292
- package/dist/astUtils/reflection.spec.js.map +0 -1
- package/dist/astUtils/stackedVisitor.spec.d.ts +0 -1
- package/dist/astUtils/stackedVisitor.spec.js +0 -79
- package/dist/astUtils/stackedVisitor.spec.js.map +0 -1
- package/dist/astUtils/visitors.spec.d.ts +0 -1
- package/dist/astUtils/visitors.spec.js +0 -854
- package/dist/astUtils/visitors.spec.js.map +0 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +0 -194
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.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.d.ts +0 -1
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js +0 -45
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +0 -1
- package/dist/files/BrsFile.Class.spec.d.ts +0 -1
- package/dist/files/BrsFile.Class.spec.js +0 -1081
- package/dist/files/BrsFile.Class.spec.js.map +0 -1
- package/dist/files/BrsFile.spec.d.ts +0 -1
- package/dist/files/BrsFile.spec.js +0 -2524
- package/dist/files/BrsFile.spec.js.map +0 -1
- package/dist/files/XmlFile.spec.d.ts +0 -1
- package/dist/files/XmlFile.spec.js +0 -1065
- package/dist/files/XmlFile.spec.js.map +0 -1
- package/dist/files/tests/imports.spec.d.ts +0 -1
- package/dist/files/tests/imports.spec.js +0 -241
- package/dist/files/tests/imports.spec.js.map +0 -1
- package/dist/lexer/Character.spec.d.ts +0 -1
- package/dist/lexer/Character.spec.js +0 -27
- package/dist/lexer/Character.spec.js.map +0 -1
- package/dist/lexer/Lexer.spec.d.ts +0 -1
- package/dist/lexer/Lexer.spec.js +0 -1101
- package/dist/lexer/Lexer.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/Parser.Class.spec.d.ts +0 -1
- package/dist/parser/Parser.Class.spec.js +0 -390
- package/dist/parser/Parser.Class.spec.js.map +0 -1
- package/dist/parser/Parser.spec.d.ts +0 -4
- package/dist/parser/Parser.spec.js +0 -1216
- package/dist/parser/Parser.spec.js.map +0 -1
- package/dist/parser/SGParser.spec.d.ts +0 -1
- package/dist/parser/SGParser.spec.js +0 -145
- package/dist/parser/SGParser.spec.js.map +0 -1
- package/dist/parser/SGTypes.spec.d.ts +0 -1
- package/dist/parser/SGTypes.spec.js +0 -351
- package/dist/parser/SGTypes.spec.js.map +0 -1
- package/dist/parser/Statement.spec.d.ts +0 -1
- package/dist/parser/Statement.spec.js +0 -94
- package/dist/parser/Statement.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/parser/tests/Parser.spec.d.ts +0 -18
- package/dist/parser/tests/Parser.spec.js +0 -35
- package/dist/parser/tests/Parser.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/For.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/For.spec.js +0 -161
- package/dist/parser/tests/controlFlow/For.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +0 -106
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/If.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/If.spec.js +0 -551
- package/dist/parser/tests/controlFlow/If.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/While.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/While.spec.js +0 -107
- package/dist/parser/tests/controlFlow/While.spec.js.map +0 -1
- package/dist/parser/tests/expression/Additive.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Additive.spec.js +0 -99
- package/dist/parser/tests/expression/Additive.spec.js.map +0 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.d.ts +0 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +0 -254
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +0 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.d.ts +0 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +0 -266
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +0 -1
- package/dist/parser/tests/expression/Boolean.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Boolean.spec.js +0 -83
- package/dist/parser/tests/expression/Boolean.spec.js.map +0 -1
- package/dist/parser/tests/expression/Call.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Call.spec.js +0 -134
- package/dist/parser/tests/expression/Call.spec.js.map +0 -1
- package/dist/parser/tests/expression/Exponential.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Exponential.spec.js +0 -37
- package/dist/parser/tests/expression/Exponential.spec.js.map +0 -1
- package/dist/parser/tests/expression/Function.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Function.spec.js +0 -403
- package/dist/parser/tests/expression/Function.spec.js.map +0 -1
- package/dist/parser/tests/expression/Indexing.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Indexing.spec.js +0 -219
- package/dist/parser/tests/expression/Indexing.spec.js.map +0 -1
- package/dist/parser/tests/expression/Multiplicative.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +0 -67
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +0 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +0 -201
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.d.ts +0 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +0 -105
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +0 -1
- package/dist/parser/tests/expression/Primary.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Primary.spec.js +0 -149
- package/dist/parser/tests/expression/Primary.spec.js.map +0 -1
- package/dist/parser/tests/expression/Relational.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Relational.spec.js +0 -83
- package/dist/parser/tests/expression/Relational.spec.js.map +0 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +0 -201
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +0 -202
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +0 -323
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +0 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.d.ts +0 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +0 -79
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +0 -1
- package/dist/parser/tests/statement/Declaration.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Declaration.spec.js +0 -108
- package/dist/parser/tests/statement/Declaration.spec.js.map +0 -1
- package/dist/parser/tests/statement/Dim.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Dim.spec.js +0 -73
- package/dist/parser/tests/statement/Dim.spec.js.map +0 -1
- package/dist/parser/tests/statement/Function.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Function.spec.js +0 -332
- package/dist/parser/tests/statement/Function.spec.js.map +0 -1
- package/dist/parser/tests/statement/Goto.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Goto.spec.js +0 -50
- package/dist/parser/tests/statement/Goto.spec.js.map +0 -1
- package/dist/parser/tests/statement/Increment.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Increment.spec.js +0 -117
- package/dist/parser/tests/statement/Increment.spec.js.map +0 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +0 -74
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Misc.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Misc.spec.js +0 -333
- package/dist/parser/tests/statement/Misc.spec.js.map +0 -1
- package/dist/parser/tests/statement/PrintStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +0 -181
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +0 -94
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Set.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Set.spec.js +0 -218
- package/dist/parser/tests/statement/Set.spec.js.map +0 -1
- package/dist/parser/tests/statement/Stop.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Stop.spec.js +0 -37
- package/dist/parser/tests/statement/Stop.spec.js.map +0 -1
- package/dist/parser/tests/statement/Throw.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Throw.spec.js +0 -35
- package/dist/parser/tests/statement/Throw.spec.js.map +0 -1
- package/dist/parser/tests/statement/TryCatch.spec.d.ts +0 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +0 -140
- package/dist/parser/tests/statement/TryCatch.spec.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/Manifest.spec.d.ts +0 -0
- package/dist/preprocessor/Manifest.spec.js +0 -105
- package/dist/preprocessor/Manifest.spec.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.d.ts +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.d.ts +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/ArrayType.spec.d.ts +0 -1
- package/dist/types/ArrayType.spec.js +0 -30
- package/dist/types/ArrayType.spec.js.map +0 -1
- package/dist/types/BooleanType.spec.d.ts +0 -1
- package/dist/types/BooleanType.spec.js +0 -12
- package/dist/types/BooleanType.spec.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/DoubleType.spec.d.ts +0 -1
- package/dist/types/DoubleType.spec.js +0 -12
- package/dist/types/DoubleType.spec.js.map +0 -1
- package/dist/types/DynamicType.spec.d.ts +0 -1
- package/dist/types/DynamicType.spec.js +0 -12
- package/dist/types/DynamicType.spec.js.map +0 -1
- package/dist/types/FloatType.spec.d.ts +0 -1
- package/dist/types/FloatType.spec.js +0 -12
- package/dist/types/FloatType.spec.js.map +0 -1
- package/dist/types/FunctionType.spec.d.ts +0 -1
- package/dist/types/FunctionType.spec.js +0 -29
- package/dist/types/FunctionType.spec.js.map +0 -1
- package/dist/types/IntegerType.spec.d.ts +0 -1
- package/dist/types/IntegerType.spec.js +0 -12
- package/dist/types/IntegerType.spec.js.map +0 -1
- package/dist/types/InvalidType.spec.d.ts +0 -1
- package/dist/types/InvalidType.spec.js +0 -12
- package/dist/types/InvalidType.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/types/LongIntegerType.spec.d.ts +0 -1
- package/dist/types/LongIntegerType.spec.js +0 -12
- package/dist/types/LongIntegerType.spec.js.map +0 -1
- package/dist/types/ObjectType.spec.d.ts +0 -1
- package/dist/types/ObjectType.spec.js +0 -12
- package/dist/types/ObjectType.spec.js.map +0 -1
- package/dist/types/StringType.spec.d.ts +0 -1
- package/dist/types/StringType.spec.js +0 -12
- package/dist/types/StringType.spec.js.map +0 -1
- package/dist/types/VoidType.spec.d.ts +0 -1
- package/dist/types/VoidType.spec.js +0 -12
- package/dist/types/VoidType.spec.js.map +0 -1
- /package/dist/{astUtils/creators.spec.d.ts → lsp/worker/run.d.ts} +0 -0
|
@@ -1,2524 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const chai_1 = require("chai");
|
|
4
|
-
const sinonImport = require("sinon");
|
|
5
|
-
const path = require("path");
|
|
6
|
-
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
7
|
-
const Program_1 = require("../Program");
|
|
8
|
-
const BooleanType_1 = require("../types/BooleanType");
|
|
9
|
-
const DynamicType_1 = require("../types/DynamicType");
|
|
10
|
-
const FunctionType_1 = require("../types/FunctionType");
|
|
11
|
-
const IntegerType_1 = require("../types/IntegerType");
|
|
12
|
-
const StringType_1 = require("../types/StringType");
|
|
13
|
-
const BrsFile_1 = require("./BrsFile");
|
|
14
|
-
const source_map_1 = require("source-map");
|
|
15
|
-
const lexer_1 = require("../lexer");
|
|
16
|
-
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
17
|
-
const util_1 = require("../util");
|
|
18
|
-
const PluginInterface_1 = require("../PluginInterface");
|
|
19
|
-
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
20
|
-
const Parser_1 = require("../parser/Parser");
|
|
21
|
-
const Logger_1 = require("../Logger");
|
|
22
|
-
const VoidType_1 = require("../types/VoidType");
|
|
23
|
-
let sinon = sinonImport.createSandbox();
|
|
24
|
-
describe('BrsFile', () => {
|
|
25
|
-
let rootDir = util_1.standardizePath `${process.cwd()}/.tmp/rootDir`;
|
|
26
|
-
let program;
|
|
27
|
-
let srcPath = util_1.standardizePath `${rootDir}/source/main.brs`;
|
|
28
|
-
let destPath = 'source/main.brs';
|
|
29
|
-
let file;
|
|
30
|
-
let testTranspile = testHelpers_spec_1.getTestTranspile(() => [program, rootDir]);
|
|
31
|
-
beforeEach(() => {
|
|
32
|
-
program = new Program_1.Program({ rootDir: rootDir, sourceMap: true });
|
|
33
|
-
file = new BrsFile_1.BrsFile(srcPath, destPath, program);
|
|
34
|
-
});
|
|
35
|
-
afterEach(() => {
|
|
36
|
-
sinon.restore();
|
|
37
|
-
program.dispose();
|
|
38
|
-
});
|
|
39
|
-
it('supports the third parameter in CreateObject', () => {
|
|
40
|
-
var _a;
|
|
41
|
-
program.setFile('source/main.brs', `
|
|
42
|
-
sub main()
|
|
43
|
-
regexp = CreateObject("roRegex", "[a-z]+", "i")
|
|
44
|
-
end sub
|
|
45
|
-
`);
|
|
46
|
-
program.validate();
|
|
47
|
-
chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
48
|
-
});
|
|
49
|
-
it('sets needsTranspiled to true for .bs files', () => {
|
|
50
|
-
//BrightScript
|
|
51
|
-
chai_1.expect(new BrsFile_1.BrsFile(`${rootDir}/source/main.brs`, 'source/main.brs', program).needsTranspiled).to.be.false;
|
|
52
|
-
//BrighterScript
|
|
53
|
-
chai_1.expect(new BrsFile_1.BrsFile(`${rootDir}/source/main.bs`, 'source/main.bs', program).needsTranspiled).to.be.true;
|
|
54
|
-
});
|
|
55
|
-
it('allows adding diagnostics', () => {
|
|
56
|
-
const expected = [{
|
|
57
|
-
message: 'message',
|
|
58
|
-
file: undefined,
|
|
59
|
-
range: undefined
|
|
60
|
-
}];
|
|
61
|
-
file.addDiagnostics(expected);
|
|
62
|
-
const actual = file.getDiagnostics();
|
|
63
|
-
chai_1.expect(actual).deep.equal(expected);
|
|
64
|
-
});
|
|
65
|
-
describe('getPartialVariableName', () => {
|
|
66
|
-
let entry = {
|
|
67
|
-
src: `${rootDir}/source/lib.brs`,
|
|
68
|
-
dest: `source/lib.brs`
|
|
69
|
-
};
|
|
70
|
-
it('creates proper tokens', () => {
|
|
71
|
-
file = program.setFile(entry, `call(ModuleA.ModuleB.ModuleC.`);
|
|
72
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[7])).to.equal('ModuleA.ModuleB.ModuleC.');
|
|
73
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[6])).to.equal('ModuleA.ModuleB.ModuleC');
|
|
74
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[5])).to.equal('ModuleA.ModuleB.');
|
|
75
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[4])).to.equal('ModuleA.ModuleB');
|
|
76
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[3])).to.equal('ModuleA.');
|
|
77
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[2])).to.equal('ModuleA');
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
describe('getScopesForFile', () => {
|
|
81
|
-
it('finds the scope for the file', () => {
|
|
82
|
-
var _a;
|
|
83
|
-
let file = program.setFile('source/main.brs', ``);
|
|
84
|
-
chai_1.expect((_a = program.getScopesForFile(file)[0]) === null || _a === void 0 ? void 0 : _a.name).to.equal('source');
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
describe('getCompletions', () => {
|
|
88
|
-
it('does not crash for callfunc on a function call', () => {
|
|
89
|
-
const file = program.setFile('source/main.brs', `
|
|
90
|
-
sub main()
|
|
91
|
-
getManager()@.
|
|
92
|
-
end sub
|
|
93
|
-
`);
|
|
94
|
-
chai_1.expect(() => {
|
|
95
|
-
program.getCompletions(file.srcPath, util_1.default.createPosition(2, 34));
|
|
96
|
-
}).not.to.throw;
|
|
97
|
-
});
|
|
98
|
-
it('suggests pkg paths in strings that match that criteria', () => {
|
|
99
|
-
program.setFile('source/main.brs', `
|
|
100
|
-
sub main()
|
|
101
|
-
print "pkg:"
|
|
102
|
-
end sub
|
|
103
|
-
`);
|
|
104
|
-
const result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
|
|
105
|
-
const names = result.map(x => x.label);
|
|
106
|
-
chai_1.expect(names.sort()).to.eql([
|
|
107
|
-
'pkg:/source/main.brs'
|
|
108
|
-
]);
|
|
109
|
-
});
|
|
110
|
-
it('suggests libpkg paths in strings that match that criteria', () => {
|
|
111
|
-
program.setFile('source/main.brs', `
|
|
112
|
-
sub main()
|
|
113
|
-
print "libpkg:"
|
|
114
|
-
end sub
|
|
115
|
-
`);
|
|
116
|
-
const result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
|
|
117
|
-
const names = result.map(x => x.label);
|
|
118
|
-
chai_1.expect(names.sort()).to.eql([
|
|
119
|
-
'libpkg:/source/main.brs'
|
|
120
|
-
]);
|
|
121
|
-
});
|
|
122
|
-
it('suggests pkg paths in template strings', () => {
|
|
123
|
-
program.setFile('source/main.brs', `
|
|
124
|
-
sub main()
|
|
125
|
-
print \`pkg:\`
|
|
126
|
-
end sub
|
|
127
|
-
`);
|
|
128
|
-
const result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
|
|
129
|
-
const names = result.map(x => x.label);
|
|
130
|
-
chai_1.expect(names.sort()).to.eql([
|
|
131
|
-
'pkg:/source/main.brs'
|
|
132
|
-
]);
|
|
133
|
-
});
|
|
134
|
-
it('waits for the file to be processed before collecting completions', () => {
|
|
135
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
136
|
-
program.setFile('source/main.brs', `
|
|
137
|
-
sub Main()
|
|
138
|
-
print "hello"
|
|
139
|
-
Say
|
|
140
|
-
end sub
|
|
141
|
-
|
|
142
|
-
sub SayHello()
|
|
143
|
-
end sub
|
|
144
|
-
`);
|
|
145
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 23));
|
|
146
|
-
let names = result.map(x => x.label);
|
|
147
|
-
chai_1.expect(names).to.includes('Main');
|
|
148
|
-
chai_1.expect(names).to.includes('SayHello');
|
|
149
|
-
});
|
|
150
|
-
it('always includes `m`', () => {
|
|
151
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
152
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
153
|
-
sub Main()
|
|
154
|
-
|
|
155
|
-
end sub
|
|
156
|
-
`);
|
|
157
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
158
|
-
let names = result.map(x => x.label);
|
|
159
|
-
chai_1.expect(names).to.contain('m');
|
|
160
|
-
});
|
|
161
|
-
it('does not fail for missing previousToken', () => {
|
|
162
|
-
//add a single character to the file, and get completions after it
|
|
163
|
-
program.setFile('source/main.brs', `i`);
|
|
164
|
-
chai_1.expect(() => {
|
|
165
|
-
program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(0, 1)).map(x => x.label);
|
|
166
|
-
}).not.to.throw;
|
|
167
|
-
});
|
|
168
|
-
it('includes all keywords`', () => {
|
|
169
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
170
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
171
|
-
sub Main()
|
|
172
|
-
|
|
173
|
-
end sub
|
|
174
|
-
`);
|
|
175
|
-
let keywords = Object.keys(lexer_1.Keywords).filter(x => !x.includes(' '));
|
|
176
|
-
//inside the function
|
|
177
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
178
|
-
let names = result.map(x => x.label);
|
|
179
|
-
for (let keyword of keywords) {
|
|
180
|
-
chai_1.expect(names).to.include(keyword);
|
|
181
|
-
}
|
|
182
|
-
//outside the function
|
|
183
|
-
result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(4, 8));
|
|
184
|
-
names = result.map(x => x.label);
|
|
185
|
-
for (let keyword of keywords) {
|
|
186
|
-
chai_1.expect(names).to.include(keyword);
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
it('does not provide completions within a comment', () => {
|
|
190
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
191
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
192
|
-
sub Main()
|
|
193
|
-
'some comment
|
|
194
|
-
end sub
|
|
195
|
-
`);
|
|
196
|
-
//inside the function
|
|
197
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 33));
|
|
198
|
-
chai_1.expect(result).to.be.lengthOf(0);
|
|
199
|
-
});
|
|
200
|
-
it('does not provide duplicate entries for variables', () => {
|
|
201
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
202
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
203
|
-
sub Main()
|
|
204
|
-
name = "bob"
|
|
205
|
-
age = 12
|
|
206
|
-
name = "john"
|
|
207
|
-
end sub
|
|
208
|
-
`);
|
|
209
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 23));
|
|
210
|
-
let count = result.reduce((total, x) => {
|
|
211
|
-
return x.label === 'name' ? total + 1 : total;
|
|
212
|
-
}, 0);
|
|
213
|
-
chai_1.expect(count).to.equal(1);
|
|
214
|
-
});
|
|
215
|
-
it('does not include `as` and `string` text options when used in function params', () => {
|
|
216
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
217
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
218
|
-
sub Main(name as string)
|
|
219
|
-
|
|
220
|
-
end sub
|
|
221
|
-
`);
|
|
222
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
223
|
-
chai_1.expect(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('as');
|
|
224
|
-
chai_1.expect(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('string');
|
|
225
|
-
});
|
|
226
|
-
it('does not provide intellisense results when inside a comment', () => {
|
|
227
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
228
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
229
|
-
sub Main(name as string)
|
|
230
|
-
'this is a comment
|
|
231
|
-
end sub
|
|
232
|
-
`);
|
|
233
|
-
let results = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 30));
|
|
234
|
-
chai_1.expect(results).to.be.empty;
|
|
235
|
-
});
|
|
236
|
-
it('does provide intellisence for labels only after a goto keyword', () => {
|
|
237
|
-
var _a;
|
|
238
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
239
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
240
|
-
sub Main(name as string)
|
|
241
|
-
something:
|
|
242
|
-
goto \nend sub
|
|
243
|
-
`);
|
|
244
|
-
let results = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 25));
|
|
245
|
-
chai_1.expect(results.length).to.equal(1);
|
|
246
|
-
chai_1.expect((_a = results[0]) === null || _a === void 0 ? void 0 : _a.label).to.equal('something');
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
describe('comment flags', () => {
|
|
250
|
-
describe('bs:disable-next-line', () => {
|
|
251
|
-
it('disables critical diagnostic issues', () => {
|
|
252
|
-
var _a, _b;
|
|
253
|
-
program.setFile('source/main.brs', `
|
|
254
|
-
sub main()
|
|
255
|
-
Dim requestData
|
|
256
|
-
end sub
|
|
257
|
-
`);
|
|
258
|
-
//should have an error
|
|
259
|
-
program.validate();
|
|
260
|
-
chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
261
|
-
program.setFile('source/main.brs', `
|
|
262
|
-
sub main()
|
|
263
|
-
'bs:disable-next-line
|
|
264
|
-
Dim requestData
|
|
265
|
-
end sub
|
|
266
|
-
`);
|
|
267
|
-
//should have an error
|
|
268
|
-
program.validate();
|
|
269
|
-
chai_1.expect((_b = program.getDiagnostics()[0]) === null || _b === void 0 ? void 0 : _b.message).not.to.exist;
|
|
270
|
-
});
|
|
271
|
-
it('works with leading whitespace', () => {
|
|
272
|
-
var _a;
|
|
273
|
-
program.setFile('source/main.brs', `
|
|
274
|
-
sub main()
|
|
275
|
-
' bs:disable-next-line
|
|
276
|
-
=asdf=sadf=
|
|
277
|
-
end sub
|
|
278
|
-
`);
|
|
279
|
-
//should have an error
|
|
280
|
-
program.validate();
|
|
281
|
-
chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
282
|
-
});
|
|
283
|
-
it('works for all', () => {
|
|
284
|
-
var _a;
|
|
285
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
286
|
-
sub Main()
|
|
287
|
-
'bs:disable-next-line
|
|
288
|
-
name = "bob
|
|
289
|
-
end sub
|
|
290
|
-
`);
|
|
291
|
-
chai_1.expect(file.commentFlags[0]).to.exist;
|
|
292
|
-
chai_1.expect(file.commentFlags[0]).to.deep.include({
|
|
293
|
-
codes: null,
|
|
294
|
-
range: vscode_languageserver_1.Range.create(2, 24, 2, 45),
|
|
295
|
-
affectedRange: util_1.default.createRange(3, 0, 3, Number.MAX_SAFE_INTEGER)
|
|
296
|
-
});
|
|
297
|
-
program.validate();
|
|
298
|
-
//the "unterminated string" error should be filtered out
|
|
299
|
-
chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
300
|
-
});
|
|
301
|
-
it('works for specific codes', () => {
|
|
302
|
-
var _a;
|
|
303
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
304
|
-
sub Main()
|
|
305
|
-
'bs:disable-next-line: 1083, 1001
|
|
306
|
-
name = "bob
|
|
307
|
-
end sub
|
|
308
|
-
`);
|
|
309
|
-
chai_1.expect(file.commentFlags[0]).to.exist;
|
|
310
|
-
chai_1.expect(file.commentFlags[0]).to.deep.include({
|
|
311
|
-
codes: [1083, 1001],
|
|
312
|
-
range: vscode_languageserver_1.Range.create(2, 24, 2, 57),
|
|
313
|
-
affectedRange: util_1.default.createRange(3, 0, 3, Number.MAX_SAFE_INTEGER)
|
|
314
|
-
});
|
|
315
|
-
//the "unterminated string" error should be filtered out
|
|
316
|
-
chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
317
|
-
});
|
|
318
|
-
it('ignores non-numeric codes', () => {
|
|
319
|
-
var _a;
|
|
320
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
321
|
-
sub Main()
|
|
322
|
-
'bs:disable-next-line: LINT9999
|
|
323
|
-
name = "bob
|
|
324
|
-
end sub
|
|
325
|
-
`);
|
|
326
|
-
chai_1.expect(file.commentFlags[0]).to.not.exist;
|
|
327
|
-
chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
328
|
-
});
|
|
329
|
-
it('adds diagnostics for unknown numeric diagnostic codes', () => {
|
|
330
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
331
|
-
sub main()
|
|
332
|
-
print "hi" 'bs:disable-line: 123456 999999 aaaab
|
|
333
|
-
end sub
|
|
334
|
-
`);
|
|
335
|
-
program.validate();
|
|
336
|
-
chai_1.expect(program.getDiagnostics()).to.be.lengthOf(2);
|
|
337
|
-
chai_1.expect(program.getDiagnostics()[0]).to.deep.include({
|
|
338
|
-
range: vscode_languageserver_1.Range.create(2, 53, 2, 59)
|
|
339
|
-
});
|
|
340
|
-
chai_1.expect(program.getDiagnostics()[1]).to.deep.include({
|
|
341
|
-
range: vscode_languageserver_1.Range.create(2, 60, 2, 66)
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
describe('bs:disable-line', () => {
|
|
346
|
-
it('works for all', () => {
|
|
347
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
348
|
-
sub Main()
|
|
349
|
-
z::;;%%%%%% 'bs:disable-line
|
|
350
|
-
end sub
|
|
351
|
-
`);
|
|
352
|
-
chai_1.expect(file.commentFlags[0]).to.exist;
|
|
353
|
-
chai_1.expect(file.commentFlags[0]).to.deep.include({
|
|
354
|
-
codes: null,
|
|
355
|
-
range: vscode_languageserver_1.Range.create(2, 36, 2, 52),
|
|
356
|
-
affectedRange: vscode_languageserver_1.Range.create(2, 0, 2, 36)
|
|
357
|
-
});
|
|
358
|
-
program.validate();
|
|
359
|
-
//the "unterminated string" error should be filtered out
|
|
360
|
-
chai_1.expect(program.getDiagnostics()).to.be.lengthOf(0);
|
|
361
|
-
});
|
|
362
|
-
it('works for specific codes', () => {
|
|
363
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
364
|
-
sub main()
|
|
365
|
-
'should not have any errors
|
|
366
|
-
DoSomething(1) 'bs:disable-line:1002
|
|
367
|
-
'should have an error because the param-count error is not being suppressed
|
|
368
|
-
DoSomething(1) 'bs:disable-line:1000
|
|
369
|
-
end sub
|
|
370
|
-
sub DoSomething()
|
|
371
|
-
end sub
|
|
372
|
-
`);
|
|
373
|
-
program.validate();
|
|
374
|
-
chai_1.expect(program.getDiagnostics()).to.be.lengthOf(1);
|
|
375
|
-
chai_1.expect(program.getDiagnostics()[0]).to.deep.include({
|
|
376
|
-
range: vscode_languageserver_1.Range.create(5, 24, 5, 35)
|
|
377
|
-
});
|
|
378
|
-
});
|
|
379
|
-
it('handles the erraneous `stop` keyword', () => {
|
|
380
|
-
//the current version of BRS causes parse errors after the `parse` keyword, showing error in comments
|
|
381
|
-
//the program should ignore all diagnostics found in brs:* comment lines EXCEPT
|
|
382
|
-
//for the diagnostics about using unknown error codes
|
|
383
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
384
|
-
sub main()
|
|
385
|
-
stop 'bs:disable-line
|
|
386
|
-
print "need a valid line to fix stop error"
|
|
387
|
-
end sub
|
|
388
|
-
`);
|
|
389
|
-
program.validate();
|
|
390
|
-
chai_1.expect(program.getDiagnostics()).to.be.lengthOf(0);
|
|
391
|
-
});
|
|
392
|
-
});
|
|
393
|
-
});
|
|
394
|
-
describe('parse', () => {
|
|
395
|
-
it('supports iife in assignment', () => {
|
|
396
|
-
program.setFile('source/main.brs', `
|
|
397
|
-
sub main()
|
|
398
|
-
result = sub()
|
|
399
|
-
end sub()
|
|
400
|
-
result = (sub()
|
|
401
|
-
end sub)()
|
|
402
|
-
end sub
|
|
403
|
-
`);
|
|
404
|
-
testHelpers_spec_1.expectZeroDiagnostics(program);
|
|
405
|
-
});
|
|
406
|
-
it('uses the proper parse mode based on file extension', () => {
|
|
407
|
-
function testParseMode(destPath, expectedParseMode) {
|
|
408
|
-
const file = program.setFile(destPath, '');
|
|
409
|
-
chai_1.expect(file.parseMode).to.equal(expectedParseMode);
|
|
410
|
-
}
|
|
411
|
-
testParseMode('source/main.brs', Parser_1.ParseMode.BrightScript);
|
|
412
|
-
testParseMode('source/main.spec.brs', Parser_1.ParseMode.BrightScript);
|
|
413
|
-
testParseMode('source/main.d.brs', Parser_1.ParseMode.BrightScript);
|
|
414
|
-
testParseMode('source/main.bs', Parser_1.ParseMode.BrighterScript);
|
|
415
|
-
testParseMode('source/main.d.bs', Parser_1.ParseMode.BrighterScript);
|
|
416
|
-
testParseMode('source/main.spec.bs', Parser_1.ParseMode.BrighterScript);
|
|
417
|
-
});
|
|
418
|
-
it('supports labels and goto statements', () => {
|
|
419
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
420
|
-
sub Main()
|
|
421
|
-
'multiple goto statements on one line
|
|
422
|
-
goto myLabel : goto myLabel
|
|
423
|
-
myLabel:
|
|
424
|
-
end sub
|
|
425
|
-
`);
|
|
426
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
427
|
-
});
|
|
428
|
-
it('supports empty print statements', () => {
|
|
429
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
430
|
-
sub main()
|
|
431
|
-
print
|
|
432
|
-
end sub
|
|
433
|
-
`);
|
|
434
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
435
|
-
});
|
|
436
|
-
describe('conditional compile', () => {
|
|
437
|
-
it('works for upper case keywords', () => {
|
|
438
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
439
|
-
sub main()
|
|
440
|
-
#CONST someFlag = true
|
|
441
|
-
#IF someFlag
|
|
442
|
-
'code to execute when someFlag is true
|
|
443
|
-
#ELSEIF someFlag
|
|
444
|
-
'code to execute when anotherFlag is true
|
|
445
|
-
#ELSE
|
|
446
|
-
'code
|
|
447
|
-
#ENDIF
|
|
448
|
-
end sub
|
|
449
|
-
`);
|
|
450
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
451
|
-
});
|
|
452
|
-
it('supports single-word #elseif and #endif', () => {
|
|
453
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
454
|
-
sub main()
|
|
455
|
-
#const someFlag = true
|
|
456
|
-
#if someFlag
|
|
457
|
-
'code to execute when someFlag is true
|
|
458
|
-
#elseif someFlag
|
|
459
|
-
'code to execute when anotherFlag is true
|
|
460
|
-
#endif
|
|
461
|
-
end sub
|
|
462
|
-
`);
|
|
463
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
464
|
-
});
|
|
465
|
-
it('supports multi-word #else if and #end if', () => {
|
|
466
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
467
|
-
sub main()
|
|
468
|
-
#const someFlag = true
|
|
469
|
-
#if someFlag
|
|
470
|
-
'code to execute when someFlag is true
|
|
471
|
-
#else if someFlag
|
|
472
|
-
'code to execute when anotherFlag is true
|
|
473
|
-
#end if
|
|
474
|
-
end sub
|
|
475
|
-
`);
|
|
476
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
477
|
-
});
|
|
478
|
-
it('does not choke on invalid code inside a false conditional compile', () => {
|
|
479
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
480
|
-
sub main()
|
|
481
|
-
#if false
|
|
482
|
-
non-commented code here should not cause parse errors
|
|
483
|
-
#end if
|
|
484
|
-
end sub
|
|
485
|
-
`);
|
|
486
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
487
|
-
});
|
|
488
|
-
it('detects syntax error in #if', () => {
|
|
489
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
490
|
-
sub main()
|
|
491
|
-
#if true1
|
|
492
|
-
print "true"
|
|
493
|
-
#end if
|
|
494
|
-
end sub
|
|
495
|
-
`);
|
|
496
|
-
chai_1.expect(file.getDiagnostics()[0]).to.exist.and.deep.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.invalidHashConstValue));
|
|
497
|
-
});
|
|
498
|
-
it('detects syntax error in #const', () => {
|
|
499
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
500
|
-
sub main()
|
|
501
|
-
#if %
|
|
502
|
-
print "true"
|
|
503
|
-
#end if
|
|
504
|
-
end sub
|
|
505
|
-
`);
|
|
506
|
-
chai_1.expect(file.getDiagnostics()[0]).to.exist.and.deep.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedCharacter('%')));
|
|
507
|
-
});
|
|
508
|
-
it('detects #const name using reserved word', () => {
|
|
509
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
510
|
-
sub main()
|
|
511
|
-
#const function = true
|
|
512
|
-
end sub
|
|
513
|
-
`);
|
|
514
|
-
chai_1.expect(file.getDiagnostics()[0]).to.exist.and.deep.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.constNameCannotBeReservedWord()));
|
|
515
|
-
});
|
|
516
|
-
it('detects syntax error in #const', () => {
|
|
517
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
518
|
-
sub main()
|
|
519
|
-
#const someConst = 123
|
|
520
|
-
end sub
|
|
521
|
-
`);
|
|
522
|
-
chai_1.expect(file.getDiagnostics()[0]).to.exist.and.deep.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.invalidHashConstValue()));
|
|
523
|
-
});
|
|
524
|
-
});
|
|
525
|
-
it('supports stop statement', () => {
|
|
526
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
527
|
-
sub main()
|
|
528
|
-
stop
|
|
529
|
-
end sub
|
|
530
|
-
`);
|
|
531
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
532
|
-
});
|
|
533
|
-
it('supports single-line if statements', () => {
|
|
534
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
535
|
-
sub main()
|
|
536
|
-
if 1 < 2: return true: end if
|
|
537
|
-
if 1 < 2: return true
|
|
538
|
-
end if
|
|
539
|
-
if false : print "true" : end if
|
|
540
|
-
if true: print "8 worked": else if true: print "not run": else: print "not run": end if
|
|
541
|
-
if true then : test = sub() : print "yes" : end sub : end if
|
|
542
|
-
end sub
|
|
543
|
-
`);
|
|
544
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
545
|
-
});
|
|
546
|
-
it('supports line_num as global variable', () => {
|
|
547
|
-
var _a;
|
|
548
|
-
file.parse(`
|
|
549
|
-
sub Main()
|
|
550
|
-
print LINE_NUM
|
|
551
|
-
end sub
|
|
552
|
-
`);
|
|
553
|
-
chai_1.expect((_a = file.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
554
|
-
});
|
|
555
|
-
it('supports many keywords as object property names', () => {
|
|
556
|
-
file.parse(`
|
|
557
|
-
sub Main()
|
|
558
|
-
person = {}
|
|
559
|
-
person.and = true
|
|
560
|
-
person.box = true
|
|
561
|
-
person.createobject = true
|
|
562
|
-
person.dim = true
|
|
563
|
-
person.double = true
|
|
564
|
-
person.each = true
|
|
565
|
-
person.else = true
|
|
566
|
-
person.elseif = true
|
|
567
|
-
person.end = true
|
|
568
|
-
person.endfor = true
|
|
569
|
-
person.endfunction = true
|
|
570
|
-
person.endif = true
|
|
571
|
-
person.endsub = true
|
|
572
|
-
person.endwhile = true
|
|
573
|
-
person.eval = true
|
|
574
|
-
person.exit = true
|
|
575
|
-
person.exitfor = true
|
|
576
|
-
person.exitwhile = true
|
|
577
|
-
person.false = true
|
|
578
|
-
person.float = true
|
|
579
|
-
person.for = true
|
|
580
|
-
person.foreach = true
|
|
581
|
-
person.function = true
|
|
582
|
-
person.getglobalaa = true
|
|
583
|
-
person.getlastruncompileerror = true
|
|
584
|
-
person.getlastrunruntimeerror = true
|
|
585
|
-
person.goto = true
|
|
586
|
-
person.if = true
|
|
587
|
-
person.integer = true
|
|
588
|
-
person.invalid = true
|
|
589
|
-
person.let = true
|
|
590
|
-
person.line_num = true
|
|
591
|
-
person.longinteger = true
|
|
592
|
-
person.next = true
|
|
593
|
-
person.not = true
|
|
594
|
-
person.objfun = true
|
|
595
|
-
person.or = true
|
|
596
|
-
person.pos = true
|
|
597
|
-
person.print = true
|
|
598
|
-
person.rem = true
|
|
599
|
-
person.return = true
|
|
600
|
-
person.run = true
|
|
601
|
-
person.step = true
|
|
602
|
-
person.stop = true
|
|
603
|
-
person.string = true
|
|
604
|
-
person.sub = true
|
|
605
|
-
person.tab = true
|
|
606
|
-
person.then = true
|
|
607
|
-
person.to = true
|
|
608
|
-
person.true = true
|
|
609
|
-
person.type = true
|
|
610
|
-
person.while = true
|
|
611
|
-
person.public = true
|
|
612
|
-
person.protected = true
|
|
613
|
-
person.private = true
|
|
614
|
-
person.class = true
|
|
615
|
-
person.override = true
|
|
616
|
-
person.new = true
|
|
617
|
-
end sub
|
|
618
|
-
`);
|
|
619
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
620
|
-
});
|
|
621
|
-
it('does not error on numeric literal type designators', () => {
|
|
622
|
-
file.parse(`
|
|
623
|
-
sub main()
|
|
624
|
-
print &he2
|
|
625
|
-
print 1.2E+2
|
|
626
|
-
print 2!
|
|
627
|
-
print 12D-12
|
|
628
|
-
print 2.3#
|
|
629
|
-
print &hFEDCBA9876543210&
|
|
630
|
-
print 9876543210&
|
|
631
|
-
end sub
|
|
632
|
-
`);
|
|
633
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
634
|
-
});
|
|
635
|
-
it('does not error when encountering sub with return type', () => {
|
|
636
|
-
file.parse(`
|
|
637
|
-
sub main() as integer
|
|
638
|
-
return
|
|
639
|
-
end sub
|
|
640
|
-
`);
|
|
641
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
642
|
-
});
|
|
643
|
-
it('does not lose function statements when mismatched end sub', () => {
|
|
644
|
-
file.parse(`
|
|
645
|
-
sub main()
|
|
646
|
-
sayHi()
|
|
647
|
-
end function
|
|
648
|
-
|
|
649
|
-
sub sayHi()
|
|
650
|
-
print "hello world"
|
|
651
|
-
end sub
|
|
652
|
-
`);
|
|
653
|
-
chai_1.expect(file.parser.references.functionStatements).to.be.lengthOf(2);
|
|
654
|
-
});
|
|
655
|
-
it('does not lose sub scope when mismatched end function', () => {
|
|
656
|
-
file.parse(`
|
|
657
|
-
function main()
|
|
658
|
-
sayHi()
|
|
659
|
-
end sub
|
|
660
|
-
|
|
661
|
-
sub sayHi()
|
|
662
|
-
print "hello world"
|
|
663
|
-
end sub
|
|
664
|
-
`);
|
|
665
|
-
chai_1.expect(file.parser.references.functionStatements).to.be.lengthOf(2);
|
|
666
|
-
});
|
|
667
|
-
it('does not error with boolean in RHS of set statement', () => {
|
|
668
|
-
file.parse(`
|
|
669
|
-
sub main()
|
|
670
|
-
foo = {
|
|
671
|
-
bar: false
|
|
672
|
-
}
|
|
673
|
-
foo.bar = true and false or 3 > 4
|
|
674
|
-
end sub
|
|
675
|
-
`);
|
|
676
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
677
|
-
});
|
|
678
|
-
it('does not error with boolean in RHS of set statement', () => {
|
|
679
|
-
file.parse(`
|
|
680
|
-
sub main()
|
|
681
|
-
m = {
|
|
682
|
-
isTrue: false
|
|
683
|
-
}
|
|
684
|
-
m.isTrue = true = true
|
|
685
|
-
m.isTrue = m.isTrue = true
|
|
686
|
-
m.isTrue = m.isTrue = m.isTrue
|
|
687
|
-
end sub
|
|
688
|
-
`);
|
|
689
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
690
|
-
});
|
|
691
|
-
it('supports variable names ending with type designators', () => {
|
|
692
|
-
file.parse(`
|
|
693
|
-
sub main()
|
|
694
|
-
name$ = "bob"
|
|
695
|
-
age% = 1
|
|
696
|
-
height! = 5.5
|
|
697
|
-
salary# = 9.87654321
|
|
698
|
-
someHex& = 13
|
|
699
|
-
end sub
|
|
700
|
-
`);
|
|
701
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
702
|
-
});
|
|
703
|
-
it('supports multiple spaces between two-word keywords', () => {
|
|
704
|
-
file.parse(`
|
|
705
|
-
sub main()
|
|
706
|
-
if true then
|
|
707
|
-
print "true"
|
|
708
|
-
else if true then
|
|
709
|
-
print "also true"
|
|
710
|
-
end if
|
|
711
|
-
end sub
|
|
712
|
-
`);
|
|
713
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
714
|
-
});
|
|
715
|
-
it('does not error with `stop` as object key', () => {
|
|
716
|
-
file.parse(`
|
|
717
|
-
function GetObject()
|
|
718
|
-
obj = {
|
|
719
|
-
stop: function() as void
|
|
720
|
-
|
|
721
|
-
end function
|
|
722
|
-
}
|
|
723
|
-
return obj
|
|
724
|
-
end function
|
|
725
|
-
`);
|
|
726
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
727
|
-
});
|
|
728
|
-
it('does not error with `run` as object key', () => {
|
|
729
|
-
file.parse(`
|
|
730
|
-
function GetObject()
|
|
731
|
-
obj = {
|
|
732
|
-
run: function() as void
|
|
733
|
-
|
|
734
|
-
end function
|
|
735
|
-
}
|
|
736
|
-
return obj
|
|
737
|
-
end function
|
|
738
|
-
`);
|
|
739
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
740
|
-
});
|
|
741
|
-
it('supports assignment operators', () => {
|
|
742
|
-
file.parse(`
|
|
743
|
-
function Main()
|
|
744
|
-
x = 1
|
|
745
|
-
x += 1
|
|
746
|
-
x += 2
|
|
747
|
-
x -= 1
|
|
748
|
-
x /= 2
|
|
749
|
-
x = 9
|
|
750
|
-
x \\= 2
|
|
751
|
-
x *= 3.0
|
|
752
|
-
x -= 1
|
|
753
|
-
print x
|
|
754
|
-
end function
|
|
755
|
-
`);
|
|
756
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
757
|
-
});
|
|
758
|
-
it('supports `then` as object property', () => {
|
|
759
|
-
file.parse(`
|
|
760
|
-
function Main()
|
|
761
|
-
promise = {
|
|
762
|
-
then: sub()
|
|
763
|
-
end sub
|
|
764
|
-
}
|
|
765
|
-
promise.then()
|
|
766
|
-
end function
|
|
767
|
-
`);
|
|
768
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
769
|
-
});
|
|
770
|
-
it('supports function as parameter type', () => {
|
|
771
|
-
file.parse(`
|
|
772
|
-
sub Main()
|
|
773
|
-
doWork = function(callback as function)
|
|
774
|
-
end function
|
|
775
|
-
end sub
|
|
776
|
-
`);
|
|
777
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
778
|
-
});
|
|
779
|
-
it('supports increment operator', () => {
|
|
780
|
-
file.parse(`
|
|
781
|
-
function Main()
|
|
782
|
-
x = 3
|
|
783
|
-
x++
|
|
784
|
-
end function
|
|
785
|
-
`);
|
|
786
|
-
file.getDiagnostics();
|
|
787
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
788
|
-
});
|
|
789
|
-
it('supports decrement operator', () => {
|
|
790
|
-
file.parse(`
|
|
791
|
-
function Main()
|
|
792
|
-
x = 3
|
|
793
|
-
x--
|
|
794
|
-
end function
|
|
795
|
-
`);
|
|
796
|
-
file.getDiagnostics();
|
|
797
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
798
|
-
});
|
|
799
|
-
it('supports writing numbers with decimal but no trailing digit', () => {
|
|
800
|
-
file.parse(`
|
|
801
|
-
function Main()
|
|
802
|
-
x = 3.
|
|
803
|
-
print x
|
|
804
|
-
end function
|
|
805
|
-
`);
|
|
806
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
807
|
-
});
|
|
808
|
-
it('supports assignment operators against object properties', () => {
|
|
809
|
-
file.parse(`
|
|
810
|
-
function Main()
|
|
811
|
-
m.age = 1
|
|
812
|
-
|
|
813
|
-
m.age += 1
|
|
814
|
-
m.age -= 1
|
|
815
|
-
m.age *= 1
|
|
816
|
-
m.age /= 1
|
|
817
|
-
m.age \\= 1
|
|
818
|
-
|
|
819
|
-
m["age"] += 1
|
|
820
|
-
m["age"] -= 1
|
|
821
|
-
m["age"] *= 1
|
|
822
|
-
m["age"] /= 1
|
|
823
|
-
m["age"] \\= 1
|
|
824
|
-
|
|
825
|
-
print m.age
|
|
826
|
-
end function
|
|
827
|
-
`);
|
|
828
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
829
|
-
});
|
|
830
|
-
//skipped until `brs` supports this
|
|
831
|
-
it('supports bitshift assignment operators', () => {
|
|
832
|
-
file.parse(`
|
|
833
|
-
function Main()
|
|
834
|
-
x = 1
|
|
835
|
-
x <<= 8
|
|
836
|
-
x >>= 4
|
|
837
|
-
print x
|
|
838
|
-
end function
|
|
839
|
-
`);
|
|
840
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
841
|
-
});
|
|
842
|
-
//skipped until `brs` supports this
|
|
843
|
-
it('supports bitshift assignment operators on objects', () => {
|
|
844
|
-
file.parse(`
|
|
845
|
-
function Main()
|
|
846
|
-
m.x = 1
|
|
847
|
-
m.x <<= 1
|
|
848
|
-
m.x >>= 1
|
|
849
|
-
print m.x
|
|
850
|
-
end function
|
|
851
|
-
`);
|
|
852
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
853
|
-
});
|
|
854
|
-
it('supports leading and trailing periods for numeric literals', () => {
|
|
855
|
-
file.parse(`
|
|
856
|
-
function Main()
|
|
857
|
-
one = 1.
|
|
858
|
-
print one
|
|
859
|
-
pointOne = .1
|
|
860
|
-
print pointOne
|
|
861
|
-
end function
|
|
862
|
-
`);
|
|
863
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
864
|
-
});
|
|
865
|
-
it('supports bitshift assignment operators on object properties accessed by array syntax', () => {
|
|
866
|
-
file.parse(`
|
|
867
|
-
function Main()
|
|
868
|
-
m.x = 1
|
|
869
|
-
'm['x'] << 1
|
|
870
|
-
'm['x'] >> 1
|
|
871
|
-
print m.x
|
|
872
|
-
end function
|
|
873
|
-
`);
|
|
874
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
875
|
-
});
|
|
876
|
-
it('supports weird period AA accessor', () => {
|
|
877
|
-
file.parse(`
|
|
878
|
-
function Main()
|
|
879
|
-
m._uuid = "123"
|
|
880
|
-
print m.["_uuid"]
|
|
881
|
-
end function
|
|
882
|
-
`);
|
|
883
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
884
|
-
});
|
|
885
|
-
it('adds error for library statements NOT at top of file', () => {
|
|
886
|
-
let file = program.setFile('source/main.bs', `
|
|
887
|
-
sub main()
|
|
888
|
-
end sub
|
|
889
|
-
import "file.brs"
|
|
890
|
-
`);
|
|
891
|
-
chai_1.expect(file.getDiagnostics().map(x => x.message)).to.eql([
|
|
892
|
-
DiagnosticMessages_1.DiagnosticMessages.importStatementMustBeDeclaredAtTopOfFile().message
|
|
893
|
-
]);
|
|
894
|
-
});
|
|
895
|
-
it('supports library imports', () => {
|
|
896
|
-
file.parse(`
|
|
897
|
-
Library "v30/bslCore.brs"
|
|
898
|
-
`);
|
|
899
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
900
|
-
});
|
|
901
|
-
it('adds error for library statements NOT at top of file', () => {
|
|
902
|
-
let file = program.setFile('source/main.brs', `
|
|
903
|
-
sub main()
|
|
904
|
-
end sub
|
|
905
|
-
Library "v30/bslCore.brs"
|
|
906
|
-
`);
|
|
907
|
-
chai_1.expect(file.getDiagnostics().map(x => x.message)).to.eql([
|
|
908
|
-
DiagnosticMessages_1.DiagnosticMessages.libraryStatementMustBeDeclaredAtTopOfFile().message
|
|
909
|
-
]);
|
|
910
|
-
});
|
|
911
|
-
it('adds error for library statements inside of function body', () => {
|
|
912
|
-
let file = program.setFile('source/main.brs', `
|
|
913
|
-
sub main()
|
|
914
|
-
Library "v30/bslCore.brs"
|
|
915
|
-
end sub
|
|
916
|
-
`);
|
|
917
|
-
chai_1.expect(file.getDiagnostics().map(x => x.message)).to.eql([
|
|
918
|
-
DiagnosticMessages_1.DiagnosticMessages.libraryStatementMustBeDeclaredAtTopOfFile().message
|
|
919
|
-
]);
|
|
920
|
-
});
|
|
921
|
-
it('supports colons as separators in associative array properties', () => {
|
|
922
|
-
file.parse(`
|
|
923
|
-
sub Main()
|
|
924
|
-
obj = {x:0 : y: 1}
|
|
925
|
-
end sub
|
|
926
|
-
`);
|
|
927
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
928
|
-
});
|
|
929
|
-
it('succeeds when finding variables with "sub" in them', () => {
|
|
930
|
-
let file = program.setFile('source/main.brs', `
|
|
931
|
-
function DoSomething()
|
|
932
|
-
return value.subType()
|
|
933
|
-
end function
|
|
934
|
-
`);
|
|
935
|
-
chai_1.expect(file.callables[0]).to.deep.include({
|
|
936
|
-
file: file,
|
|
937
|
-
nameRange: vscode_languageserver_1.Range.create(1, 25, 1, 36)
|
|
938
|
-
});
|
|
939
|
-
});
|
|
940
|
-
it('succeeds when finding variables with the word "function" in them', () => {
|
|
941
|
-
file.parse(`
|
|
942
|
-
function Test()
|
|
943
|
-
typeCheckFunction = RBS_CMN_GetFunction(invalid, methodName)
|
|
944
|
-
end function
|
|
945
|
-
`);
|
|
946
|
-
});
|
|
947
|
-
it('finds line and column numbers for functions', () => {
|
|
948
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
949
|
-
file.parse(`
|
|
950
|
-
function DoA()
|
|
951
|
-
print "A"
|
|
952
|
-
end function
|
|
953
|
-
|
|
954
|
-
function DoB()
|
|
955
|
-
print "B"
|
|
956
|
-
end function
|
|
957
|
-
`);
|
|
958
|
-
chai_1.expect(file.callables[0].name).to.equal('DoA');
|
|
959
|
-
chai_1.expect(file.callables[0].nameRange).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 28));
|
|
960
|
-
chai_1.expect(file.callables[1].name).to.equal('DoB');
|
|
961
|
-
chai_1.expect(file.callables[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 26, 5, 29));
|
|
962
|
-
});
|
|
963
|
-
it('throws an error if the file has already been parsed', () => {
|
|
964
|
-
let file = new BrsFile_1.BrsFile('abspath', 'relpath', program);
|
|
965
|
-
file.parse(`'a comment`);
|
|
966
|
-
try {
|
|
967
|
-
file.parse(`'a new comment`);
|
|
968
|
-
chai_1.assert.fail(null, null, 'Should have thrown an exception, but did not');
|
|
969
|
-
}
|
|
970
|
-
catch (e) {
|
|
971
|
-
//test passes
|
|
972
|
-
}
|
|
973
|
-
});
|
|
974
|
-
it('finds and registers duplicate callables', () => {
|
|
975
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
976
|
-
file.parse(`
|
|
977
|
-
function DoA()
|
|
978
|
-
print "A"
|
|
979
|
-
end function
|
|
980
|
-
|
|
981
|
-
function DoA()
|
|
982
|
-
print "A"
|
|
983
|
-
end function
|
|
984
|
-
`);
|
|
985
|
-
chai_1.expect(file.callables.length).to.equal(2);
|
|
986
|
-
chai_1.expect(file.callables[0].name).to.equal('DoA');
|
|
987
|
-
chai_1.expect(file.callables[0].nameRange.start.line).to.equal(1);
|
|
988
|
-
chai_1.expect(file.callables[1].name).to.equal('DoA');
|
|
989
|
-
chai_1.expect(file.callables[1].nameRange.start.line).to.equal(5);
|
|
990
|
-
});
|
|
991
|
-
it('finds function call line and column numbers', () => {
|
|
992
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
993
|
-
file.parse(`
|
|
994
|
-
function DoA()
|
|
995
|
-
DoB("a")
|
|
996
|
-
end function
|
|
997
|
-
function DoB(a as string)
|
|
998
|
-
DoC()
|
|
999
|
-
end function
|
|
1000
|
-
`);
|
|
1001
|
-
chai_1.expect(file.functionCalls.length).to.equal(2);
|
|
1002
|
-
chai_1.expect(file.functionCalls[0].range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 28));
|
|
1003
|
-
chai_1.expect(file.functionCalls[0].nameRange).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 23));
|
|
1004
|
-
chai_1.expect(file.functionCalls[1].range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 25));
|
|
1005
|
-
chai_1.expect(file.functionCalls[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 23));
|
|
1006
|
-
});
|
|
1007
|
-
it('sanitizes brs errors', () => {
|
|
1008
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1009
|
-
file.parse(`
|
|
1010
|
-
function DoSomething
|
|
1011
|
-
end function
|
|
1012
|
-
`);
|
|
1013
|
-
chai_1.expect(file.getDiagnostics().length).to.be.greaterThan(0);
|
|
1014
|
-
chai_1.expect(file.getDiagnostics()[0]).to.deep.include({
|
|
1015
|
-
file: file
|
|
1016
|
-
});
|
|
1017
|
-
chai_1.expect(file.getDiagnostics()[0].range.start.line).to.equal(1);
|
|
1018
|
-
});
|
|
1019
|
-
it('supports using the `next` keyword in a for loop', () => {
|
|
1020
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1021
|
-
file.parse(`
|
|
1022
|
-
sub countit()
|
|
1023
|
-
for each num in [1,2,3]
|
|
1024
|
-
print num
|
|
1025
|
-
next
|
|
1026
|
-
end sub
|
|
1027
|
-
`);
|
|
1028
|
-
chai_1.expect(file.getDiagnostics()).to.be.empty;
|
|
1029
|
-
});
|
|
1030
|
-
//test is not working yet, but will be enabled when brs supports this syntax
|
|
1031
|
-
it('supports assigning functions to objects', () => {
|
|
1032
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1033
|
-
file.parse(`
|
|
1034
|
-
function main()
|
|
1035
|
-
o = CreateObject("roAssociativeArray")
|
|
1036
|
-
o.sayHello = sub()
|
|
1037
|
-
print "hello"
|
|
1038
|
-
end sub
|
|
1039
|
-
end function
|
|
1040
|
-
`);
|
|
1041
|
-
chai_1.expect(file.getDiagnostics().length).to.equal(0);
|
|
1042
|
-
});
|
|
1043
|
-
});
|
|
1044
|
-
describe('findCallables', () => {
|
|
1045
|
-
it('finds range', () => {
|
|
1046
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1047
|
-
file.parse(`
|
|
1048
|
-
sub Sum()
|
|
1049
|
-
print "hello world"
|
|
1050
|
-
end sub
|
|
1051
|
-
`);
|
|
1052
|
-
let callable = file.callables[0];
|
|
1053
|
-
chai_1.expect(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 3, 23));
|
|
1054
|
-
});
|
|
1055
|
-
it('finds correct body range even with inner function', () => {
|
|
1056
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1057
|
-
file.parse(`
|
|
1058
|
-
sub Sum()
|
|
1059
|
-
sayHi = sub()
|
|
1060
|
-
print "Hi"
|
|
1061
|
-
end sub
|
|
1062
|
-
sayHi()
|
|
1063
|
-
end sub
|
|
1064
|
-
`);
|
|
1065
|
-
let callable = file.callables[0];
|
|
1066
|
-
chai_1.expect(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 6, 23));
|
|
1067
|
-
});
|
|
1068
|
-
it('finds callable parameters', () => {
|
|
1069
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1070
|
-
file.parse(`
|
|
1071
|
-
function Sum(a, b, c)
|
|
1072
|
-
|
|
1073
|
-
end function
|
|
1074
|
-
`);
|
|
1075
|
-
let callable = file.callables[0];
|
|
1076
|
-
chai_1.expect(callable.params[0]).to.deep.include({
|
|
1077
|
-
name: 'a',
|
|
1078
|
-
isOptional: false,
|
|
1079
|
-
isRestArgument: false
|
|
1080
|
-
});
|
|
1081
|
-
chai_1.expect(callable.params[0].type).instanceof(DynamicType_1.DynamicType);
|
|
1082
|
-
chai_1.expect(callable.params[1]).to.deep.include({
|
|
1083
|
-
name: 'b',
|
|
1084
|
-
isOptional: false,
|
|
1085
|
-
isRestArgument: false
|
|
1086
|
-
});
|
|
1087
|
-
chai_1.expect(callable.params[1].type).instanceof(DynamicType_1.DynamicType);
|
|
1088
|
-
chai_1.expect(callable.params[2]).to.deep.include({
|
|
1089
|
-
name: 'c',
|
|
1090
|
-
isOptional: false,
|
|
1091
|
-
isRestArgument: false
|
|
1092
|
-
});
|
|
1093
|
-
chai_1.expect(callable.params[2].type).instanceof(DynamicType_1.DynamicType);
|
|
1094
|
-
});
|
|
1095
|
-
it('finds optional parameters', () => {
|
|
1096
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1097
|
-
file.parse(`
|
|
1098
|
-
function Sum(a=2)
|
|
1099
|
-
|
|
1100
|
-
end function
|
|
1101
|
-
`);
|
|
1102
|
-
let callable = file.callables[0];
|
|
1103
|
-
chai_1.expect(callable.params[0]).to.deep.include({
|
|
1104
|
-
name: 'a',
|
|
1105
|
-
isOptional: true,
|
|
1106
|
-
isRestArgument: false
|
|
1107
|
-
});
|
|
1108
|
-
chai_1.expect(callable.params[0].type).instanceof(IntegerType_1.IntegerType);
|
|
1109
|
-
});
|
|
1110
|
-
it('finds parameter types', () => {
|
|
1111
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1112
|
-
file.parse(`
|
|
1113
|
-
function Sum(a, b as integer, c as string)
|
|
1114
|
-
|
|
1115
|
-
end function
|
|
1116
|
-
`);
|
|
1117
|
-
let callable = file.callables[0];
|
|
1118
|
-
chai_1.expect(callable.params[0]).to.deep.include({
|
|
1119
|
-
name: 'a',
|
|
1120
|
-
isOptional: false,
|
|
1121
|
-
isRestArgument: false
|
|
1122
|
-
});
|
|
1123
|
-
chai_1.expect(callable.params[0].type).instanceof(DynamicType_1.DynamicType);
|
|
1124
|
-
chai_1.expect(callable.params[1]).to.deep.include({
|
|
1125
|
-
name: 'b',
|
|
1126
|
-
isOptional: false,
|
|
1127
|
-
isRestArgument: false
|
|
1128
|
-
});
|
|
1129
|
-
chai_1.expect(callable.params[1].type).instanceof(IntegerType_1.IntegerType);
|
|
1130
|
-
chai_1.expect(callable.params[2]).to.deep.include({
|
|
1131
|
-
name: 'c',
|
|
1132
|
-
isOptional: false,
|
|
1133
|
-
isRestArgument: false
|
|
1134
|
-
});
|
|
1135
|
-
chai_1.expect(callable.params[2].type).instanceof(StringType_1.StringType);
|
|
1136
|
-
});
|
|
1137
|
-
});
|
|
1138
|
-
describe('findCallableInvocations', () => {
|
|
1139
|
-
it('finds arguments with literal values', () => {
|
|
1140
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1141
|
-
file.parse(`
|
|
1142
|
-
function Sum()
|
|
1143
|
-
DoSomething("name", 12, true)
|
|
1144
|
-
end function
|
|
1145
|
-
`);
|
|
1146
|
-
chai_1.expect(file.functionCalls.length).to.equal(1);
|
|
1147
|
-
chai_1.expect(file.functionCalls[0].args).to.eql([{
|
|
1148
|
-
type: new StringType_1.StringType(),
|
|
1149
|
-
range: util_1.default.createRange(2, 32, 2, 38),
|
|
1150
|
-
text: '"name"'
|
|
1151
|
-
}, {
|
|
1152
|
-
type: new IntegerType_1.IntegerType(),
|
|
1153
|
-
range: util_1.default.createRange(2, 40, 2, 42),
|
|
1154
|
-
text: '12'
|
|
1155
|
-
}, {
|
|
1156
|
-
type: new BooleanType_1.BooleanType(),
|
|
1157
|
-
range: util_1.default.createRange(2, 44, 2, 48),
|
|
1158
|
-
text: 'true'
|
|
1159
|
-
}]);
|
|
1160
|
-
});
|
|
1161
|
-
it('finds function calls nested inside statements', () => {
|
|
1162
|
-
var _a;
|
|
1163
|
-
program.setFile(`source/main.brs`, `
|
|
1164
|
-
sub main()
|
|
1165
|
-
if true then
|
|
1166
|
-
DoesNotExist(1, 2)
|
|
1167
|
-
end if
|
|
1168
|
-
end sub
|
|
1169
|
-
`);
|
|
1170
|
-
program.validate();
|
|
1171
|
-
chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.callToUnknownFunction('DoesNotExist', 'source').message);
|
|
1172
|
-
});
|
|
1173
|
-
it('finds arguments with variable values', () => {
|
|
1174
|
-
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
1175
|
-
file.parse(`
|
|
1176
|
-
function Sum()
|
|
1177
|
-
count = 1
|
|
1178
|
-
name = "John"
|
|
1179
|
-
isAlive = true
|
|
1180
|
-
DoSomething(count, name, isAlive)
|
|
1181
|
-
end function
|
|
1182
|
-
`);
|
|
1183
|
-
chai_1.expect(file.functionCalls.length).to.equal(1);
|
|
1184
|
-
chai_1.expect(file.functionCalls[0].args[0]).deep.include({
|
|
1185
|
-
type: new DynamicType_1.DynamicType(),
|
|
1186
|
-
text: 'count'
|
|
1187
|
-
});
|
|
1188
|
-
chai_1.expect(file.functionCalls[0].args[1]).deep.include({
|
|
1189
|
-
type: new DynamicType_1.DynamicType(),
|
|
1190
|
-
text: 'name'
|
|
1191
|
-
});
|
|
1192
|
-
chai_1.expect(file.functionCalls[0].args[2]).deep.include({
|
|
1193
|
-
type: new DynamicType_1.DynamicType(),
|
|
1194
|
-
text: 'isAlive'
|
|
1195
|
-
});
|
|
1196
|
-
});
|
|
1197
|
-
});
|
|
1198
|
-
describe('findCallables', () => {
|
|
1199
|
-
//this test is to help with code coverage
|
|
1200
|
-
it('skips top-level statements', () => {
|
|
1201
|
-
let file = new BrsFile_1.BrsFile('absolute', 'relative', program);
|
|
1202
|
-
file.parse('name = "Bob"');
|
|
1203
|
-
chai_1.expect(file.callables.length).to.equal(0);
|
|
1204
|
-
});
|
|
1205
|
-
it('finds return type', () => {
|
|
1206
|
-
let file = program.setFile('source/main.brs', `
|
|
1207
|
-
function DoSomething() as string
|
|
1208
|
-
end function
|
|
1209
|
-
`);
|
|
1210
|
-
chai_1.expect(file.callables[0]).to.deep.include({
|
|
1211
|
-
file: file,
|
|
1212
|
-
nameRange: vscode_languageserver_1.Range.create(1, 25, 1, 36),
|
|
1213
|
-
name: 'DoSomething',
|
|
1214
|
-
params: []
|
|
1215
|
-
});
|
|
1216
|
-
chai_1.expect(file.callables[0].type.returnType).instanceof(StringType_1.StringType);
|
|
1217
|
-
});
|
|
1218
|
-
});
|
|
1219
|
-
describe('function local variable handling', () => {
|
|
1220
|
-
it('creates range properly', () => {
|
|
1221
|
-
file.parse(`
|
|
1222
|
-
sub Main()
|
|
1223
|
-
name = 'bob"
|
|
1224
|
-
end sub
|
|
1225
|
-
`);
|
|
1226
|
-
chai_1.expect(file.parser.references.functionStatements[0].range).to.eql(vscode_languageserver_1.Range.create(1, 16, 3, 23));
|
|
1227
|
-
});
|
|
1228
|
-
it('creates scopes for parent and child functions', () => {
|
|
1229
|
-
file.parse(`
|
|
1230
|
-
sub Main()
|
|
1231
|
-
sayHi = sub()
|
|
1232
|
-
print "hi"
|
|
1233
|
-
end sub
|
|
1234
|
-
|
|
1235
|
-
scheduleJob(sub()
|
|
1236
|
-
print "job completed"
|
|
1237
|
-
end sub)
|
|
1238
|
-
end sub
|
|
1239
|
-
`);
|
|
1240
|
-
chai_1.expect(file.parser.references.functionExpressions).to.be.length(3);
|
|
1241
|
-
});
|
|
1242
|
-
it('finds variables declared in function expressions', () => {
|
|
1243
|
-
file.parse(`
|
|
1244
|
-
sub Main()
|
|
1245
|
-
sayHi = sub()
|
|
1246
|
-
age = 12
|
|
1247
|
-
end sub
|
|
1248
|
-
|
|
1249
|
-
scheduleJob(sub()
|
|
1250
|
-
name = "bob"
|
|
1251
|
-
end sub)
|
|
1252
|
-
end sub
|
|
1253
|
-
`);
|
|
1254
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1255
|
-
['sayHi', new FunctionType_1.FunctionType(new VoidType_1.VoidType(), true), util_1.default.createRange(2, 20, 2, 25)]
|
|
1256
|
-
]);
|
|
1257
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[1].symbolTable, [
|
|
1258
|
-
['age', new IntegerType_1.IntegerType(), util_1.default.createRange(3, 24, 3, 27)]
|
|
1259
|
-
]);
|
|
1260
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[2].symbolTable, [
|
|
1261
|
-
['name', new StringType_1.StringType(), util_1.default.createRange(7, 24, 7, 28)]
|
|
1262
|
-
]);
|
|
1263
|
-
});
|
|
1264
|
-
it('finds variable declarations inside of if statements', () => {
|
|
1265
|
-
file.parse(`
|
|
1266
|
-
sub Main()
|
|
1267
|
-
if true then
|
|
1268
|
-
theLength = 1
|
|
1269
|
-
end if
|
|
1270
|
-
end sub
|
|
1271
|
-
`);
|
|
1272
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1273
|
-
['theLength', new IntegerType_1.IntegerType(), util_1.default.createRange(3, 24, 3, 33)]
|
|
1274
|
-
]);
|
|
1275
|
-
});
|
|
1276
|
-
it('finds value from global return', () => {
|
|
1277
|
-
let file = program.setFile('source/main.brs', `
|
|
1278
|
-
sub Main()
|
|
1279
|
-
myName = GetName()
|
|
1280
|
-
end sub
|
|
1281
|
-
|
|
1282
|
-
function GetName() as string
|
|
1283
|
-
return "bob"
|
|
1284
|
-
end function
|
|
1285
|
-
`);
|
|
1286
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1287
|
-
['myName', new StringType_1.StringType(), util_1.default.createRange(2, 19, 2, 25)]
|
|
1288
|
-
]);
|
|
1289
|
-
});
|
|
1290
|
-
it('finds variable type from other variable', () => {
|
|
1291
|
-
file.parse(`
|
|
1292
|
-
sub Main()
|
|
1293
|
-
name = "bob"
|
|
1294
|
-
nameCopy = name
|
|
1295
|
-
end sub
|
|
1296
|
-
`);
|
|
1297
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1298
|
-
['name', new StringType_1.StringType(), util_1.default.createRange(2, 19, 2, 23)],
|
|
1299
|
-
['nameCopy', new StringType_1.StringType(), util_1.default.createRange(3, 19, 3, 27)]
|
|
1300
|
-
]);
|
|
1301
|
-
});
|
|
1302
|
-
it('sets proper range for functions', () => {
|
|
1303
|
-
file.parse(`
|
|
1304
|
-
sub Main()
|
|
1305
|
-
getName = function()
|
|
1306
|
-
return "bob"
|
|
1307
|
-
end function
|
|
1308
|
-
end sub
|
|
1309
|
-
`);
|
|
1310
|
-
chai_1.expect(file.parser.references.functionExpressions).to.be.length(2);
|
|
1311
|
-
chai_1.expect(file.parser.references.functionExpressions.map(x => x.range)).to.eql([
|
|
1312
|
-
util_1.default.createRange(1, 16, 5, 23),
|
|
1313
|
-
util_1.default.createRange(2, 30, 4, 32)
|
|
1314
|
-
]);
|
|
1315
|
-
});
|
|
1316
|
-
});
|
|
1317
|
-
describe('getHover', () => {
|
|
1318
|
-
it('works for param types', () => {
|
|
1319
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1320
|
-
sub DoSomething(name as string)
|
|
1321
|
-
name = 1
|
|
1322
|
-
sayMyName = function(name as string)
|
|
1323
|
-
end function
|
|
1324
|
-
end sub
|
|
1325
|
-
`);
|
|
1326
|
-
//hover over the `name = 1` line
|
|
1327
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(2, 24));
|
|
1328
|
-
chai_1.expect(hover).to.exist;
|
|
1329
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 24));
|
|
1330
|
-
//hover over the `name` parameter declaration
|
|
1331
|
-
hover = file.getHover(vscode_languageserver_1.Position.create(1, 34));
|
|
1332
|
-
chai_1.expect(hover).to.exist;
|
|
1333
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 32, 1, 36));
|
|
1334
|
-
});
|
|
1335
|
-
//ignore this for now...it's not a huge deal
|
|
1336
|
-
it('does not match on keywords or data types', () => {
|
|
1337
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1338
|
-
sub Main(name as string)
|
|
1339
|
-
end sub
|
|
1340
|
-
sub as()
|
|
1341
|
-
end sub
|
|
1342
|
-
`);
|
|
1343
|
-
//hover over the `as`
|
|
1344
|
-
chai_1.expect(file.getHover(vscode_languageserver_1.Position.create(1, 31))).not.to.exist;
|
|
1345
|
-
//hover over the `string`
|
|
1346
|
-
chai_1.expect(file.getHover(vscode_languageserver_1.Position.create(1, 36))).not.to.exist;
|
|
1347
|
-
});
|
|
1348
|
-
it('finds declared function', () => {
|
|
1349
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1350
|
-
function Main(count = 1)
|
|
1351
|
-
firstName = "bob"
|
|
1352
|
-
age = 21
|
|
1353
|
-
shoeSize = 10
|
|
1354
|
-
end function
|
|
1355
|
-
`);
|
|
1356
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(1, 28));
|
|
1357
|
-
chai_1.expect(hover).to.exist;
|
|
1358
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 29));
|
|
1359
|
-
chai_1.expect(hover.contents).to.equal('function Main(count? as integer) as dynamic');
|
|
1360
|
-
});
|
|
1361
|
-
it('finds variable function hover in same scope', () => {
|
|
1362
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1363
|
-
sub Main()
|
|
1364
|
-
sayMyName = sub(name as string)
|
|
1365
|
-
end sub
|
|
1366
|
-
|
|
1367
|
-
sayMyName()
|
|
1368
|
-
end sub
|
|
1369
|
-
`);
|
|
1370
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(5, 24));
|
|
1371
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 29));
|
|
1372
|
-
chai_1.expect(hover.contents).to.equal('sub (name as string) as void');
|
|
1373
|
-
});
|
|
1374
|
-
it('finds function hover in file scope', () => {
|
|
1375
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1376
|
-
sub Main()
|
|
1377
|
-
sayMyName()
|
|
1378
|
-
end sub
|
|
1379
|
-
|
|
1380
|
-
sub sayMyName()
|
|
1381
|
-
|
|
1382
|
-
end sub
|
|
1383
|
-
`);
|
|
1384
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(2, 25));
|
|
1385
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1386
|
-
chai_1.expect(hover.contents).to.equal('sub sayMyName() as void');
|
|
1387
|
-
});
|
|
1388
|
-
it('finds function hover in scope', () => {
|
|
1389
|
-
let rootDir = process.cwd();
|
|
1390
|
-
program = new Program_1.Program({
|
|
1391
|
-
rootDir: rootDir
|
|
1392
|
-
});
|
|
1393
|
-
let mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1394
|
-
sub Main()
|
|
1395
|
-
sayMyName()
|
|
1396
|
-
end sub
|
|
1397
|
-
`);
|
|
1398
|
-
program.setFile({ src: `${rootDir}/source/lib.brs`, dest: 'source/lib.brs' }, `
|
|
1399
|
-
sub sayMyName(name as string)
|
|
1400
|
-
|
|
1401
|
-
end sub
|
|
1402
|
-
`);
|
|
1403
|
-
let hover = mainFile.getHover(vscode_languageserver_1.Position.create(2, 25));
|
|
1404
|
-
chai_1.expect(hover).to.exist;
|
|
1405
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1406
|
-
chai_1.expect(hover.contents).to.equal('sub sayMyName(name as string) as void');
|
|
1407
|
-
});
|
|
1408
|
-
it('handles mixed case `then` partions of conditionals', () => {
|
|
1409
|
-
let mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1410
|
-
sub Main()
|
|
1411
|
-
if true then
|
|
1412
|
-
print "works"
|
|
1413
|
-
end if
|
|
1414
|
-
end sub
|
|
1415
|
-
`);
|
|
1416
|
-
chai_1.expect(mainFile.getDiagnostics()).to.be.lengthOf(0);
|
|
1417
|
-
mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1418
|
-
sub Main()
|
|
1419
|
-
if true Then
|
|
1420
|
-
print "works"
|
|
1421
|
-
end if
|
|
1422
|
-
end sub
|
|
1423
|
-
`);
|
|
1424
|
-
chai_1.expect(mainFile.getDiagnostics()).to.be.lengthOf(0);
|
|
1425
|
-
mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1426
|
-
sub Main()
|
|
1427
|
-
if true THEN
|
|
1428
|
-
print "works"
|
|
1429
|
-
end if
|
|
1430
|
-
end sub
|
|
1431
|
-
`);
|
|
1432
|
-
chai_1.expect(mainFile.getDiagnostics()).to.be.lengthOf(0);
|
|
1433
|
-
});
|
|
1434
|
-
it('displays the context from multiple scopes', () => {
|
|
1435
|
-
let commonFile = program.setFile('source/common.brs', `
|
|
1436
|
-
sub displayPi()
|
|
1437
|
-
pi = getPi()
|
|
1438
|
-
print pi
|
|
1439
|
-
end sub
|
|
1440
|
-
`);
|
|
1441
|
-
let scope1File = program.setFile('components/comp1/scope1.brs', `
|
|
1442
|
-
function getPi() as string
|
|
1443
|
-
return "apple"
|
|
1444
|
-
end function
|
|
1445
|
-
`);
|
|
1446
|
-
chai_1.expect(scope1File.getDiagnostics()).to.be.lengthOf(0);
|
|
1447
|
-
program.setFile('components/comp1/comp1.xml', testHelpers_spec_1.trim `
|
|
1448
|
-
<?xml version="1.0" encoding="utf-8" ?>
|
|
1449
|
-
<component name="Component1" extends="Group">
|
|
1450
|
-
<script type="text/brightscript" uri="scope1.brs" />
|
|
1451
|
-
<script type="text/brightscript" uri="pkg:/source/common.brs" />
|
|
1452
|
-
</component>
|
|
1453
|
-
`);
|
|
1454
|
-
let scope2File = program.setFile('components/comp2/scope2.brs', `
|
|
1455
|
-
function getPi() as float
|
|
1456
|
-
return 3.14
|
|
1457
|
-
end function
|
|
1458
|
-
`);
|
|
1459
|
-
chai_1.expect(scope2File.getDiagnostics()).to.be.lengthOf(0);
|
|
1460
|
-
program.setFile('components/comp2/comp2.xml', testHelpers_spec_1.trim `
|
|
1461
|
-
<?xml version="1.0" encoding="utf-8" ?>
|
|
1462
|
-
<component name="Component2" extends="Group">
|
|
1463
|
-
<script type="text/brightscript" uri="scope2.brs" />
|
|
1464
|
-
<script type="text/brightscript" uri="pkg:/source/common.brs" />
|
|
1465
|
-
</component>
|
|
1466
|
-
`);
|
|
1467
|
-
program.validate();
|
|
1468
|
-
let funcCallHover = commonFile.getHover(vscode_languageserver_1.Position.create(2, 27));
|
|
1469
|
-
chai_1.expect(funcCallHover).to.exist;
|
|
1470
|
-
chai_1.expect(funcCallHover.contents).to.equal('function getPi() as string | function getPi() as float');
|
|
1471
|
-
let variableHover = commonFile.getHover(vscode_languageserver_1.Position.create(3, 27));
|
|
1472
|
-
chai_1.expect(variableHover).to.exist;
|
|
1473
|
-
chai_1.expect(variableHover.contents).to.equal('pi as uninitialized | pi as string | pi as float');
|
|
1474
|
-
});
|
|
1475
|
-
});
|
|
1476
|
-
it('does not throw when encountering incomplete import statement', () => {
|
|
1477
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1478
|
-
import
|
|
1479
|
-
sub main()
|
|
1480
|
-
end sub
|
|
1481
|
-
`);
|
|
1482
|
-
program.validate();
|
|
1483
|
-
//this test will throw an exception if something went wrong
|
|
1484
|
-
});
|
|
1485
|
-
describe('transpile', () => {
|
|
1486
|
-
describe('throwStatement', () => {
|
|
1487
|
-
it('transpiles properly', () => {
|
|
1488
|
-
testTranspile(`
|
|
1489
|
-
sub main()
|
|
1490
|
-
try
|
|
1491
|
-
throw "some message"
|
|
1492
|
-
catch e
|
|
1493
|
-
end try
|
|
1494
|
-
end sub
|
|
1495
|
-
`);
|
|
1496
|
-
});
|
|
1497
|
-
});
|
|
1498
|
-
describe('try/catch', () => {
|
|
1499
|
-
it('transpiles properly', () => {
|
|
1500
|
-
testTranspile(`
|
|
1501
|
-
sub main()
|
|
1502
|
-
try
|
|
1503
|
-
print a.b.c
|
|
1504
|
-
catch e
|
|
1505
|
-
print e
|
|
1506
|
-
end try
|
|
1507
|
-
end sub
|
|
1508
|
-
`);
|
|
1509
|
-
});
|
|
1510
|
-
});
|
|
1511
|
-
describe('namespaces', () => {
|
|
1512
|
-
it('properly transpiles namespace functions for assignments', () => {
|
|
1513
|
-
testTranspile(`
|
|
1514
|
-
namespace NameA.NameB
|
|
1515
|
-
sub Speak()
|
|
1516
|
-
end sub
|
|
1517
|
-
end namespace
|
|
1518
|
-
sub main()
|
|
1519
|
-
sayHello = NameA.NameB.Speak
|
|
1520
|
-
sayHello()
|
|
1521
|
-
someOtherObject = some.other.object
|
|
1522
|
-
end sub
|
|
1523
|
-
`, `
|
|
1524
|
-
sub NameA_NameB_Speak()
|
|
1525
|
-
end sub
|
|
1526
|
-
|
|
1527
|
-
sub main()
|
|
1528
|
-
sayHello = NameA_NameB_Speak
|
|
1529
|
-
sayHello()
|
|
1530
|
-
someOtherObject = some.other.object
|
|
1531
|
-
end sub
|
|
1532
|
-
`);
|
|
1533
|
-
});
|
|
1534
|
-
it('properly transpiles inferred namespace function for assignment', () => {
|
|
1535
|
-
testTranspile(`
|
|
1536
|
-
namespace NameA.NameB
|
|
1537
|
-
sub Speak()
|
|
1538
|
-
end sub
|
|
1539
|
-
sub main()
|
|
1540
|
-
sayHello = Speak
|
|
1541
|
-
sayHello()
|
|
1542
|
-
end sub
|
|
1543
|
-
end namespace
|
|
1544
|
-
`, `
|
|
1545
|
-
sub NameA_NameB_Speak()
|
|
1546
|
-
end sub
|
|
1547
|
-
|
|
1548
|
-
sub NameA_NameB_main()
|
|
1549
|
-
sayHello = NameA_NameB_Speak
|
|
1550
|
-
sayHello()
|
|
1551
|
-
end sub
|
|
1552
|
-
`);
|
|
1553
|
-
});
|
|
1554
|
-
});
|
|
1555
|
-
it('includes all text to end of line for a non-terminated string', () => {
|
|
1556
|
-
testTranspile('sub main()\n name = "john \nend sub', 'sub main()\n name = "john "\nend sub', null, 'source/main.bs', false);
|
|
1557
|
-
});
|
|
1558
|
-
it('escapes quotes in string literals', () => {
|
|
1559
|
-
testTranspile(`
|
|
1560
|
-
sub main()
|
|
1561
|
-
expected += chr(10) + " version=""2.0"""
|
|
1562
|
-
end sub
|
|
1563
|
-
`);
|
|
1564
|
-
});
|
|
1565
|
-
it('keeps function parameter types in proper order', () => {
|
|
1566
|
-
testTranspile(`
|
|
1567
|
-
function CreateTestStatistic(name as string, result = "Success" as string, time = 0 as integer, errorCode = 0 as integer, errorMessage = "" as string) as object
|
|
1568
|
-
end function
|
|
1569
|
-
`);
|
|
1570
|
-
});
|
|
1571
|
-
it('transpiles local var assignment operators', () => {
|
|
1572
|
-
testTranspile(`
|
|
1573
|
-
sub main()
|
|
1574
|
-
count = 0
|
|
1575
|
-
count += 1
|
|
1576
|
-
count -= 1
|
|
1577
|
-
count *= 1
|
|
1578
|
-
count /= 1
|
|
1579
|
-
count \\= 1
|
|
1580
|
-
count <<= 1
|
|
1581
|
-
count >>= 1
|
|
1582
|
-
end sub
|
|
1583
|
-
`);
|
|
1584
|
-
});
|
|
1585
|
-
it('transpiles AA property assignment operators', () => {
|
|
1586
|
-
testTranspile(`
|
|
1587
|
-
sub main()
|
|
1588
|
-
person = {
|
|
1589
|
-
count: 0
|
|
1590
|
-
}
|
|
1591
|
-
person.count += 1
|
|
1592
|
-
end sub
|
|
1593
|
-
`);
|
|
1594
|
-
});
|
|
1595
|
-
it('transpiles AA indexed assignment operators', () => {
|
|
1596
|
-
testTranspile(`
|
|
1597
|
-
sub main()
|
|
1598
|
-
person = {
|
|
1599
|
-
count: 0
|
|
1600
|
-
}
|
|
1601
|
-
person["count"] += 1
|
|
1602
|
-
end sub
|
|
1603
|
-
`);
|
|
1604
|
-
});
|
|
1605
|
-
it('relative-referenced namespaced functions get prefixed', () => {
|
|
1606
|
-
testTranspile(`
|
|
1607
|
-
namespace Vertibrates.Birds
|
|
1608
|
-
function GetAllBirds()
|
|
1609
|
-
return [
|
|
1610
|
-
GetDuck(),
|
|
1611
|
-
GetGoose()
|
|
1612
|
-
]
|
|
1613
|
-
end function
|
|
1614
|
-
|
|
1615
|
-
function GetDuck()
|
|
1616
|
-
end function
|
|
1617
|
-
|
|
1618
|
-
function GetGoose()
|
|
1619
|
-
end function
|
|
1620
|
-
end namespace
|
|
1621
|
-
`, `
|
|
1622
|
-
function Vertibrates_Birds_GetAllBirds()
|
|
1623
|
-
return [
|
|
1624
|
-
Vertibrates_Birds_GetDuck(),
|
|
1625
|
-
Vertibrates_Birds_GetGoose()
|
|
1626
|
-
]
|
|
1627
|
-
end function
|
|
1628
|
-
|
|
1629
|
-
function Vertibrates_Birds_GetDuck()
|
|
1630
|
-
end function
|
|
1631
|
-
|
|
1632
|
-
function Vertibrates_Birds_GetGoose()
|
|
1633
|
-
end function
|
|
1634
|
-
`, 'trim', 'source/main.bs');
|
|
1635
|
-
});
|
|
1636
|
-
it('transpiles namespaced functions', () => {
|
|
1637
|
-
testTranspile(`
|
|
1638
|
-
namespace NameA
|
|
1639
|
-
sub alert()
|
|
1640
|
-
end sub
|
|
1641
|
-
end namespace
|
|
1642
|
-
namespace NameA.NameB
|
|
1643
|
-
sub alert()
|
|
1644
|
-
end sub
|
|
1645
|
-
end namespace
|
|
1646
|
-
`, `
|
|
1647
|
-
sub NameA_alert()
|
|
1648
|
-
end sub
|
|
1649
|
-
sub NameA_NameB_alert()
|
|
1650
|
-
end sub
|
|
1651
|
-
`, 'trim', 'source/main.bs');
|
|
1652
|
-
});
|
|
1653
|
-
it('transpiles dim', () => {
|
|
1654
|
-
testTranspile(`Dim c[5]`, `Dim c[5]`);
|
|
1655
|
-
testTranspile(`Dim c[5, 4]`, `Dim c[5, 4]`);
|
|
1656
|
-
testTranspile(`Dim c[5, 4, 6]`, `Dim c[5, 4, 6]`);
|
|
1657
|
-
testTranspile(`Dim requestData[requestList.count()]`, `Dim requestData[requestList.count()]`);
|
|
1658
|
-
testTranspile(`Dim requestData[1, requestList.count()]`, `Dim requestData[1, requestList.count()]`);
|
|
1659
|
-
testTranspile(`Dim requestData[1, requestList.count(), 2]`, `Dim requestData[1, requestList.count(), 2]`);
|
|
1660
|
-
testTranspile(`Dim requestData[requestList[2]]`, `Dim requestData[requestList[2]]`);
|
|
1661
|
-
testTranspile(`Dim requestData[1, requestList[2]]`, `Dim requestData[1, requestList[2]]`);
|
|
1662
|
-
testTranspile(`Dim requestData[1, requestList[2], 2]`, `Dim requestData[1, requestList[2], 2]`);
|
|
1663
|
-
testTranspile(`Dim requestData[requestList["2"]]`, `Dim requestData[requestList["2"]]`);
|
|
1664
|
-
testTranspile(`Dim requestData[1, requestList["2"]]`, `Dim requestData[1, requestList["2"]]`);
|
|
1665
|
-
testTranspile(`Dim requestData[1, requestList["2"], 2]`, `Dim requestData[1, requestList["2"], 2]`);
|
|
1666
|
-
testTranspile(`Dim requestData[1, getValue(), 2]`, `Dim requestData[1, getValue(), 2]`);
|
|
1667
|
-
testTranspile(`
|
|
1668
|
-
Dim requestData[1, getValue({
|
|
1669
|
-
key: "value"
|
|
1670
|
-
}), 2]
|
|
1671
|
-
`, `
|
|
1672
|
-
Dim requestData[1, getValue({
|
|
1673
|
-
key: "value"
|
|
1674
|
-
}), 2]
|
|
1675
|
-
`);
|
|
1676
|
-
});
|
|
1677
|
-
it('transpiles calls to fully-qualified namespaced functions', () => {
|
|
1678
|
-
testTranspile(`
|
|
1679
|
-
namespace NameA
|
|
1680
|
-
sub alert()
|
|
1681
|
-
end sub
|
|
1682
|
-
end namespace
|
|
1683
|
-
namespace NameA.NameB
|
|
1684
|
-
sub alert()
|
|
1685
|
-
end sub
|
|
1686
|
-
end namespace
|
|
1687
|
-
sub main()
|
|
1688
|
-
NameA.alert()
|
|
1689
|
-
NameA.NameB.alert()
|
|
1690
|
-
end sub
|
|
1691
|
-
`, `
|
|
1692
|
-
sub NameA_alert()
|
|
1693
|
-
end sub
|
|
1694
|
-
sub NameA_NameB_alert()
|
|
1695
|
-
end sub
|
|
1696
|
-
|
|
1697
|
-
sub main()
|
|
1698
|
-
NameA_alert()
|
|
1699
|
-
NameA_NameB_alert()
|
|
1700
|
-
end sub
|
|
1701
|
-
`, 'trim', 'source/main.bs');
|
|
1702
|
-
});
|
|
1703
|
-
it('keeps end-of-line comments with their line', () => {
|
|
1704
|
-
testTranspile(`
|
|
1705
|
-
function DoSomething() 'comment 1
|
|
1706
|
-
name = "bob" 'comment 2
|
|
1707
|
-
end function 'comment 3
|
|
1708
|
-
`);
|
|
1709
|
-
});
|
|
1710
|
-
it('works for functions', () => {
|
|
1711
|
-
testTranspile(`
|
|
1712
|
-
function DoSomething()
|
|
1713
|
-
'lots of empty white space
|
|
1714
|
-
'that will be removed during transpile
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
end function
|
|
1719
|
-
`, `
|
|
1720
|
-
function DoSomething()
|
|
1721
|
-
'lots of empty white space
|
|
1722
|
-
'that will be removed during transpile
|
|
1723
|
-
end function
|
|
1724
|
-
`);
|
|
1725
|
-
});
|
|
1726
|
-
it('keeps empty AAs and arrays on same line', () => {
|
|
1727
|
-
testTranspile(`
|
|
1728
|
-
sub a()
|
|
1729
|
-
person = {}
|
|
1730
|
-
stuff = []
|
|
1731
|
-
end sub
|
|
1732
|
-
`, null, 'trim');
|
|
1733
|
-
});
|
|
1734
|
-
it('adds `then` when missing', () => {
|
|
1735
|
-
testTranspile(`
|
|
1736
|
-
sub a()
|
|
1737
|
-
if true
|
|
1738
|
-
print "true"
|
|
1739
|
-
else if true
|
|
1740
|
-
print "true"
|
|
1741
|
-
else
|
|
1742
|
-
print "true"
|
|
1743
|
-
end if
|
|
1744
|
-
end sub
|
|
1745
|
-
`, `
|
|
1746
|
-
sub a()
|
|
1747
|
-
if true then
|
|
1748
|
-
print "true"
|
|
1749
|
-
else if true then
|
|
1750
|
-
print "true"
|
|
1751
|
-
else
|
|
1752
|
-
print "true"
|
|
1753
|
-
end if
|
|
1754
|
-
end sub
|
|
1755
|
-
`, 'trim');
|
|
1756
|
-
});
|
|
1757
|
-
it('does not add leading or trailing newlines', () => {
|
|
1758
|
-
testTranspile(`function abc()\nend function`, undefined, 'none');
|
|
1759
|
-
});
|
|
1760
|
-
it('handles sourcemap edge case', async () => {
|
|
1761
|
-
let source = 'sub main()\n' +
|
|
1762
|
-
'\n' +
|
|
1763
|
-
' print 1\n' +
|
|
1764
|
-
'\n' +
|
|
1765
|
-
'end sub';
|
|
1766
|
-
program.options.sourceMap = true;
|
|
1767
|
-
let result = testTranspile(source, `sub main()\n print 1\nend sub`, 'none', 'source/main.bs');
|
|
1768
|
-
//load the source map
|
|
1769
|
-
let location = await source_map_1.SourceMapConsumer.with(result.map.toJSON(), null, (consumer) => {
|
|
1770
|
-
return consumer.generatedPositionFor({
|
|
1771
|
-
line: 3,
|
|
1772
|
-
column: 0,
|
|
1773
|
-
source: util_1.standardizePath `${rootDir}/source/main.bs`,
|
|
1774
|
-
bias: source_map_1.SourceMapConsumer.LEAST_UPPER_BOUND
|
|
1775
|
-
});
|
|
1776
|
-
});
|
|
1777
|
-
chai_1.expect(location.line).to.eql(2);
|
|
1778
|
-
chai_1.expect(location.column).eql(4);
|
|
1779
|
-
});
|
|
1780
|
-
it('computes correct locations for sourcemap', async () => {
|
|
1781
|
-
let source = `function abc(name)\n firstName = name\nend function`;
|
|
1782
|
-
let tokens = lexer_1.Lexer.scan(source).tokens
|
|
1783
|
-
//remove newlines and EOF
|
|
1784
|
-
.filter(x => x.kind !== lexer_1.TokenKind.Eof && x.kind !== lexer_1.TokenKind.Newline);
|
|
1785
|
-
program.options.sourceMap = true;
|
|
1786
|
-
let result = testTranspile(source, source, 'none');
|
|
1787
|
-
//load the source map
|
|
1788
|
-
await source_map_1.SourceMapConsumer.with(result.map.toString(), null, (consumer) => {
|
|
1789
|
-
let tokenResult = tokens.map(token => ({
|
|
1790
|
-
kind: token.kind,
|
|
1791
|
-
start: token.range.start
|
|
1792
|
-
}));
|
|
1793
|
-
let sourcemapResult = tokens.map(token => {
|
|
1794
|
-
let originalPosition = consumer.originalPositionFor({
|
|
1795
|
-
//convert token 0-based line to source-map 1-based line for the lookup
|
|
1796
|
-
line: token.range.start.line + 1,
|
|
1797
|
-
column: token.range.start.character
|
|
1798
|
-
});
|
|
1799
|
-
return {
|
|
1800
|
-
kind: token.kind,
|
|
1801
|
-
start: vscode_languageserver_1.Position.create(
|
|
1802
|
-
//convert source-map 1-based line to token 0-based line
|
|
1803
|
-
originalPosition.line - 1, originalPosition.column)
|
|
1804
|
-
};
|
|
1805
|
-
});
|
|
1806
|
-
chai_1.expect(sourcemapResult).to.eql(tokenResult);
|
|
1807
|
-
});
|
|
1808
|
-
});
|
|
1809
|
-
it('handles empty if block', () => {
|
|
1810
|
-
testTranspile(`
|
|
1811
|
-
if true then
|
|
1812
|
-
end if
|
|
1813
|
-
if true then
|
|
1814
|
-
else
|
|
1815
|
-
print "else"
|
|
1816
|
-
end if
|
|
1817
|
-
if true then
|
|
1818
|
-
else if true then
|
|
1819
|
-
print "else"
|
|
1820
|
-
end if
|
|
1821
|
-
if true then
|
|
1822
|
-
else if true then
|
|
1823
|
-
print "elseif"
|
|
1824
|
-
else
|
|
1825
|
-
print "else"
|
|
1826
|
-
end if
|
|
1827
|
-
`);
|
|
1828
|
-
});
|
|
1829
|
-
it('handles empty elseif block', () => {
|
|
1830
|
-
testTranspile(`
|
|
1831
|
-
if true then
|
|
1832
|
-
print "if"
|
|
1833
|
-
else if true then
|
|
1834
|
-
end if
|
|
1835
|
-
if true then
|
|
1836
|
-
print "if"
|
|
1837
|
-
else if true then
|
|
1838
|
-
else if true then
|
|
1839
|
-
end if
|
|
1840
|
-
`);
|
|
1841
|
-
});
|
|
1842
|
-
it('handles empty else block', () => {
|
|
1843
|
-
testTranspile(`
|
|
1844
|
-
if true then
|
|
1845
|
-
print "if"
|
|
1846
|
-
else
|
|
1847
|
-
end if
|
|
1848
|
-
if true then
|
|
1849
|
-
print "if"
|
|
1850
|
-
else if true then
|
|
1851
|
-
print "elseif"
|
|
1852
|
-
else
|
|
1853
|
-
end if
|
|
1854
|
-
`);
|
|
1855
|
-
});
|
|
1856
|
-
it('works for function parameters', () => {
|
|
1857
|
-
testTranspile(`
|
|
1858
|
-
function DoSomething(name, age as integer, text as string)
|
|
1859
|
-
end function
|
|
1860
|
-
`, `
|
|
1861
|
-
function DoSomething(name, age as integer, text as string)
|
|
1862
|
-
end function
|
|
1863
|
-
`);
|
|
1864
|
-
});
|
|
1865
|
-
it('adds newlines between top-level statements', () => {
|
|
1866
|
-
testTranspile(`
|
|
1867
|
-
function a()
|
|
1868
|
-
end function
|
|
1869
|
-
|
|
1870
|
-
function b()
|
|
1871
|
-
end function
|
|
1872
|
-
`);
|
|
1873
|
-
});
|
|
1874
|
-
it('properly indents nested AA literals', () => {
|
|
1875
|
-
testTranspile(`
|
|
1876
|
-
sub doSomething()
|
|
1877
|
-
grandparent = {
|
|
1878
|
-
parent: {
|
|
1879
|
-
child: {
|
|
1880
|
-
grandchild: {
|
|
1881
|
-
name: "baby"
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
end sub
|
|
1887
|
-
`);
|
|
1888
|
-
});
|
|
1889
|
-
it('does not add comma after final object property even when comments are present', () => {
|
|
1890
|
-
testTranspile(`
|
|
1891
|
-
sub doSomething()
|
|
1892
|
-
person = {
|
|
1893
|
-
age: 12, 'comment
|
|
1894
|
-
name: "child"
|
|
1895
|
-
}
|
|
1896
|
-
person = {
|
|
1897
|
-
age: 12, 'comment
|
|
1898
|
-
name: "child" 'comment
|
|
1899
|
-
}
|
|
1900
|
-
person = {
|
|
1901
|
-
age: 12, 'comment
|
|
1902
|
-
name: "child"
|
|
1903
|
-
'comment
|
|
1904
|
-
}
|
|
1905
|
-
person = {
|
|
1906
|
-
age: 12, 'comment
|
|
1907
|
-
name: "child" 'comment
|
|
1908
|
-
'comment
|
|
1909
|
-
}
|
|
1910
|
-
end sub
|
|
1911
|
-
`);
|
|
1912
|
-
});
|
|
1913
|
-
it('works for a complex function with comments all over the place', () => {
|
|
1914
|
-
testTranspile(`
|
|
1915
|
-
'import some library
|
|
1916
|
-
library "v30/bslCore.brs" 'comment
|
|
1917
|
-
|
|
1918
|
-
'a function that does something
|
|
1919
|
-
function doSomething(age as integer, name = "bob") 'comment
|
|
1920
|
-
person = { 'comment
|
|
1921
|
-
name: "parent", 'comment
|
|
1922
|
-
"age": 12,
|
|
1923
|
-
'comment as whole line
|
|
1924
|
-
child: { 'comment
|
|
1925
|
-
name: "child" 'comment
|
|
1926
|
-
}
|
|
1927
|
-
}
|
|
1928
|
-
person.name = "john" 'comment
|
|
1929
|
-
person.child.name = "baby" 'comment
|
|
1930
|
-
person["name"] = person.child["name"] 'comment
|
|
1931
|
-
age = 12 + 2 'comment
|
|
1932
|
-
name = "tim" 'comment
|
|
1933
|
-
age = 12 'comment
|
|
1934
|
-
while true 'comment
|
|
1935
|
-
age = age + 1 'comment
|
|
1936
|
-
exit while 'comment
|
|
1937
|
-
end while 'comment
|
|
1938
|
-
while age < 12 or age < 15 'comment
|
|
1939
|
-
age++ 'comment
|
|
1940
|
-
exit while 'comment
|
|
1941
|
-
end while 'comment
|
|
1942
|
-
if true or 1 = 1 or name = "tim" then 'comment
|
|
1943
|
-
print false 'comment
|
|
1944
|
-
else if false or "cat" = "dog" or true then 'comment
|
|
1945
|
-
print "true" 'comment
|
|
1946
|
-
else 'comment
|
|
1947
|
-
print "else" 'comment
|
|
1948
|
-
end if 'comment
|
|
1949
|
-
someBool = (true or false) or ((true) or (false)) 'comment
|
|
1950
|
-
mylabel: 'comment
|
|
1951
|
-
goto mylabel 'comment
|
|
1952
|
-
age++ 'comment
|
|
1953
|
-
age-- 'comment
|
|
1954
|
-
end 'comment
|
|
1955
|
-
stop 'comment
|
|
1956
|
-
indexes = [ 'comment
|
|
1957
|
-
'comment on its own line
|
|
1958
|
-
1, 'comment
|
|
1959
|
-
2, 'comment
|
|
1960
|
-
3 'comment
|
|
1961
|
-
] 'comment
|
|
1962
|
-
firstIndex = indexes[0] 'comment
|
|
1963
|
-
for each idx in indxes 'comment
|
|
1964
|
-
indexes[idx] = idx + 1 'comment
|
|
1965
|
-
end for 'comment
|
|
1966
|
-
if not true then 'comment
|
|
1967
|
-
print "false" 'comment
|
|
1968
|
-
end if 'comment 'comment
|
|
1969
|
-
for i = 0 to 10 step 1 'comment
|
|
1970
|
-
name = "bob" 'comment
|
|
1971
|
-
age = 12 'comment
|
|
1972
|
-
exit for 'comment
|
|
1973
|
-
end for 'comment
|
|
1974
|
-
callback = function(name, age as integer, cb as Function) as integer 'comment
|
|
1975
|
-
returnValue = 12 'comment
|
|
1976
|
-
return returnValue 'comment
|
|
1977
|
-
end function 'comment
|
|
1978
|
-
print "a"; "b"; 3 'comment
|
|
1979
|
-
a(1, 2, 3) 'comment
|
|
1980
|
-
person.functionCall(1, 2, 3) 'comment
|
|
1981
|
-
if true then 'comment
|
|
1982
|
-
level = 1 'comment
|
|
1983
|
-
if false then 'comment
|
|
1984
|
-
level = 2 'comment
|
|
1985
|
-
if true or false then 'comment
|
|
1986
|
-
level = 3 'comment
|
|
1987
|
-
if false and true then 'comment
|
|
1988
|
-
level = 4 'comment
|
|
1989
|
-
end if 'comment
|
|
1990
|
-
end if 'comment
|
|
1991
|
-
end if 'comment
|
|
1992
|
-
end if 'comment
|
|
1993
|
-
end function
|
|
1994
|
-
|
|
1995
|
-
function a(p1, p2, p3) 'comment
|
|
1996
|
-
end function 'comment
|
|
1997
|
-
`);
|
|
1998
|
-
});
|
|
1999
|
-
it('simple mapped files include a reference to the source map', () => {
|
|
2000
|
-
let file = program.setFile('source/logger.brs', testHelpers_spec_1.trim `
|
|
2001
|
-
sub logInfo()
|
|
2002
|
-
end sub
|
|
2003
|
-
`);
|
|
2004
|
-
file.needsTranspiled = false;
|
|
2005
|
-
const { code } = file.transpile();
|
|
2006
|
-
chai_1.expect(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
|
|
2007
|
-
});
|
|
2008
|
-
it('AST generated files include a reference to the source map', () => {
|
|
2009
|
-
let file = program.setFile('source/logger.brs', testHelpers_spec_1.trim `
|
|
2010
|
-
sub logInfo()
|
|
2011
|
-
end sub
|
|
2012
|
-
`);
|
|
2013
|
-
file.needsTranspiled = true;
|
|
2014
|
-
const { code } = file.transpile();
|
|
2015
|
-
chai_1.expect(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
|
|
2016
|
-
});
|
|
2017
|
-
it('replaces custom types in parameter types and return types', () => {
|
|
2018
|
-
program.setFile('source/SomeKlass.bs', `
|
|
2019
|
-
class SomeKlass
|
|
2020
|
-
end class
|
|
2021
|
-
`);
|
|
2022
|
-
testTranspile(`
|
|
2023
|
-
function foo() as SomeKlass
|
|
2024
|
-
return new SomeKlass()
|
|
2025
|
-
end function
|
|
2026
|
-
|
|
2027
|
-
sub bar(obj as SomeKlass)
|
|
2028
|
-
end sub
|
|
2029
|
-
`, `
|
|
2030
|
-
function foo() as object
|
|
2031
|
-
return SomeKlass()
|
|
2032
|
-
end function
|
|
2033
|
-
|
|
2034
|
-
sub bar(obj as object)
|
|
2035
|
-
end sub
|
|
2036
|
-
`);
|
|
2037
|
-
});
|
|
2038
|
-
});
|
|
2039
|
-
describe('callfunc operator', () => {
|
|
2040
|
-
describe('transpile', () => {
|
|
2041
|
-
it('does not produce diagnostics', () => {
|
|
2042
|
-
var _a;
|
|
2043
|
-
program.setFile('source/main.bs', `
|
|
2044
|
-
sub main()
|
|
2045
|
-
someObject@.someFunction(paramObject.value)
|
|
2046
|
-
end sub
|
|
2047
|
-
`);
|
|
2048
|
-
program.validate();
|
|
2049
|
-
chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
2050
|
-
});
|
|
2051
|
-
it('sets invalid on empty callfunc', () => {
|
|
2052
|
-
testTranspile(`
|
|
2053
|
-
sub main()
|
|
2054
|
-
node@.doSomething()
|
|
2055
|
-
m.top.node@.doSomething()
|
|
2056
|
-
m.top.node@.doSomething(1)
|
|
2057
|
-
end sub
|
|
2058
|
-
`, `
|
|
2059
|
-
sub main()
|
|
2060
|
-
node.callfunc("doSomething", invalid)
|
|
2061
|
-
m.top.node.callfunc("doSomething", invalid)
|
|
2062
|
-
m.top.node.callfunc("doSomething", 1)
|
|
2063
|
-
end sub
|
|
2064
|
-
`);
|
|
2065
|
-
});
|
|
2066
|
-
it('includes original arguments', () => {
|
|
2067
|
-
testTranspile(`
|
|
2068
|
-
sub main()
|
|
2069
|
-
node@.doSomething(1, true, m.top.someVal)
|
|
2070
|
-
end sub
|
|
2071
|
-
`, `
|
|
2072
|
-
sub main()
|
|
2073
|
-
node.callfunc("doSomething", 1, true, m.top.someVal)
|
|
2074
|
-
end sub
|
|
2075
|
-
`);
|
|
2076
|
-
});
|
|
2077
|
-
});
|
|
2078
|
-
});
|
|
2079
|
-
describe('transform callback', () => {
|
|
2080
|
-
function parseFileWithCallback(ext, onParsed) {
|
|
2081
|
-
const rootDir = process.cwd();
|
|
2082
|
-
const program = new Program_1.Program({
|
|
2083
|
-
rootDir: rootDir
|
|
2084
|
-
});
|
|
2085
|
-
program.plugins.add({
|
|
2086
|
-
name: 'transform callback',
|
|
2087
|
-
afterFileParse: onParsed
|
|
2088
|
-
});
|
|
2089
|
-
file = program.setFile(`source/file.${ext}`, `
|
|
2090
|
-
sub Sum()
|
|
2091
|
-
print "hello world"
|
|
2092
|
-
end sub
|
|
2093
|
-
`);
|
|
2094
|
-
chai_1.expect(file.extension).to.equal(ext);
|
|
2095
|
-
return file;
|
|
2096
|
-
}
|
|
2097
|
-
it('called for BRS file', () => {
|
|
2098
|
-
const onParsed = sinon.spy();
|
|
2099
|
-
parseFileWithCallback('.brs', onParsed);
|
|
2100
|
-
chai_1.expect(onParsed.callCount).to.equal(1);
|
|
2101
|
-
});
|
|
2102
|
-
it('called for BS file', () => {
|
|
2103
|
-
const onParsed = sinon.spy();
|
|
2104
|
-
parseFileWithCallback('.bs', onParsed);
|
|
2105
|
-
chai_1.expect(onParsed.callCount).to.equal(1);
|
|
2106
|
-
});
|
|
2107
|
-
});
|
|
2108
|
-
describe('typedefKey', () => {
|
|
2109
|
-
it('works for .brs files', () => {
|
|
2110
|
-
chai_1.expect(util_1.standardizePath((program.setFile('source/main.brs', '')).typedefSrcPath)).to.equal(util_1.standardizePath `${rootDir.toLowerCase()}/source/main.d.bs`);
|
|
2111
|
-
});
|
|
2112
|
-
it('returns undefined for files that should not have a typedef', () => {
|
|
2113
|
-
chai_1.expect((program.setFile('source/main.bs', '')).typedefSrcPath).to.be.undefined;
|
|
2114
|
-
chai_1.expect((program.setFile('source/main.d.bs', '')).typedefSrcPath).to.be.undefined;
|
|
2115
|
-
const xmlFile = program.setFile('components/comp.xml', '');
|
|
2116
|
-
chai_1.expect(xmlFile.typedefSrcPath).to.be.undefined;
|
|
2117
|
-
});
|
|
2118
|
-
});
|
|
2119
|
-
describe('type definitions', () => {
|
|
2120
|
-
it('only exposes defined functions even if source has more', () => {
|
|
2121
|
-
//parse the .brs file first so it doesn't know about the typedef
|
|
2122
|
-
program.setFile('source/main.brs', `
|
|
2123
|
-
sub main()
|
|
2124
|
-
end sub
|
|
2125
|
-
sub speak()
|
|
2126
|
-
end sub
|
|
2127
|
-
`);
|
|
2128
|
-
program.setFile('source/main.d.bs', `
|
|
2129
|
-
sub main()
|
|
2130
|
-
end sub
|
|
2131
|
-
`);
|
|
2132
|
-
const sourceScope = program.getScopeByName('source');
|
|
2133
|
-
const functionNames = sourceScope.getAllCallables().map(x => x.callable.name);
|
|
2134
|
-
chai_1.expect(functionNames).to.include('main');
|
|
2135
|
-
chai_1.expect(functionNames).not.to.include('speak');
|
|
2136
|
-
});
|
|
2137
|
-
it('reacts to typedef file changes', () => {
|
|
2138
|
-
let file = program.setFile('source/main.brs', `
|
|
2139
|
-
sub main()
|
|
2140
|
-
end sub
|
|
2141
|
-
sub speak()
|
|
2142
|
-
end sub
|
|
2143
|
-
`);
|
|
2144
|
-
chai_1.expect(file.hasTypedef).to.be.false;
|
|
2145
|
-
chai_1.expect(file.typedefFile).not.to.exist;
|
|
2146
|
-
program.setFile('source/main.d.bs', `
|
|
2147
|
-
sub main()
|
|
2148
|
-
end sub
|
|
2149
|
-
`);
|
|
2150
|
-
chai_1.expect(file.hasTypedef).to.be.true;
|
|
2151
|
-
chai_1.expect(file.typedefFile).to.exist;
|
|
2152
|
-
//add replace file, does it still find the typedef
|
|
2153
|
-
file = program.setFile('source/main.brs', `
|
|
2154
|
-
sub main()
|
|
2155
|
-
end sub
|
|
2156
|
-
sub speak()
|
|
2157
|
-
end sub
|
|
2158
|
-
`);
|
|
2159
|
-
chai_1.expect(file.hasTypedef).to.be.true;
|
|
2160
|
-
chai_1.expect(file.typedefFile).to.exist;
|
|
2161
|
-
program.removeFile(util_1.standardizePath `${rootDir}/source/main.d.bs`);
|
|
2162
|
-
chai_1.expect(file.hasTypedef).to.be.false;
|
|
2163
|
-
chai_1.expect(file.typedefFile).not.to.exist;
|
|
2164
|
-
});
|
|
2165
|
-
});
|
|
2166
|
-
describe('typedef', () => {
|
|
2167
|
-
it('sets typedef path properly', () => {
|
|
2168
|
-
chai_1.expect((program.setFile('source/main1.brs', '')).typedefSrcPath).to.equal(util_1.standardizePath `${rootDir}/source/main1.d.bs`.toLowerCase());
|
|
2169
|
-
chai_1.expect((program.setFile('source/main2.d.bs', '')).typedefSrcPath).to.equal(undefined);
|
|
2170
|
-
chai_1.expect((program.setFile('source/main3.bs', '')).typedefSrcPath).to.equal(undefined);
|
|
2171
|
-
//works for dest with `.brs` extension
|
|
2172
|
-
chai_1.expect((program.setFile({ src: 'source/main4.bs', dest: 'source/main4.brs' }, '')).typedefSrcPath).to.equal(undefined);
|
|
2173
|
-
});
|
|
2174
|
-
it('does not link when missing from program', () => {
|
|
2175
|
-
const file = program.setFile('source/main.brs', ``);
|
|
2176
|
-
chai_1.expect(file.typedefFile).not.to.exist;
|
|
2177
|
-
});
|
|
2178
|
-
it('links typedef when added BEFORE .brs file', () => {
|
|
2179
|
-
const typedef = program.setFile('source/main.d.bs', ``);
|
|
2180
|
-
const file = program.setFile('source/main.brs', ``);
|
|
2181
|
-
chai_1.expect(file.typedefFile).to.equal(typedef);
|
|
2182
|
-
});
|
|
2183
|
-
it('links typedef when added AFTER .brs file', () => {
|
|
2184
|
-
const file = program.setFile('source/main.brs', ``);
|
|
2185
|
-
const typedef = program.setFile('source/main.d.bs', ``);
|
|
2186
|
-
chai_1.expect(file.typedefFile).to.eql(typedef);
|
|
2187
|
-
});
|
|
2188
|
-
it('removes typedef link when typedef is removed', () => {
|
|
2189
|
-
const typedef = program.setFile('source/main.d.bs', ``);
|
|
2190
|
-
const file = program.setFile('source/main.brs', ``);
|
|
2191
|
-
program.removeFile(typedef.srcPath);
|
|
2192
|
-
chai_1.expect(file.typedefFile).to.be.undefined;
|
|
2193
|
-
});
|
|
2194
|
-
});
|
|
2195
|
-
describe('getTypedef', () => {
|
|
2196
|
-
function testTypedef(original, expected) {
|
|
2197
|
-
let file = program.setFile('source/main.brs', original);
|
|
2198
|
-
chai_1.expect(file.getTypedef()).to.eql(expected);
|
|
2199
|
-
}
|
|
2200
|
-
it('includes namespace on extend class names', () => {
|
|
2201
|
-
testTypedef(`
|
|
2202
|
-
namespace AnimalKingdom
|
|
2203
|
-
class Bird
|
|
2204
|
-
end class
|
|
2205
|
-
class Duck extends Bird
|
|
2206
|
-
end class
|
|
2207
|
-
end namespace`, testHelpers_spec_1.trim `
|
|
2208
|
-
namespace AnimalKingdom
|
|
2209
|
-
class Bird
|
|
2210
|
-
end class
|
|
2211
|
-
class Duck extends AnimalKingdom.Bird
|
|
2212
|
-
end class
|
|
2213
|
-
end namespace
|
|
2214
|
-
`);
|
|
2215
|
-
});
|
|
2216
|
-
it('strips function body', () => {
|
|
2217
|
-
testTypedef(`
|
|
2218
|
-
sub main(param1 as string)
|
|
2219
|
-
print "main"
|
|
2220
|
-
end sub
|
|
2221
|
-
`, testHelpers_spec_1.trim `
|
|
2222
|
-
sub main(param1 as string)
|
|
2223
|
-
end sub
|
|
2224
|
-
`);
|
|
2225
|
-
});
|
|
2226
|
-
it('includes annotations', () => {
|
|
2227
|
-
testTypedef(`
|
|
2228
|
-
namespace test
|
|
2229
|
-
@an
|
|
2230
|
-
@anFunc("value")
|
|
2231
|
-
function getDuck()
|
|
2232
|
-
end function
|
|
2233
|
-
class Duck
|
|
2234
|
-
@anMember
|
|
2235
|
-
@anMember("field")
|
|
2236
|
-
private thing
|
|
2237
|
-
|
|
2238
|
-
@anMember
|
|
2239
|
-
@anMember("func")
|
|
2240
|
-
private function foo()
|
|
2241
|
-
end function
|
|
2242
|
-
end class
|
|
2243
|
-
end namespace
|
|
2244
|
-
`, testHelpers_spec_1.trim `
|
|
2245
|
-
namespace test
|
|
2246
|
-
@an
|
|
2247
|
-
@anFunc("value")
|
|
2248
|
-
function getDuck()
|
|
2249
|
-
end function
|
|
2250
|
-
class Duck
|
|
2251
|
-
@anMember
|
|
2252
|
-
@anMember("field")
|
|
2253
|
-
private thing as dynamic
|
|
2254
|
-
@anMember
|
|
2255
|
-
@anMember("func")
|
|
2256
|
-
private function foo()
|
|
2257
|
-
end function
|
|
2258
|
-
end class
|
|
2259
|
-
end namespace
|
|
2260
|
-
`);
|
|
2261
|
-
});
|
|
2262
|
-
it('includes import statements', () => {
|
|
2263
|
-
testTypedef(`
|
|
2264
|
-
import "pkg:/source/lib.brs"
|
|
2265
|
-
`, testHelpers_spec_1.trim `
|
|
2266
|
-
import "pkg:/source/lib.brs"
|
|
2267
|
-
`);
|
|
2268
|
-
});
|
|
2269
|
-
it('includes namespace statements', () => {
|
|
2270
|
-
testTypedef(`
|
|
2271
|
-
namespace Name
|
|
2272
|
-
sub logInfo()
|
|
2273
|
-
end sub
|
|
2274
|
-
end namespace
|
|
2275
|
-
namespace NameA.NameB
|
|
2276
|
-
sub logInfo()
|
|
2277
|
-
end sub
|
|
2278
|
-
end namespace
|
|
2279
|
-
`, testHelpers_spec_1.trim `
|
|
2280
|
-
namespace Name
|
|
2281
|
-
sub logInfo()
|
|
2282
|
-
end sub
|
|
2283
|
-
end namespace
|
|
2284
|
-
namespace NameA.NameB
|
|
2285
|
-
sub logInfo()
|
|
2286
|
-
end sub
|
|
2287
|
-
end namespace
|
|
2288
|
-
`);
|
|
2289
|
-
});
|
|
2290
|
-
it('includes classes', () => {
|
|
2291
|
-
testTypedef(`
|
|
2292
|
-
class Person
|
|
2293
|
-
public name as string
|
|
2294
|
-
public age = 12
|
|
2295
|
-
public sub getAge() as integer
|
|
2296
|
-
return m.age
|
|
2297
|
-
end sub
|
|
2298
|
-
end class
|
|
2299
|
-
namespace NameA.NameB
|
|
2300
|
-
class Person
|
|
2301
|
-
public name as string
|
|
2302
|
-
public age = 12
|
|
2303
|
-
public sub getAge() as integer
|
|
2304
|
-
return m.age
|
|
2305
|
-
end sub
|
|
2306
|
-
end class
|
|
2307
|
-
end namespace
|
|
2308
|
-
`, testHelpers_spec_1.trim `
|
|
2309
|
-
class Person
|
|
2310
|
-
public name as string
|
|
2311
|
-
public age as integer
|
|
2312
|
-
public sub getAge() as integer
|
|
2313
|
-
end sub
|
|
2314
|
-
end class
|
|
2315
|
-
namespace NameA.NameB
|
|
2316
|
-
class Person
|
|
2317
|
-
public name as string
|
|
2318
|
-
public age as integer
|
|
2319
|
-
public sub getAge() as integer
|
|
2320
|
-
end sub
|
|
2321
|
-
end class
|
|
2322
|
-
end namespace
|
|
2323
|
-
`);
|
|
2324
|
-
});
|
|
2325
|
-
it('sets properties to dynamic when initialized to invalid', () => {
|
|
2326
|
-
testTypedef(`
|
|
2327
|
-
class Human
|
|
2328
|
-
public firstName = invalid
|
|
2329
|
-
public lastName as string = invalid
|
|
2330
|
-
end class
|
|
2331
|
-
`, testHelpers_spec_1.trim `
|
|
2332
|
-
class Human
|
|
2333
|
-
public firstName as dynamic
|
|
2334
|
-
public lastName as string
|
|
2335
|
-
end class
|
|
2336
|
-
`);
|
|
2337
|
-
});
|
|
2338
|
-
it('includes class inheritance', () => {
|
|
2339
|
-
testTypedef(`
|
|
2340
|
-
class Human
|
|
2341
|
-
sub new(name as string)
|
|
2342
|
-
m.name = name
|
|
2343
|
-
end sub
|
|
2344
|
-
end class
|
|
2345
|
-
class Person extends Human
|
|
2346
|
-
sub new(name as string)
|
|
2347
|
-
super(name)
|
|
2348
|
-
end sub
|
|
2349
|
-
end class
|
|
2350
|
-
`, testHelpers_spec_1.trim `
|
|
2351
|
-
class Human
|
|
2352
|
-
sub new(name as string)
|
|
2353
|
-
end sub
|
|
2354
|
-
end class
|
|
2355
|
-
class Person extends Human
|
|
2356
|
-
sub new(name as string)
|
|
2357
|
-
end sub
|
|
2358
|
-
end class
|
|
2359
|
-
`);
|
|
2360
|
-
});
|
|
2361
|
-
it('includes access modifier keyword', () => {
|
|
2362
|
-
testTypedef(`
|
|
2363
|
-
class Human
|
|
2364
|
-
public firstName as string
|
|
2365
|
-
protected middleName as string
|
|
2366
|
-
private lastName as string
|
|
2367
|
-
public function getFirstName()
|
|
2368
|
-
return m.firstName
|
|
2369
|
-
end function
|
|
2370
|
-
protected function getMiddleName()
|
|
2371
|
-
return m.middleName
|
|
2372
|
-
end function
|
|
2373
|
-
private function getLastName()
|
|
2374
|
-
return m.lastName
|
|
2375
|
-
end function
|
|
2376
|
-
end class
|
|
2377
|
-
`, testHelpers_spec_1.trim `
|
|
2378
|
-
class Human
|
|
2379
|
-
public firstName as string
|
|
2380
|
-
protected middleName as string
|
|
2381
|
-
private lastName as string
|
|
2382
|
-
public function getFirstName()
|
|
2383
|
-
end function
|
|
2384
|
-
protected function getMiddleName()
|
|
2385
|
-
end function
|
|
2386
|
-
private function getLastName()
|
|
2387
|
-
end function
|
|
2388
|
-
end class
|
|
2389
|
-
`);
|
|
2390
|
-
});
|
|
2391
|
-
it('includes overrides keyword if present in source', () => {
|
|
2392
|
-
testTypedef(`
|
|
2393
|
-
class Animal
|
|
2394
|
-
public sub speak()
|
|
2395
|
-
print "Hello Animal"
|
|
2396
|
-
end sub
|
|
2397
|
-
end class
|
|
2398
|
-
class Dog extends Animal
|
|
2399
|
-
public override sub speak()
|
|
2400
|
-
print "Hello Dog"
|
|
2401
|
-
end sub
|
|
2402
|
-
end class
|
|
2403
|
-
`, testHelpers_spec_1.trim `
|
|
2404
|
-
class Animal
|
|
2405
|
-
public sub speak()
|
|
2406
|
-
end sub
|
|
2407
|
-
end class
|
|
2408
|
-
class Dog extends Animal
|
|
2409
|
-
public override sub speak()
|
|
2410
|
-
end sub
|
|
2411
|
-
end class
|
|
2412
|
-
`);
|
|
2413
|
-
});
|
|
2414
|
-
it('includes class inheritance cross-namespace', () => {
|
|
2415
|
-
testTypedef(`
|
|
2416
|
-
namespace NameA
|
|
2417
|
-
class Human
|
|
2418
|
-
sub new(name as string)
|
|
2419
|
-
m.name = name
|
|
2420
|
-
end sub
|
|
2421
|
-
end class
|
|
2422
|
-
end namespace
|
|
2423
|
-
namespace NameB
|
|
2424
|
-
class Person extends NameA.Human
|
|
2425
|
-
sub new(name as string)
|
|
2426
|
-
super(name)
|
|
2427
|
-
end sub
|
|
2428
|
-
end class
|
|
2429
|
-
end namespace
|
|
2430
|
-
`, testHelpers_spec_1.trim `
|
|
2431
|
-
namespace NameA
|
|
2432
|
-
class Human
|
|
2433
|
-
sub new(name as string)
|
|
2434
|
-
end sub
|
|
2435
|
-
end class
|
|
2436
|
-
end namespace
|
|
2437
|
-
namespace NameB
|
|
2438
|
-
class Person extends NameA.Human
|
|
2439
|
-
sub new(name as string)
|
|
2440
|
-
end sub
|
|
2441
|
-
end class
|
|
2442
|
-
end namespace
|
|
2443
|
-
`);
|
|
2444
|
-
});
|
|
2445
|
-
});
|
|
2446
|
-
describe('parser getter', () => {
|
|
2447
|
-
it('recreates the parser when missing', () => {
|
|
2448
|
-
const file = program.setFile('source/main.brs', `
|
|
2449
|
-
sub main()
|
|
2450
|
-
end sub
|
|
2451
|
-
`);
|
|
2452
|
-
const parser = file['_parser'];
|
|
2453
|
-
//clear the private _parser instance
|
|
2454
|
-
file['_parser'] = undefined;
|
|
2455
|
-
//force the file to get a new instance of parser
|
|
2456
|
-
const newParser = file.parser;
|
|
2457
|
-
chai_1.expect(newParser).to.exist.and.to.not.equal(parser);
|
|
2458
|
-
//reference shouldn't change in subsequent accesses
|
|
2459
|
-
chai_1.expect(file.parser).to.equal(newParser);
|
|
2460
|
-
});
|
|
2461
|
-
it('call parse when previously skipped', () => {
|
|
2462
|
-
program.setFile('source/main.d.bs', `
|
|
2463
|
-
sub main()
|
|
2464
|
-
end sub
|
|
2465
|
-
`);
|
|
2466
|
-
const file = program.setFile('source/main.brs', `
|
|
2467
|
-
sub main()
|
|
2468
|
-
end sub
|
|
2469
|
-
`);
|
|
2470
|
-
//no functions should be found since the parser was skipped
|
|
2471
|
-
chai_1.expect(file['_parser']).to.not.exist;
|
|
2472
|
-
const stub = sinon.stub(file, 'parse').callThrough();
|
|
2473
|
-
//`file.parser` is a getter, so that should force the parse to occur
|
|
2474
|
-
chai_1.expect(file.parser.references.functionStatements).to.be.lengthOf(1);
|
|
2475
|
-
chai_1.expect(stub.called).to.be.true;
|
|
2476
|
-
//parse should have been called
|
|
2477
|
-
});
|
|
2478
|
-
});
|
|
2479
|
-
describe('Plugins', () => {
|
|
2480
|
-
function testPluginTranspile() {
|
|
2481
|
-
testTranspile(`
|
|
2482
|
-
sub main()
|
|
2483
|
-
sayHello(sub()
|
|
2484
|
-
print "sub hello"
|
|
2485
|
-
end sub)
|
|
2486
|
-
print "something"
|
|
2487
|
-
end sub
|
|
2488
|
-
|
|
2489
|
-
sub sayHello(fn)
|
|
2490
|
-
fn()
|
|
2491
|
-
print "hello"
|
|
2492
|
-
end sub
|
|
2493
|
-
`, `
|
|
2494
|
-
sub main()
|
|
2495
|
-
sayHello(sub()
|
|
2496
|
-
\n end sub)
|
|
2497
|
-
\n end sub
|
|
2498
|
-
|
|
2499
|
-
sub sayHello(fn)
|
|
2500
|
-
fn()
|
|
2501
|
-
\n end sub
|
|
2502
|
-
`);
|
|
2503
|
-
}
|
|
2504
|
-
it('can use a plugin object which transforms the AST', () => {
|
|
2505
|
-
program.plugins = new PluginInterface_1.default(util_1.default.loadPlugins('', [
|
|
2506
|
-
require.resolve('../examples/plugins/removePrint')
|
|
2507
|
-
]), new Logger_1.Logger());
|
|
2508
|
-
testPluginTranspile();
|
|
2509
|
-
});
|
|
2510
|
-
it('can load an absolute plugin which transforms the AST', () => {
|
|
2511
|
-
program.plugins = new PluginInterface_1.default(util_1.default.loadPlugins('', [
|
|
2512
|
-
path.resolve(process.cwd(), './dist/examples/plugins/removePrint.js')
|
|
2513
|
-
]), new Logger_1.Logger());
|
|
2514
|
-
testPluginTranspile();
|
|
2515
|
-
});
|
|
2516
|
-
it('can load a relative plugin which transforms the AST', () => {
|
|
2517
|
-
program.plugins = new PluginInterface_1.default(util_1.default.loadPlugins(process.cwd(), [
|
|
2518
|
-
'./dist/examples/plugins/removePrint.js'
|
|
2519
|
-
]), new Logger_1.Logger());
|
|
2520
|
-
testPluginTranspile();
|
|
2521
|
-
});
|
|
2522
|
-
});
|
|
2523
|
-
});
|
|
2524
|
-
//# sourceMappingURL=BrsFile.spec.js.map
|