brighterscript 1.0.0-alpha.23 → 1.0.0-alpha.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +585 -218
- package/README.md +45 -139
- package/bsconfig.schema.json +41 -0
- package/dist/ActionPipeline.d.ts +10 -0
- package/dist/ActionPipeline.js +40 -0
- package/dist/ActionPipeline.js.map +1 -0
- package/dist/AstValidationSegmenter.d.ts +25 -0
- package/dist/AstValidationSegmenter.js +152 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +39 -4
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.js +3 -3
- package/dist/Cache.js.map +1 -1
- package/dist/CacheVerifier.d.ts +7 -0
- package/dist/CacheVerifier.js +20 -0
- package/dist/CacheVerifier.js.map +1 -0
- package/dist/CodeActionUtil.d.ts +3 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +3 -2
- package/dist/CommentFlagProcessor.js +5 -4
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +3 -2
- package/dist/DependencyGraph.js +11 -10
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.js +9 -5
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +1 -0
- package/dist/DiagnosticFilterer.js +5 -3
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +79 -15
- package/dist/DiagnosticMessages.js +134 -21
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
- package/dist/DiagnosticSeverityAdjuster.js +41 -0
- package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
- package/dist/FunctionScope.d.ts +28 -0
- package/dist/FunctionScope.js +52 -0
- package/dist/FunctionScope.js.map +1 -0
- package/dist/KeyedThrottler.d.ts +3 -3
- package/dist/KeyedThrottler.js +3 -3
- package/dist/KeyedThrottler.js.map +1 -1
- package/dist/LanguageServer.d.ts +23 -11
- package/dist/LanguageServer.js +222 -87
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +3 -2
- package/dist/Logger.js +11 -3
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +21 -3
- package/dist/PluginInterface.js +74 -6
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +162 -81
- package/dist/Program.js +903 -732
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +22 -12
- package/dist/ProgramBuilder.js +132 -104
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +95 -134
- package/dist/Scope.js +477 -551
- package/dist/Scope.js.map +1 -1
- package/dist/Stopwatch.js +1 -1
- package/dist/Stopwatch.js.map +1 -1
- package/dist/SymbolTable.d.ts +95 -29
- package/dist/SymbolTable.js +256 -102
- package/dist/SymbolTable.js.map +1 -1
- package/dist/Throttler.d.ts +12 -0
- package/dist/Throttler.js +39 -0
- package/dist/Throttler.js.map +1 -1
- package/dist/Watcher.d.ts +0 -3
- package/dist/Watcher.js +0 -3
- package/dist/Watcher.js.map +1 -1
- package/dist/XmlScope.d.ts +4 -6
- package/dist/XmlScope.js +74 -68
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +48 -0
- package/dist/astUtils/CachedLookups.js +323 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +9 -5
- package/dist/astUtils/{AstEditor.js → Editor.js} +10 -4
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +68 -64
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +10 -10
- package/dist/astUtils/creators.js +26 -16
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +5 -5
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +132 -100
- package/dist/astUtils/reflection.js +225 -166
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +208 -126
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +12 -12
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +54 -35
- package/dist/astUtils/visitors.js +29 -3
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +178 -33
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -9
- package/dist/astUtils/xml.js +9 -9
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +12 -2
- package/dist/bscPlugin/BscPlugin.js +41 -3
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
- package/dist/bscPlugin/CallExpressionInfo.js +131 -0
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
- package/dist/bscPlugin/FileWriter.d.ts +6 -0
- package/dist/bscPlugin/FileWriter.js +24 -0
- package/dist/bscPlugin/FileWriter.js.map +1 -0
- package/dist/bscPlugin/SignatureHelpUtil.d.ts +10 -0
- package/dist/bscPlugin/SignatureHelpUtil.js +135 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +21 -12
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +86 -12
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +57 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js +544 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1909 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +17 -0
- package/dist/bscPlugin/hover/HoverProcessor.js +188 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +513 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +3 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +102 -29
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +167 -6
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +1 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
- package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
- package/dist/bscPlugin/serialize/BslibManager.js +40 -0
- package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
- package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
- package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
- package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +16 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +123 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +12 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +22 -1
- package/dist/bscPlugin/validation/BrsFileValidator.js +316 -29
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +264 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/ProgramValidator.d.ts +10 -0
- package/dist/bscPlugin/validation/ProgramValidator.js +32 -0
- package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +56 -8
- package/dist/bscPlugin/validation/ScopeValidator.js +514 -116
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2454 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js +44 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
- package/dist/cli.js +107 -8
- package/dist/cli.js.map +1 -1
- package/dist/deferred.d.ts +3 -3
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +8 -2
- package/dist/diagnosticUtils.js +47 -17
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +8 -10
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +26 -0
- package/dist/files/AssetFile.js +26 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +529 -486
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +124 -112
- package/dist/files/BrsFile.js +819 -1131
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1869 -1277
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +104 -0
- package/dist/files/BscFile.js +16 -0
- package/dist/files/BscFile.js.map +1 -0
- package/dist/files/Factory.d.ts +25 -0
- package/dist/files/Factory.js +22 -0
- package/dist/files/Factory.js.map +1 -0
- package/dist/files/LazyFileData.d.ts +20 -0
- package/dist/files/LazyFileData.js +54 -0
- package/dist/files/LazyFileData.js.map +1 -0
- package/dist/files/LazyFileData.spec.d.ts +1 -0
- package/dist/files/LazyFileData.spec.js +27 -0
- package/dist/files/LazyFileData.spec.js.map +1 -0
- package/dist/files/XmlFile.d.ts +70 -32
- package/dist/files/XmlFile.js +106 -117
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +325 -262
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +49 -41
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.js +104 -40
- package/dist/files/tests/optionalChaning.spec.js.map +1 -1
- package/dist/globalCallables.js +16 -18
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +440 -150
- package/dist/interfaces.js +27 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Character.spec.js +5 -5
- package/dist/lexer/Character.spec.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +12 -5
- package/dist/lexer/Lexer.js +28 -13
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +187 -134
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +9 -1
- package/dist/lexer/Token.js +9 -1
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +9 -0
- package/dist/lexer/TokenKind.js +30 -5
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +162 -0
- package/dist/parser/AstNode.js +225 -0
- package/dist/parser/AstNode.js.map +1 -0
- package/dist/parser/AstNode.spec.d.ts +1 -0
- package/dist/parser/AstNode.spec.js +165 -0
- package/dist/parser/AstNode.spec.js.map +1 -0
- package/dist/parser/BrsTranspileState.d.ts +4 -7
- package/dist/parser/BrsTranspileState.js +4 -12
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +126 -167
- package/dist/parser/Expression.js +524 -394
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +152 -146
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +45 -196
- package/dist/parser/Parser.js +470 -926
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +1034 -805
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +9 -8
- package/dist/parser/SGParser.js +10 -8
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +27 -38
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +98 -35
- package/dist/parser/SGTypes.js +169 -99
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +208 -122
- package/dist/parser/Statement.js +599 -364
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +45 -21
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +1 -1
- package/dist/parser/TranspileState.js +7 -12
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.js +3 -2
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +33 -23
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +25 -20
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +96 -94
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +22 -16
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +8 -8
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +58 -21
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +61 -20
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +8 -8
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +129 -21
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +5 -5
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +36 -36
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +67 -22
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +9 -9
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +123 -81
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +12 -12
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +12 -12
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/Relational.spec.js +13 -13
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +221 -81
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +287 -105
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js +127 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +15 -15
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/ConstStatement.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js +262 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/Continue.spec.d.ts +1 -0
- package/dist/parser/tests/statement/Continue.spec.js +119 -0
- package/dist/parser/tests/statement/Continue.spec.js.map +1 -0
- package/dist/parser/tests/statement/Declaration.spec.js +19 -19
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +22 -22
- package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.js +111 -300
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
- package/dist/parser/tests/statement/For.spec.js +9 -10
- package/dist/parser/tests/statement/For.spec.js.map +1 -1
- package/dist/parser/tests/statement/ForEach.spec.js +8 -9
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/statement/Function.spec.js +44 -35
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +5 -5
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +20 -20
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +30 -196
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +11 -11
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +16 -78
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +107 -90
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +14 -12
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +48 -35
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +6 -6
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +6 -6
- package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +18 -16
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +1 -1
- package/dist/preprocessor/Manifest.js +3 -3
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/preprocessor/Manifest.spec.js +8 -8
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/preprocessor/Preprocessor.d.ts +5 -6
- package/dist/preprocessor/Preprocessor.js +15 -11
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/preprocessor/Preprocessor.spec.js +25 -25
- package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.d.ts +1 -1
- package/dist/preprocessor/PreprocessorParser.js +7 -1
- package/dist/preprocessor/PreprocessorParser.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +13 -13
- package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
- package/dist/roku-types/data.json +6544 -10519
- package/dist/roku-types/index.d.ts +662 -1934
- package/dist/types/ArrayType.d.ts +10 -9
- package/dist/types/ArrayType.js +65 -60
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +36 -68
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +11 -0
- package/dist/types/AssociativeArrayType.js +52 -0
- package/dist/types/AssociativeArrayType.js.map +1 -0
- package/dist/types/BaseFunctionType.d.ts +9 -0
- package/dist/types/BaseFunctionType.js +25 -0
- package/dist/types/BaseFunctionType.js.map +1 -0
- package/dist/types/BooleanType.d.ts +8 -5
- package/dist/types/BooleanType.js +14 -7
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +10 -6
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +32 -21
- package/dist/types/BscType.js +118 -21
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BscTypeKind.d.ts +25 -0
- package/dist/types/BscTypeKind.js +30 -0
- package/dist/types/BscTypeKind.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
- package/dist/types/BuiltInInterfaceAdder.js +164 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +116 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
- package/dist/types/ClassType.d.ts +17 -0
- package/dist/types/ClassType.js +58 -0
- package/dist/types/ClassType.js.map +1 -0
- package/dist/types/ClassType.spec.d.ts +1 -0
- package/dist/types/ClassType.spec.js +77 -0
- package/dist/types/ClassType.spec.js.map +1 -0
- package/dist/types/ComponentType.d.ts +26 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +8 -5
- package/dist/types/DoubleType.js +18 -16
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +12 -6
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +10 -5
- package/dist/types/DynamicType.js +16 -4
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/DynamicType.spec.js +16 -5
- package/dist/types/DynamicType.spec.js.map +1 -1
- package/dist/types/EnumType.d.ts +30 -12
- package/dist/types/EnumType.js +43 -17
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/EnumType.spec.d.ts +1 -0
- package/dist/types/EnumType.spec.js +33 -0
- package/dist/types/EnumType.spec.js.map +1 -0
- package/dist/types/FloatType.d.ts +8 -5
- package/dist/types/FloatType.js +18 -16
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -6
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +13 -8
- package/dist/types/FunctionType.js +30 -14
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +28 -0
- package/dist/types/InheritableType.js +152 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +8 -5
- package/dist/types/IntegerType.js +18 -16
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +8 -6
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +12 -13
- package/dist/types/InterfaceType.js +20 -48
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +90 -56
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/InvalidType.d.ts +7 -5
- package/dist/types/InvalidType.js +13 -7
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +8 -6
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +8 -5
- package/dist/types/LongIntegerType.js +17 -15
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +10 -6
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/NamespaceType.d.ts +12 -0
- package/dist/types/NamespaceType.js +28 -0
- package/dist/types/NamespaceType.js.map +1 -0
- package/dist/types/ObjectType.d.ts +9 -8
- package/dist/types/ObjectType.js +21 -11
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ObjectType.spec.js +3 -3
- package/dist/types/ObjectType.spec.js.map +1 -1
- package/dist/types/ReferenceType.d.ts +63 -0
- package/dist/types/ReferenceType.js +423 -0
- package/dist/types/ReferenceType.js.map +1 -0
- package/dist/types/ReferenceType.spec.d.ts +1 -0
- package/dist/types/ReferenceType.spec.js +137 -0
- package/dist/types/ReferenceType.spec.js.map +1 -0
- package/dist/types/StringType.d.ts +11 -5
- package/dist/types/StringType.js +18 -7
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +3 -5
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +22 -17
- package/dist/types/TypedFunctionType.js +78 -60
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/TypedFunctionType.spec.js +105 -20
- package/dist/types/TypedFunctionType.spec.js.map +1 -1
- package/dist/types/UninitializedType.d.ts +8 -6
- package/dist/types/UninitializedType.js +13 -7
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +20 -0
- package/dist/types/UnionType.js +123 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +130 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +8 -5
- package/dist/types/VoidType.js +14 -7
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/VoidType.spec.js +3 -3
- package/dist/types/VoidType.spec.js.map +1 -1
- package/dist/types/helper.spec.d.ts +1 -0
- package/dist/types/helper.spec.js +145 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +19 -37
- package/dist/types/helpers.js +159 -99
- package/dist/types/helpers.js.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.js +39 -0
- package/dist/types/index.js.map +1 -0
- package/dist/util.d.ts +167 -131
- package/dist/util.js +890 -350
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +7 -25
- package/dist/validators/ClassValidator.js +103 -194
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +165 -149
- package/dist/astUtils/AstEditor.js.map +0 -1
- package/dist/astUtils/AstEditor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +0 -8
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +0 -40
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -32
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
- package/dist/parser/SGTypes.spec.js +0 -351
- package/dist/parser/SGTypes.spec.js.map +0 -1
- package/dist/types/CustomType.d.ts +0 -12
- package/dist/types/CustomType.js +0 -44
- package/dist/types/CustomType.js.map +0 -1
- package/dist/types/LazyType.d.ts +0 -16
- package/dist/types/LazyType.js +0 -44
- package/dist/types/LazyType.js.map +0 -1
- /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
- /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{parser/SGTypes.spec.d.ts → bscPlugin/hover/HoverProcessor.spec.d.ts} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const chai_config_spec_1 = require("../chai-config.spec");
|
|
4
4
|
const sinonImport = require("sinon");
|
|
5
5
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
6
6
|
const Program_1 = require("../Program");
|
|
@@ -15,35 +15,62 @@ const Lexer_1 = require("../lexer/Lexer");
|
|
|
15
15
|
const TokenKind_1 = require("../lexer/TokenKind");
|
|
16
16
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
17
17
|
const util_1 = require("../util");
|
|
18
|
-
const PluginInterface_1 = require("../PluginInterface");
|
|
19
18
|
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
20
19
|
const Parser_1 = require("../parser/Parser");
|
|
21
|
-
const Logger_1 = require("../Logger");
|
|
22
20
|
const Statement_1 = require("../parser/Statement");
|
|
23
21
|
const creators_1 = require("../astUtils/creators");
|
|
24
22
|
const fsExtra = require("fs-extra");
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
23
|
+
const vscode_uri_1 = require("vscode-uri");
|
|
24
|
+
const undent_1 = require("undent");
|
|
25
|
+
const testHelpers_spec_2 = require("../testHelpers.spec");
|
|
26
|
+
const SymbolTable_1 = require("../SymbolTable");
|
|
27
|
+
const types_1 = require("../types");
|
|
29
28
|
let sinon = sinonImport.createSandbox();
|
|
30
29
|
describe('BrsFile', () => {
|
|
31
|
-
let tempDir = (0, util_1.standardizePath) `${process.cwd()}/.tmp`;
|
|
32
|
-
let rootDir = (0, util_1.standardizePath) `${tempDir}/rootDir`;
|
|
33
30
|
let program;
|
|
34
|
-
let srcPath = (0, util_1.standardizePath) `${rootDir}/source/main.brs`;
|
|
31
|
+
let srcPath = (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.brs`;
|
|
35
32
|
let destPath = 'source/main.brs';
|
|
36
33
|
let file;
|
|
37
|
-
let testTranspile = (0, testHelpers_spec_1.getTestTranspile)(() => [program, rootDir]);
|
|
34
|
+
let testTranspile = (0, testHelpers_spec_1.getTestTranspile)(() => [program, testHelpers_spec_2.rootDir]);
|
|
35
|
+
let testGetTypedef = (0, testHelpers_spec_1.getTestGetTypedef)(() => [program, testHelpers_spec_2.rootDir]);
|
|
38
36
|
beforeEach(() => {
|
|
39
|
-
fsExtra.emptyDirSync(tempDir);
|
|
40
|
-
program = new Program_1.Program({ rootDir: rootDir, sourceMap: true });
|
|
41
|
-
file = new BrsFile_1.BrsFile(
|
|
37
|
+
fsExtra.emptyDirSync(testHelpers_spec_2.tempDir);
|
|
38
|
+
program = new Program_1.Program({ rootDir: testHelpers_spec_2.rootDir, sourceMap: true });
|
|
39
|
+
file = new BrsFile_1.BrsFile({
|
|
40
|
+
srcPath: srcPath,
|
|
41
|
+
destPath: destPath,
|
|
42
|
+
program: program
|
|
43
|
+
});
|
|
42
44
|
});
|
|
43
45
|
afterEach(() => {
|
|
44
46
|
sinon.restore();
|
|
45
47
|
program.dispose();
|
|
46
48
|
});
|
|
49
|
+
describe('constructor', () => {
|
|
50
|
+
it('calculates correct paths when no pkgPath specified', () => {
|
|
51
|
+
(0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile({
|
|
52
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.bs`,
|
|
53
|
+
destPath: (0, util_1.standardizePath) `source/main.bs`,
|
|
54
|
+
program: program
|
|
55
|
+
})).to.include({
|
|
56
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.bs`,
|
|
57
|
+
destPath: (0, util_1.standardizePath) `source/main.bs`,
|
|
58
|
+
pkgPath: (0, util_1.standardizePath) `source/main.brs`
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
it('uses supplied pkgPath', () => {
|
|
62
|
+
(0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile({
|
|
63
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.bs`,
|
|
64
|
+
destPath: (0, util_1.standardizePath) `source/main.bs`,
|
|
65
|
+
pkgPath: (0, util_1.standardizePath) `source/main.transpiled.brs`,
|
|
66
|
+
program: program
|
|
67
|
+
})).to.include({
|
|
68
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.bs`,
|
|
69
|
+
destPath: (0, util_1.standardizePath) `source/main.bs`,
|
|
70
|
+
pkgPath: (0, util_1.standardizePath) `source/main.transpiled.brs`
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
47
74
|
describe('allowBrighterScriptInBrightScript', () => {
|
|
48
75
|
it('is false by default', () => {
|
|
49
76
|
program.setFile('source/main.brs', `
|
|
@@ -63,6 +90,66 @@ describe('BrsFile', () => {
|
|
|
63
90
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
64
91
|
});
|
|
65
92
|
});
|
|
93
|
+
it('flags namespaces used as variables', () => {
|
|
94
|
+
program.setFile('source/main.bs', `
|
|
95
|
+
sub main()
|
|
96
|
+
alpha.beta.charlie.test()
|
|
97
|
+
print alpha
|
|
98
|
+
print alpha.beta
|
|
99
|
+
print alpha.beta.charlie
|
|
100
|
+
end sub
|
|
101
|
+
|
|
102
|
+
namespace alpha
|
|
103
|
+
namespace beta
|
|
104
|
+
namespace charlie
|
|
105
|
+
sub test()
|
|
106
|
+
end sub
|
|
107
|
+
end namespace
|
|
108
|
+
end namespace
|
|
109
|
+
end namespace
|
|
110
|
+
`);
|
|
111
|
+
program.validate();
|
|
112
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('namespace')), { range: util_1.default.createRange(3, 22, 3, 27) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('namespace')), { range: util_1.default.createRange(4, 22, 4, 32) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('namespace')), { range: util_1.default.createRange(5, 22, 5, 40) })]);
|
|
113
|
+
});
|
|
114
|
+
it('allows namespaces with the name `optional`', () => {
|
|
115
|
+
program.setFile('source/main.bs', `
|
|
116
|
+
namespace optional
|
|
117
|
+
namespace optional
|
|
118
|
+
end namespace
|
|
119
|
+
end namespace
|
|
120
|
+
namespace alpha
|
|
121
|
+
namespace optional
|
|
122
|
+
end namespace
|
|
123
|
+
end namespace
|
|
124
|
+
namespace alpha.beta.optional
|
|
125
|
+
end namespace
|
|
126
|
+
`);
|
|
127
|
+
program.validate();
|
|
128
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
129
|
+
});
|
|
130
|
+
it('flags enums used as variables', () => {
|
|
131
|
+
program.setFile('source/main.bs', `
|
|
132
|
+
enum Foo
|
|
133
|
+
bar
|
|
134
|
+
baz
|
|
135
|
+
end enum
|
|
136
|
+
|
|
137
|
+
sub main()
|
|
138
|
+
print getFooValue()
|
|
139
|
+
print getFoo()
|
|
140
|
+
end sub
|
|
141
|
+
|
|
142
|
+
function getFoo() as Foo
|
|
143
|
+
return Foo ' Error - cannot return an enum, just an enum value
|
|
144
|
+
end function
|
|
145
|
+
|
|
146
|
+
function getFooValue() as Foo
|
|
147
|
+
return Foo.bar
|
|
148
|
+
end function
|
|
149
|
+
`);
|
|
150
|
+
program.validate();
|
|
151
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('enum').message]);
|
|
152
|
+
});
|
|
66
153
|
it('supports the third parameter in CreateObject', () => {
|
|
67
154
|
program.setFile('source/main.brs', `
|
|
68
155
|
sub main()
|
|
@@ -83,17 +170,25 @@ describe('BrsFile', () => {
|
|
|
83
170
|
});
|
|
84
171
|
it('sets needsTranspiled to true for .bs files', () => {
|
|
85
172
|
//BrightScript
|
|
86
|
-
(0,
|
|
173
|
+
(0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile({
|
|
174
|
+
srcPath: `${testHelpers_spec_2.rootDir}/source/main.brs`,
|
|
175
|
+
destPath: 'source/main.brs',
|
|
176
|
+
program: program
|
|
177
|
+
})['needsTranspiled']).to.be.false;
|
|
87
178
|
//BrighterScript
|
|
88
|
-
(0,
|
|
179
|
+
(0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile({
|
|
180
|
+
srcPath: `${testHelpers_spec_2.rootDir}/source/main.bs`,
|
|
181
|
+
destPath: 'source/main.bs',
|
|
182
|
+
program: program
|
|
183
|
+
})['needsTranspiled']).to.be.true;
|
|
89
184
|
});
|
|
90
185
|
it('computes new import statements after clearing parser references', () => {
|
|
91
186
|
const file = program.setFile('source/main.bs', ``);
|
|
92
|
-
(0,
|
|
187
|
+
(0, chai_config_spec_1.expect)(file.ownScriptImports).to.be.empty;
|
|
93
188
|
file.parser.ast.statements.push(new Statement_1.ImportStatement((0, creators_1.createToken)(TokenKind_1.TokenKind.Import), (0, creators_1.createToken)(TokenKind_1.TokenKind.StringLiteral, 'pkg:/source/lib.brs')));
|
|
94
|
-
(0,
|
|
95
|
-
file.
|
|
96
|
-
(0,
|
|
189
|
+
(0, chai_config_spec_1.expect)(file.ownScriptImports).to.be.empty;
|
|
190
|
+
file['_cachedLookups'].invalidate();
|
|
191
|
+
(0, chai_config_spec_1.expect)(file.ownScriptImports.map(x => x.text)).to.eql(['pkg:/source/lib.brs']);
|
|
97
192
|
});
|
|
98
193
|
it('allows adding diagnostics', () => {
|
|
99
194
|
const expected = [{
|
|
@@ -106,282 +201,78 @@ describe('BrsFile', () => {
|
|
|
106
201
|
});
|
|
107
202
|
describe('getPartialVariableName', () => {
|
|
108
203
|
let entry = {
|
|
109
|
-
src: `${rootDir}/source/lib.brs`,
|
|
204
|
+
src: `${testHelpers_spec_2.rootDir}/source/lib.brs`,
|
|
110
205
|
dest: `source/lib.brs`
|
|
111
206
|
};
|
|
112
207
|
it('creates proper tokens', () => {
|
|
113
208
|
file = program.setFile(entry, `call(ModuleA.ModuleB.ModuleC.`);
|
|
114
|
-
(0,
|
|
115
|
-
(0,
|
|
116
|
-
(0,
|
|
117
|
-
(0,
|
|
118
|
-
(0,
|
|
119
|
-
(0,
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
describe('getScopesForFile', () => {
|
|
123
|
-
it('finds the scope for the file', () => {
|
|
124
|
-
var _a;
|
|
125
|
-
let file = program.setFile('source/main.brs', ``);
|
|
126
|
-
(0, chai_1.expect)((_a = program.getScopesForFile(file)[0]) === null || _a === void 0 ? void 0 : _a.name).to.equal('source');
|
|
209
|
+
(0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[7])).to.equal('ModuleA.ModuleB.ModuleC.');
|
|
210
|
+
(0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[6])).to.equal('ModuleA.ModuleB.ModuleC');
|
|
211
|
+
(0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[5])).to.equal('ModuleA.ModuleB.');
|
|
212
|
+
(0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[4])).to.equal('ModuleA.ModuleB');
|
|
213
|
+
(0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[3])).to.equal('ModuleA.');
|
|
214
|
+
(0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[2])).to.equal('ModuleA');
|
|
127
215
|
});
|
|
128
216
|
});
|
|
129
|
-
describe('
|
|
130
|
-
it('
|
|
131
|
-
const file = program.setFile('source/main.brs', `
|
|
132
|
-
sub main()
|
|
133
|
-
getManager()@.
|
|
134
|
-
end sub
|
|
135
|
-
`);
|
|
136
|
-
(0, chai_1.expect)(() => {
|
|
137
|
-
program.getCompletions(file.srcPath, util_1.default.createPosition(2, 34));
|
|
138
|
-
}).not.to.throw;
|
|
139
|
-
});
|
|
140
|
-
it('suggests pkg paths in strings that match that criteria', () => {
|
|
217
|
+
describe('canBePruned', () => {
|
|
218
|
+
it('returns false is target file has contains a function statement', () => {
|
|
141
219
|
program.setFile('source/main.brs', `
|
|
142
220
|
sub main()
|
|
143
|
-
print
|
|
221
|
+
print \`pkg:\`
|
|
144
222
|
end sub
|
|
145
223
|
`);
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
(0, chai_1.expect)(names.sort()).to.eql([
|
|
149
|
-
'pkg:/source/main.brs'
|
|
150
|
-
]);
|
|
224
|
+
const file = program.getFile('source/main.brs');
|
|
225
|
+
(0, chai_config_spec_1.expect)(file.canBePruned).to.be.false;
|
|
151
226
|
});
|
|
152
|
-
it('
|
|
227
|
+
it('returns false if target file contains a class statement', () => {
|
|
153
228
|
program.setFile('source/main.brs', `
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
end
|
|
229
|
+
class Animal
|
|
230
|
+
public name as string
|
|
231
|
+
end class
|
|
157
232
|
`);
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
(0, chai_1.expect)(names.sort()).to.eql([
|
|
161
|
-
'libpkg:/source/main.brs'
|
|
162
|
-
]);
|
|
233
|
+
const file = program.getFile('source/main.brs');
|
|
234
|
+
(0, chai_config_spec_1.expect)(file.canBePruned).to.be.false;
|
|
163
235
|
});
|
|
164
|
-
it('
|
|
236
|
+
it('returns false if target file contains a class statement', () => {
|
|
165
237
|
program.setFile('source/main.brs', `
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
238
|
+
namespace Vertibrates.Birds
|
|
239
|
+
function GetDucks()
|
|
240
|
+
end function
|
|
241
|
+
end namespace
|
|
169
242
|
`);
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
(0, chai_1.expect)(names.sort()).to.eql([
|
|
173
|
-
'pkg:/source/main.brs'
|
|
174
|
-
]);
|
|
243
|
+
const file = program.getFile('source/main.brs');
|
|
244
|
+
(0, chai_config_spec_1.expect)(file.canBePruned).to.be.false;
|
|
175
245
|
});
|
|
176
|
-
it('
|
|
177
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
246
|
+
it('returns true if target file contains only enum', () => {
|
|
178
247
|
program.setFile('source/main.brs', `
|
|
179
|
-
sub Main()
|
|
180
|
-
print "hello"
|
|
181
|
-
Say
|
|
182
|
-
end sub
|
|
183
|
-
|
|
184
|
-
sub SayHello()
|
|
185
|
-
end sub
|
|
186
|
-
`);
|
|
187
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 23));
|
|
188
|
-
let names = result.map(x => x.label);
|
|
189
|
-
(0, chai_1.expect)(names).to.includes('Main');
|
|
190
|
-
(0, chai_1.expect)(names).to.includes('SayHello');
|
|
191
|
-
});
|
|
192
|
-
it('includes every type of item at base level', () => {
|
|
193
|
-
program.setFile('source/main.bs', `
|
|
194
|
-
sub main()
|
|
195
|
-
print
|
|
196
|
-
end sub
|
|
197
|
-
sub speak()
|
|
198
|
-
end sub
|
|
199
|
-
namespace stuff
|
|
200
|
-
end namespace
|
|
201
|
-
class Person
|
|
202
|
-
end class
|
|
203
248
|
enum Direction
|
|
249
|
+
up
|
|
250
|
+
down
|
|
251
|
+
left
|
|
252
|
+
right
|
|
204
253
|
end enum
|
|
205
254
|
`);
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
209
|
-
}, {
|
|
210
|
-
label: 'speak',
|
|
211
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
212
|
-
}, {
|
|
213
|
-
label: 'stuff',
|
|
214
|
-
kind: vscode_languageserver_1.CompletionItemKind.Module
|
|
215
|
-
}, {
|
|
216
|
-
label: 'Person',
|
|
217
|
-
kind: vscode_languageserver_1.CompletionItemKind.Class
|
|
218
|
-
}, {
|
|
219
|
-
label: 'Direction',
|
|
220
|
-
kind: vscode_languageserver_1.CompletionItemKind.Enum
|
|
221
|
-
}]);
|
|
222
|
-
});
|
|
223
|
-
describe('namespaces', () => {
|
|
224
|
-
it('gets full namespace completions at any point through the leading identifier', () => {
|
|
225
|
-
program.setFile('source/main.bs', `
|
|
226
|
-
sub main()
|
|
227
|
-
foo.bar
|
|
228
|
-
end sub
|
|
229
|
-
|
|
230
|
-
namespace foo.bar
|
|
231
|
-
end namespace
|
|
232
|
-
|
|
233
|
-
class Person
|
|
234
|
-
end class
|
|
235
|
-
`);
|
|
236
|
-
const result = program.getCompletions(`${rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 24)).map(x => x.label);
|
|
237
|
-
(0, chai_1.expect)(result).includes('main');
|
|
238
|
-
(0, chai_1.expect)(result).includes('foo');
|
|
239
|
-
(0, chai_1.expect)(result).includes('Person');
|
|
240
|
-
});
|
|
241
|
-
it('gets namespace completions', () => {
|
|
242
|
-
program.setFile('source/main.bs', `
|
|
243
|
-
namespace foo.bar
|
|
244
|
-
function sayHello()
|
|
245
|
-
end function
|
|
246
|
-
end namespace
|
|
247
|
-
|
|
248
|
-
sub Main()
|
|
249
|
-
print "hello"
|
|
250
|
-
foo.ba
|
|
251
|
-
foo.bar.
|
|
252
|
-
end sub
|
|
253
|
-
`);
|
|
254
|
-
let result = program.getCompletions(`${rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(8, 30));
|
|
255
|
-
let names = result.map(x => x.label);
|
|
256
|
-
(0, chai_1.expect)(names).to.includes('bar');
|
|
257
|
-
result = program.getCompletions(`${rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(9, 32));
|
|
258
|
-
names = result.map(x => x.label);
|
|
259
|
-
(0, chai_1.expect)(names).to.includes('sayHello');
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
it('always includes `m`', () => {
|
|
263
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
264
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
265
|
-
sub Main()
|
|
266
|
-
|
|
267
|
-
end sub
|
|
268
|
-
`);
|
|
269
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
270
|
-
let names = result.map(x => x.label);
|
|
271
|
-
(0, chai_1.expect)(names).to.contain('m');
|
|
272
|
-
});
|
|
273
|
-
it('does not fail for missing previousToken', () => {
|
|
274
|
-
//add a single character to the file, and get completions after it
|
|
275
|
-
program.setFile('source/main.brs', `i`);
|
|
276
|
-
(0, chai_1.expect)(() => {
|
|
277
|
-
program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(0, 1)).map(x => x.label);
|
|
278
|
-
}).not.to.throw;
|
|
279
|
-
});
|
|
280
|
-
it('includes all keywords`', () => {
|
|
281
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
282
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
283
|
-
sub Main()
|
|
284
|
-
|
|
285
|
-
end sub
|
|
286
|
-
`);
|
|
287
|
-
let keywords = Object.keys(TokenKind_1.Keywords).filter(x => !x.includes(' '));
|
|
288
|
-
//inside the function
|
|
289
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
290
|
-
let names = result.map(x => x.label);
|
|
291
|
-
for (let keyword of keywords) {
|
|
292
|
-
(0, chai_1.expect)(names).to.include(keyword);
|
|
293
|
-
}
|
|
294
|
-
//outside the function
|
|
295
|
-
result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(4, 8));
|
|
296
|
-
names = result.map(x => x.label);
|
|
297
|
-
for (let keyword of keywords) {
|
|
298
|
-
(0, chai_1.expect)(names).to.include(keyword);
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
it('does not provide completions within a comment', () => {
|
|
302
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
303
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
304
|
-
sub Main()
|
|
305
|
-
'some comment
|
|
306
|
-
end sub
|
|
307
|
-
`);
|
|
308
|
-
//inside the function
|
|
309
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 33));
|
|
310
|
-
(0, chai_1.expect)(result).to.be.lengthOf(0);
|
|
311
|
-
});
|
|
312
|
-
it('does not provide duplicate entries for variables', () => {
|
|
313
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
314
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
315
|
-
sub Main()
|
|
316
|
-
name = "bob"
|
|
317
|
-
age = 12
|
|
318
|
-
name = "john"
|
|
319
|
-
end sub
|
|
320
|
-
`);
|
|
321
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 23));
|
|
322
|
-
let count = result.reduce((total, x) => {
|
|
323
|
-
return x.label === 'name' ? total + 1 : total;
|
|
324
|
-
}, 0);
|
|
325
|
-
(0, chai_1.expect)(count).to.equal(1);
|
|
326
|
-
});
|
|
327
|
-
it('does not include `as` and `string` text options when used in function params', () => {
|
|
328
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
329
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
330
|
-
sub Main(name as string)
|
|
331
|
-
|
|
332
|
-
end sub
|
|
333
|
-
`);
|
|
334
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
335
|
-
(0, chai_1.expect)(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('as');
|
|
336
|
-
(0, chai_1.expect)(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('string');
|
|
255
|
+
const file = program.getFile('source/main.brs');
|
|
256
|
+
(0, chai_config_spec_1.expect)(file.canBePruned).to.be.true;
|
|
337
257
|
});
|
|
338
|
-
it('
|
|
339
|
-
|
|
340
|
-
program.
|
|
341
|
-
|
|
342
|
-
'this is a comment
|
|
343
|
-
end sub
|
|
344
|
-
`);
|
|
345
|
-
let results = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 30));
|
|
346
|
-
(0, chai_1.expect)(results).to.be.empty;
|
|
258
|
+
it('returns true if target file is empty', () => {
|
|
259
|
+
program.setFile('source/main.brs', '');
|
|
260
|
+
const file = program.getFile('source/main.brs');
|
|
261
|
+
(0, chai_config_spec_1.expect)(file.canBePruned).to.be.true;
|
|
347
262
|
});
|
|
348
|
-
it('
|
|
349
|
-
var _a;
|
|
350
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
351
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
352
|
-
sub Main(name as string)
|
|
353
|
-
something:
|
|
354
|
-
goto \nend sub
|
|
355
|
-
`);
|
|
356
|
-
let results = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 25));
|
|
357
|
-
(0, chai_1.expect)(results.length).to.equal(1);
|
|
358
|
-
(0, chai_1.expect)((_a = results[0]) === null || _a === void 0 ? void 0 : _a.label).to.equal('something');
|
|
359
|
-
});
|
|
360
|
-
it('includes properties of objects', () => {
|
|
361
|
-
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
263
|
+
it('returns true if target file only has comments', () => {
|
|
362
264
|
program.setFile('source/main.brs', `
|
|
363
|
-
|
|
364
|
-
myObj = {name:"Bob", age: 34, height:6.0}
|
|
365
|
-
myObj.
|
|
366
|
-
end sub
|
|
265
|
+
' this is an interesting comment
|
|
367
266
|
`);
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
(0, chai_1.expect)(names).to.contain('name');
|
|
371
|
-
(0, chai_1.expect)(names).to.contain('age');
|
|
372
|
-
(0, chai_1.expect)(names).to.contain('height');
|
|
267
|
+
const file = program.getFile('source/main.brs');
|
|
268
|
+
(0, chai_config_spec_1.expect)(file.canBePruned).to.be.true;
|
|
373
269
|
});
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
end sub
|
|
381
|
-
`);
|
|
382
|
-
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 22));
|
|
383
|
-
let names = result.map(x => x.label);
|
|
384
|
-
(0, chai_1.expect)(names).to.contain('someField');
|
|
270
|
+
});
|
|
271
|
+
describe('getScopesForFile', () => {
|
|
272
|
+
it('finds the scope for the file', () => {
|
|
273
|
+
var _a;
|
|
274
|
+
let file = program.setFile('source/main.brs', ``);
|
|
275
|
+
(0, chai_config_spec_1.expect)((_a = program.getScopesForFile(file)[0]) === null || _a === void 0 ? void 0 : _a.name).to.equal('source');
|
|
385
276
|
});
|
|
386
277
|
});
|
|
387
278
|
describe('comment flags', () => {
|
|
@@ -417,14 +308,14 @@ describe('BrsFile', () => {
|
|
|
417
308
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
418
309
|
});
|
|
419
310
|
it('works for all', () => {
|
|
420
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
311
|
+
let file = program.setFile({ src: `${testHelpers_spec_2.rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
421
312
|
sub Main()
|
|
422
313
|
'bs:disable-next-line
|
|
423
314
|
name = "bob
|
|
424
315
|
end sub
|
|
425
316
|
`);
|
|
426
|
-
(0,
|
|
427
|
-
(0,
|
|
317
|
+
(0, chai_config_spec_1.expect)(file.commentFlags[0]).to.exist;
|
|
318
|
+
(0, chai_config_spec_1.expect)(file.commentFlags[0]).to.deep.include({
|
|
428
319
|
codes: null,
|
|
429
320
|
range: vscode_languageserver_1.Range.create(2, 24, 2, 45),
|
|
430
321
|
affectedRange: util_1.default.createRange(3, 0, 3, Number.MAX_SAFE_INTEGER)
|
|
@@ -434,14 +325,14 @@ describe('BrsFile', () => {
|
|
|
434
325
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
435
326
|
});
|
|
436
327
|
it('works for specific codes', () => {
|
|
437
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
328
|
+
let file = program.setFile({ src: `${testHelpers_spec_2.rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
438
329
|
sub Main()
|
|
439
330
|
'bs:disable-next-line: 1083, 1001
|
|
440
331
|
name = "bob
|
|
441
332
|
end sub
|
|
442
333
|
`);
|
|
443
|
-
(0,
|
|
444
|
-
(0,
|
|
334
|
+
(0, chai_config_spec_1.expect)(file.commentFlags[0]).to.exist;
|
|
335
|
+
(0, chai_config_spec_1.expect)(file.commentFlags[0]).to.deep.include({
|
|
445
336
|
codes: [1083, 1001],
|
|
446
337
|
range: vscode_languageserver_1.Range.create(2, 24, 2, 57),
|
|
447
338
|
affectedRange: util_1.default.createRange(3, 0, 3, Number.MAX_SAFE_INTEGER)
|
|
@@ -450,13 +341,13 @@ describe('BrsFile', () => {
|
|
|
450
341
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
451
342
|
});
|
|
452
343
|
it('recognizes non-numeric codes', () => {
|
|
453
|
-
let file = program.setFile('source/main.brs', `
|
|
344
|
+
let file = program.setFile({ src: `${testHelpers_spec_2.rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
454
345
|
sub Main()
|
|
455
346
|
'bs:disable-next-line: LINT9999
|
|
456
347
|
name = "bob
|
|
457
348
|
end sub
|
|
458
|
-
|
|
459
|
-
(0,
|
|
349
|
+
`);
|
|
350
|
+
(0, chai_config_spec_1.expect)(file.commentFlags[0]).to.exist;
|
|
460
351
|
(0, testHelpers_spec_1.expectHasDiagnostics)(program);
|
|
461
352
|
});
|
|
462
353
|
it('supports disabling non-numeric error codes', () => {
|
|
@@ -465,35 +356,35 @@ describe('BrsFile', () => {
|
|
|
465
356
|
sub main()
|
|
466
357
|
something = true 'bs:disable-line: LINT1005
|
|
467
358
|
end sub
|
|
468
|
-
|
|
469
|
-
file.
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
359
|
+
`);
|
|
360
|
+
file.diagnostics.push({
|
|
361
|
+
code: 'LINT1005',
|
|
362
|
+
file: file,
|
|
363
|
+
message: 'Something is not right',
|
|
364
|
+
range: util_1.default.createRange(2, 16, 2, 26)
|
|
365
|
+
});
|
|
475
366
|
const scope = program.getScopesForFile(file)[0];
|
|
476
367
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(scope);
|
|
477
368
|
});
|
|
478
369
|
it('adds diagnostics for unknown numeric diagnostic codes', () => {
|
|
479
|
-
program.setFile(
|
|
370
|
+
program.setFile('source/main.brs', `
|
|
480
371
|
sub main()
|
|
481
372
|
print "hi" 'bs:disable-line: 123456 999999 aaaab
|
|
482
373
|
end sub
|
|
483
|
-
|
|
374
|
+
`);
|
|
484
375
|
program.validate();
|
|
485
376
|
(0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unknownDiagnosticCode(123456)), { range: vscode_languageserver_1.Range.create(2, 53, 2, 59) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unknownDiagnosticCode(999999)), { range: vscode_languageserver_1.Range.create(2, 60, 2, 66) })]);
|
|
486
377
|
});
|
|
487
378
|
});
|
|
488
379
|
describe('bs:disable-line', () => {
|
|
489
380
|
it('works for all', () => {
|
|
490
|
-
let file = program.setFile({ src: `${rootDir}
|
|
381
|
+
let file = program.setFile({ src: `${testHelpers_spec_2.rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
491
382
|
sub Main()
|
|
492
383
|
z::;;%%%%%% 'bs:disable-line
|
|
493
384
|
end sub
|
|
494
385
|
`);
|
|
495
|
-
(0,
|
|
496
|
-
(0,
|
|
386
|
+
(0, chai_config_spec_1.expect)(file.commentFlags[0]).to.exist;
|
|
387
|
+
(0, chai_config_spec_1.expect)(file.commentFlags[0]).to.deep.include({
|
|
497
388
|
codes: null,
|
|
498
389
|
range: vscode_languageserver_1.Range.create(2, 36, 2, 52),
|
|
499
390
|
affectedRange: vscode_languageserver_1.Range.create(2, 0, 2, 36)
|
|
@@ -503,7 +394,7 @@ describe('BrsFile', () => {
|
|
|
503
394
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
504
395
|
});
|
|
505
396
|
it('works for specific codes', () => {
|
|
506
|
-
program.setFile(
|
|
397
|
+
program.setFile('source/main.brs', `
|
|
507
398
|
sub main()
|
|
508
399
|
'should not have any errors
|
|
509
400
|
DoSomething(1) 'bs:disable-line:1002
|
|
@@ -522,12 +413,12 @@ describe('BrsFile', () => {
|
|
|
522
413
|
//the current version of BRS causes parse errors after the `parse` keyword, showing error in comments
|
|
523
414
|
//the program should ignore all diagnostics found in brs:* comment lines EXCEPT
|
|
524
415
|
//for the diagnostics about using unknown error codes
|
|
525
|
-
program.setFile(
|
|
416
|
+
program.setFile('source/main.brs', `
|
|
526
417
|
sub main()
|
|
527
418
|
stop 'bs:disable-line
|
|
528
419
|
print "need a valid line to fix stop error"
|
|
529
420
|
end sub
|
|
530
|
-
|
|
421
|
+
`);
|
|
531
422
|
program.validate();
|
|
532
423
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
533
424
|
});
|
|
@@ -574,9 +465,9 @@ describe('BrsFile', () => {
|
|
|
574
465
|
it('supports iife in assignment', () => {
|
|
575
466
|
program.setFile('source/main.brs', `
|
|
576
467
|
sub main()
|
|
577
|
-
|
|
468
|
+
result = sub()
|
|
578
469
|
end sub()
|
|
579
|
-
|
|
470
|
+
result = (sub()
|
|
580
471
|
end sub)()
|
|
581
472
|
end sub
|
|
582
473
|
`);
|
|
@@ -585,7 +476,7 @@ describe('BrsFile', () => {
|
|
|
585
476
|
it('uses the proper parse mode based on file extension', () => {
|
|
586
477
|
function testParseMode(destPath, expectedParseMode) {
|
|
587
478
|
const file = program.setFile(destPath, '');
|
|
588
|
-
(0,
|
|
479
|
+
(0, chai_config_spec_1.expect)(file.parseMode).to.equal(expectedParseMode);
|
|
589
480
|
}
|
|
590
481
|
testParseMode('source/main.brs', Parser_1.ParseMode.BrightScript);
|
|
591
482
|
testParseMode('source/main.spec.brs', Parser_1.ParseMode.BrightScript);
|
|
@@ -595,26 +486,46 @@ describe('BrsFile', () => {
|
|
|
595
486
|
testParseMode('source/main.spec.bs', Parser_1.ParseMode.BrighterScript);
|
|
596
487
|
});
|
|
597
488
|
it('supports labels and goto statements', () => {
|
|
598
|
-
let file = program.setFile(
|
|
489
|
+
let file = program.setFile('source/main.brs', `
|
|
599
490
|
sub Main()
|
|
600
491
|
'multiple goto statements on one line
|
|
601
|
-
goto myLabel: goto myLabel
|
|
492
|
+
goto myLabel : goto myLabel
|
|
602
493
|
myLabel:
|
|
603
494
|
end sub
|
|
604
495
|
`);
|
|
605
496
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
606
497
|
});
|
|
607
498
|
it('supports empty print statements', () => {
|
|
608
|
-
let file = program.setFile(
|
|
499
|
+
let file = program.setFile('source/main.brs', `
|
|
609
500
|
sub main()
|
|
610
|
-
|
|
501
|
+
print
|
|
611
502
|
end sub
|
|
612
503
|
`);
|
|
613
504
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
614
505
|
});
|
|
615
506
|
describe('conditional compile', () => {
|
|
507
|
+
it('supports case-insensitive bs_const variables', () => {
|
|
508
|
+
fsExtra.outputFileSync(`${testHelpers_spec_2.rootDir}/manifest`, (0, undent_1.default) `
|
|
509
|
+
bs_const=SomeKey=true
|
|
510
|
+
`);
|
|
511
|
+
program.setFile('source/main.brs', `
|
|
512
|
+
sub something()
|
|
513
|
+
#if somekey
|
|
514
|
+
print "lower"
|
|
515
|
+
#end if
|
|
516
|
+
#if SOMEKEY
|
|
517
|
+
print "UPPER"
|
|
518
|
+
#end if
|
|
519
|
+
#if SomeKey
|
|
520
|
+
print "MiXeD"
|
|
521
|
+
#end if
|
|
522
|
+
end sub
|
|
523
|
+
`);
|
|
524
|
+
program.validate();
|
|
525
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
526
|
+
});
|
|
616
527
|
it('works for upper case keywords', () => {
|
|
617
|
-
let file = program.setFile(
|
|
528
|
+
let file = program.setFile('source/main.brs', `
|
|
618
529
|
sub main()
|
|
619
530
|
#CONST someFlag = true
|
|
620
531
|
#IF someFlag
|
|
@@ -629,7 +540,7 @@ describe('BrsFile', () => {
|
|
|
629
540
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
630
541
|
});
|
|
631
542
|
it('supports single-word #elseif and #endif', () => {
|
|
632
|
-
let file = program.setFile(
|
|
543
|
+
let file = program.setFile('source/main.brs', `
|
|
633
544
|
sub main()
|
|
634
545
|
#const someFlag = true
|
|
635
546
|
#if someFlag
|
|
@@ -642,7 +553,7 @@ describe('BrsFile', () => {
|
|
|
642
553
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
643
554
|
});
|
|
644
555
|
it('supports multi-word #else if and #end if', () => {
|
|
645
|
-
let file = program.setFile(
|
|
556
|
+
let file = program.setFile('source/main.brs', `
|
|
646
557
|
sub main()
|
|
647
558
|
#const someFlag = true
|
|
648
559
|
#if someFlag
|
|
@@ -655,17 +566,17 @@ describe('BrsFile', () => {
|
|
|
655
566
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
656
567
|
});
|
|
657
568
|
it('does not choke on invalid code inside a false conditional compile', () => {
|
|
658
|
-
let file = program.setFile(
|
|
569
|
+
let file = program.setFile('source/main.brs', `
|
|
659
570
|
sub main()
|
|
660
571
|
#if false
|
|
661
|
-
non
|
|
572
|
+
non-commented code here should not cause parse errors
|
|
662
573
|
#end if
|
|
663
574
|
end sub
|
|
664
575
|
`);
|
|
665
576
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
666
577
|
});
|
|
667
578
|
it('detects syntax error in #if', () => {
|
|
668
|
-
let file = program.setFile(
|
|
579
|
+
let file = program.setFile('source/main.brs', `
|
|
669
580
|
sub main()
|
|
670
581
|
#if true1
|
|
671
582
|
print "true"
|
|
@@ -677,7 +588,7 @@ describe('BrsFile', () => {
|
|
|
677
588
|
]);
|
|
678
589
|
});
|
|
679
590
|
it('detects syntax error in #const', () => {
|
|
680
|
-
let file = program.setFile(
|
|
591
|
+
let file = program.setFile('source/main.brs', `
|
|
681
592
|
sub main()
|
|
682
593
|
#if %
|
|
683
594
|
print "true"
|
|
@@ -690,7 +601,7 @@ describe('BrsFile', () => {
|
|
|
690
601
|
]);
|
|
691
602
|
});
|
|
692
603
|
it('detects #const name using reserved word', () => {
|
|
693
|
-
let file = program.setFile(
|
|
604
|
+
let file = program.setFile('source/main.brs', `
|
|
694
605
|
sub main()
|
|
695
606
|
#const function = true
|
|
696
607
|
end sub
|
|
@@ -701,7 +612,7 @@ describe('BrsFile', () => {
|
|
|
701
612
|
]);
|
|
702
613
|
});
|
|
703
614
|
it('detects syntax error in #const', () => {
|
|
704
|
-
let file = program.setFile(
|
|
615
|
+
let file = program.setFile('source/main.brs', `
|
|
705
616
|
sub main()
|
|
706
617
|
#const someConst = 123
|
|
707
618
|
end sub
|
|
@@ -712,22 +623,22 @@ describe('BrsFile', () => {
|
|
|
712
623
|
});
|
|
713
624
|
});
|
|
714
625
|
it('supports stop statement', () => {
|
|
715
|
-
let file = program.setFile(
|
|
626
|
+
let file = program.setFile('source/main.brs', `
|
|
716
627
|
sub main()
|
|
717
|
-
|
|
628
|
+
stop
|
|
718
629
|
end sub
|
|
719
630
|
`);
|
|
720
631
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
721
632
|
});
|
|
722
633
|
it('supports single-line if statements', () => {
|
|
723
|
-
let file = program.setFile(
|
|
634
|
+
let file = program.setFile('source/main.brs', `
|
|
724
635
|
sub main()
|
|
725
636
|
if 1 < 2: return true: end if
|
|
726
637
|
if 1 < 2: return true
|
|
727
638
|
end if
|
|
728
639
|
if false : print "true" : end if
|
|
729
640
|
if true: print "8 worked": else if true: print "not run": else: print "not run": end if
|
|
730
|
-
if true then: test = sub() : print "yes" : end sub: end if
|
|
641
|
+
if true then : test = sub() : print "yes" : end sub : end if
|
|
731
642
|
end sub
|
|
732
643
|
`);
|
|
733
644
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
@@ -812,7 +723,7 @@ describe('BrsFile', () => {
|
|
|
812
723
|
print &he2
|
|
813
724
|
print 1.2E+2
|
|
814
725
|
print 2!
|
|
815
|
-
print 12D
|
|
726
|
+
print 12D-12
|
|
816
727
|
print 2.3#
|
|
817
728
|
print &hFEDCBA9876543210&
|
|
818
729
|
print 9876543210&
|
|
@@ -828,7 +739,7 @@ describe('BrsFile', () => {
|
|
|
828
739
|
`);
|
|
829
740
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
830
741
|
});
|
|
831
|
-
it('does not lose function
|
|
742
|
+
it('does not lose function scopes when mismatched end sub', () => {
|
|
832
743
|
file.parse(`
|
|
833
744
|
sub main()
|
|
834
745
|
sayHi()
|
|
@@ -838,7 +749,7 @@ describe('BrsFile', () => {
|
|
|
838
749
|
print "hello world"
|
|
839
750
|
end sub
|
|
840
751
|
`);
|
|
841
|
-
(0,
|
|
752
|
+
(0, chai_config_spec_1.expect)(file.functionScopes).to.be.lengthOf(2);
|
|
842
753
|
});
|
|
843
754
|
it('does not lose sub scope when mismatched end function', () => {
|
|
844
755
|
file.parse(`
|
|
@@ -850,7 +761,7 @@ describe('BrsFile', () => {
|
|
|
850
761
|
print "hello world"
|
|
851
762
|
end sub
|
|
852
763
|
`);
|
|
853
|
-
(0,
|
|
764
|
+
(0, chai_config_spec_1.expect)(file.functionScopes).to.be.lengthOf(2);
|
|
854
765
|
});
|
|
855
766
|
it('does not error with boolean in RHS of set statement', () => {
|
|
856
767
|
file.parse(`
|
|
@@ -879,11 +790,11 @@ describe('BrsFile', () => {
|
|
|
879
790
|
it('supports variable names ending with type designators', () => {
|
|
880
791
|
file.parse(`
|
|
881
792
|
sub main()
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
793
|
+
name$ = "bob"
|
|
794
|
+
age% = 1
|
|
795
|
+
height! = 5.5
|
|
796
|
+
salary# = 9.87654321
|
|
797
|
+
someHex& = 13
|
|
887
798
|
end sub
|
|
888
799
|
`);
|
|
889
800
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
@@ -893,7 +804,7 @@ describe('BrsFile', () => {
|
|
|
893
804
|
sub main()
|
|
894
805
|
if true then
|
|
895
806
|
print "true"
|
|
896
|
-
else
|
|
807
|
+
else if true then
|
|
897
808
|
print "also true"
|
|
898
809
|
end if
|
|
899
810
|
end sub
|
|
@@ -904,9 +815,9 @@ describe('BrsFile', () => {
|
|
|
904
815
|
file.parse(`
|
|
905
816
|
function GetObject()
|
|
906
817
|
obj = {
|
|
907
|
-
|
|
818
|
+
stop: function() as void
|
|
908
819
|
|
|
909
|
-
|
|
820
|
+
end function
|
|
910
821
|
}
|
|
911
822
|
return obj
|
|
912
823
|
end function
|
|
@@ -917,10 +828,10 @@ describe('BrsFile', () => {
|
|
|
917
828
|
file.parse(`
|
|
918
829
|
function GetObject()
|
|
919
830
|
obj = {
|
|
920
|
-
run: function
|
|
831
|
+
run: function() as void
|
|
921
832
|
|
|
922
833
|
end function
|
|
923
|
-
|
|
834
|
+
}
|
|
924
835
|
return obj
|
|
925
836
|
end function
|
|
926
837
|
`);
|
|
@@ -948,7 +859,7 @@ describe('BrsFile', () => {
|
|
|
948
859
|
function Main()
|
|
949
860
|
promise = {
|
|
950
861
|
then: sub()
|
|
951
|
-
|
|
862
|
+
end sub
|
|
952
863
|
}
|
|
953
864
|
promise.then()
|
|
954
865
|
end function
|
|
@@ -958,7 +869,8 @@ describe('BrsFile', () => {
|
|
|
958
869
|
it('supports function as parameter type', () => {
|
|
959
870
|
file.parse(`
|
|
960
871
|
sub Main()
|
|
961
|
-
doWork = function
|
|
872
|
+
doWork = function(callback as function)
|
|
873
|
+
callback()
|
|
962
874
|
end function
|
|
963
875
|
end sub
|
|
964
876
|
`);
|
|
@@ -1074,7 +986,7 @@ describe('BrsFile', () => {
|
|
|
1074
986
|
sub main()
|
|
1075
987
|
end sub
|
|
1076
988
|
import "file.brs"
|
|
1077
|
-
|
|
989
|
+
`);
|
|
1078
990
|
program.validate();
|
|
1079
991
|
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1080
992
|
DiagnosticMessages_1.DiagnosticMessages.importStatementMustBeDeclaredAtTopOfFile()
|
|
@@ -1111,7 +1023,7 @@ describe('BrsFile', () => {
|
|
|
1111
1023
|
it('supports colons as separators in associative array properties', () => {
|
|
1112
1024
|
file.parse(`
|
|
1113
1025
|
sub Main()
|
|
1114
|
-
obj = {
|
|
1026
|
+
obj = {x:0 : y: 1}
|
|
1115
1027
|
end sub
|
|
1116
1028
|
`);
|
|
1117
1029
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
@@ -1122,47 +1034,59 @@ describe('BrsFile', () => {
|
|
|
1122
1034
|
return value.subType()
|
|
1123
1035
|
end function
|
|
1124
1036
|
`);
|
|
1125
|
-
(0,
|
|
1037
|
+
(0, chai_config_spec_1.expect)(file.callables[0]).to.deep.include({
|
|
1126
1038
|
file: file,
|
|
1127
1039
|
nameRange: vscode_languageserver_1.Range.create(1, 25, 1, 36)
|
|
1128
1040
|
});
|
|
1129
1041
|
});
|
|
1130
1042
|
it('succeeds when finding variables with the word "function" in them', () => {
|
|
1131
1043
|
file.parse(`
|
|
1132
|
-
|
|
1133
|
-
|
|
1044
|
+
function Test()
|
|
1045
|
+
typeCheckFunction = RBS_CMN_GetFunction(invalid, methodName)
|
|
1134
1046
|
end function
|
|
1135
1047
|
`);
|
|
1136
1048
|
});
|
|
1137
1049
|
it('finds line and column numbers for functions', () => {
|
|
1138
|
-
let file = new BrsFile_1.BrsFile(
|
|
1050
|
+
let file = new BrsFile_1.BrsFile({
|
|
1051
|
+
srcPath: 'absolute_path/file.brs',
|
|
1052
|
+
destPath: 'relative_path/file.brs',
|
|
1053
|
+
program: program
|
|
1054
|
+
});
|
|
1139
1055
|
file.parse(`
|
|
1140
1056
|
function DoA()
|
|
1141
1057
|
print "A"
|
|
1142
1058
|
end function
|
|
1143
1059
|
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1060
|
+
function DoB()
|
|
1061
|
+
print "B"
|
|
1062
|
+
end function
|
|
1147
1063
|
`);
|
|
1148
|
-
(0,
|
|
1149
|
-
(0,
|
|
1150
|
-
(0,
|
|
1151
|
-
(0,
|
|
1064
|
+
(0, chai_config_spec_1.expect)(file.callables[0].name).to.equal('DoA');
|
|
1065
|
+
(0, chai_config_spec_1.expect)(file.callables[0].nameRange).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 28));
|
|
1066
|
+
(0, chai_config_spec_1.expect)(file.callables[1].name).to.equal('DoB');
|
|
1067
|
+
(0, chai_config_spec_1.expect)(file.callables[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 26, 5, 29));
|
|
1152
1068
|
});
|
|
1153
1069
|
it('throws an error if the file has already been parsed', () => {
|
|
1154
|
-
let file = new BrsFile_1.BrsFile(
|
|
1070
|
+
let file = new BrsFile_1.BrsFile({
|
|
1071
|
+
srcPath: 'abspath',
|
|
1072
|
+
destPath: 'relpath',
|
|
1073
|
+
program: program
|
|
1074
|
+
});
|
|
1155
1075
|
file.parse(`'a comment`);
|
|
1156
1076
|
try {
|
|
1157
1077
|
file.parse(`'a new comment`);
|
|
1158
|
-
|
|
1078
|
+
chai_config_spec_1.assert.fail(null, null, 'Should have thrown an exception, but did not');
|
|
1159
1079
|
}
|
|
1160
1080
|
catch (e) {
|
|
1161
1081
|
//test passes
|
|
1162
1082
|
}
|
|
1163
1083
|
});
|
|
1164
1084
|
it('finds and registers duplicate callables', () => {
|
|
1165
|
-
let file = new BrsFile_1.BrsFile(
|
|
1085
|
+
let file = new BrsFile_1.BrsFile({
|
|
1086
|
+
srcPath: 'absolute_path/file.brs',
|
|
1087
|
+
destPath: 'relative_path/file.brs',
|
|
1088
|
+
program: program
|
|
1089
|
+
});
|
|
1166
1090
|
file.parse(`
|
|
1167
1091
|
function DoA()
|
|
1168
1092
|
print "A"
|
|
@@ -1172,14 +1096,18 @@ describe('BrsFile', () => {
|
|
|
1172
1096
|
print "A"
|
|
1173
1097
|
end function
|
|
1174
1098
|
`);
|
|
1175
|
-
(0,
|
|
1176
|
-
(0,
|
|
1177
|
-
(0,
|
|
1178
|
-
(0,
|
|
1179
|
-
(0,
|
|
1099
|
+
(0, chai_config_spec_1.expect)(file.callables.length).to.equal(2);
|
|
1100
|
+
(0, chai_config_spec_1.expect)(file.callables[0].name).to.equal('DoA');
|
|
1101
|
+
(0, chai_config_spec_1.expect)(file.callables[0].nameRange.start.line).to.equal(1);
|
|
1102
|
+
(0, chai_config_spec_1.expect)(file.callables[1].name).to.equal('DoA');
|
|
1103
|
+
(0, chai_config_spec_1.expect)(file.callables[1].nameRange.start.line).to.equal(5);
|
|
1180
1104
|
});
|
|
1181
1105
|
it('finds function call line and column numbers', () => {
|
|
1182
|
-
let file = new BrsFile_1.BrsFile(
|
|
1106
|
+
let file = new BrsFile_1.BrsFile({
|
|
1107
|
+
srcPath: 'absolute_path/file.brs',
|
|
1108
|
+
destPath: 'relative_path/file.brs',
|
|
1109
|
+
program: program
|
|
1110
|
+
});
|
|
1183
1111
|
file.parse(`
|
|
1184
1112
|
function DoA()
|
|
1185
1113
|
DoB("a")
|
|
@@ -1188,24 +1116,59 @@ describe('BrsFile', () => {
|
|
|
1188
1116
|
DoC()
|
|
1189
1117
|
end function
|
|
1190
1118
|
`);
|
|
1191
|
-
(0,
|
|
1192
|
-
(0,
|
|
1193
|
-
(0,
|
|
1194
|
-
(0,
|
|
1195
|
-
(0,
|
|
1119
|
+
(0, chai_config_spec_1.expect)(file.functionCalls.length).to.equal(2);
|
|
1120
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[0].range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 28));
|
|
1121
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[0].nameRange).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 23));
|
|
1122
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[1].range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 25));
|
|
1123
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 23));
|
|
1124
|
+
});
|
|
1125
|
+
it('finds function calls that are unfinished', () => {
|
|
1126
|
+
let file = new BrsFile_1.BrsFile({
|
|
1127
|
+
srcPath: 'absolute_path/file.brs',
|
|
1128
|
+
destPath: 'relative_path/file.brs',
|
|
1129
|
+
program: program
|
|
1130
|
+
});
|
|
1131
|
+
file.parse(`
|
|
1132
|
+
function DoA()
|
|
1133
|
+
DoB("a"
|
|
1134
|
+
end function
|
|
1135
|
+
function DoB(a as string)
|
|
1136
|
+
DoC(
|
|
1137
|
+
end function
|
|
1138
|
+
`);
|
|
1139
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file.parser.diagnostics, [
|
|
1140
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(),
|
|
1141
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon(),
|
|
1142
|
+
DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('end function'),
|
|
1143
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(),
|
|
1144
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon()
|
|
1145
|
+
]);
|
|
1146
|
+
(0, chai_config_spec_1.expect)(file.functionCalls.length).to.equal(2);
|
|
1147
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[0].range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 27));
|
|
1148
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[0].nameRange).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 23));
|
|
1149
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[1].range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 24));
|
|
1150
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 23));
|
|
1196
1151
|
});
|
|
1197
1152
|
it('sanitizes brs errors', () => {
|
|
1198
|
-
let file = new BrsFile_1.BrsFile(
|
|
1153
|
+
let file = new BrsFile_1.BrsFile({
|
|
1154
|
+
srcPath: 'absolute_path/file.brs',
|
|
1155
|
+
destPath: 'relative_path/file.brs',
|
|
1156
|
+
program: program
|
|
1157
|
+
});
|
|
1199
1158
|
file.parse(`
|
|
1200
1159
|
function DoSomething
|
|
1201
1160
|
end function
|
|
1202
1161
|
`);
|
|
1203
1162
|
(0, testHelpers_spec_1.expectHasDiagnostics)(file);
|
|
1204
|
-
(0,
|
|
1205
|
-
(0,
|
|
1163
|
+
(0, chai_config_spec_1.expect)(file.getDiagnostics()[0].file).to.equal(file);
|
|
1164
|
+
(0, chai_config_spec_1.expect)(file.getDiagnostics()[0].range.start.line).to.equal(1);
|
|
1206
1165
|
});
|
|
1207
1166
|
it('supports using the `next` keyword in a for loop', () => {
|
|
1208
|
-
let file = new BrsFile_1.BrsFile(
|
|
1167
|
+
let file = new BrsFile_1.BrsFile({
|
|
1168
|
+
srcPath: 'absolute_path/file.brs',
|
|
1169
|
+
destPath: 'relative_path/file.brs',
|
|
1170
|
+
program: program
|
|
1171
|
+
});
|
|
1209
1172
|
file.parse(`
|
|
1210
1173
|
sub countit()
|
|
1211
1174
|
for each num in [1,2,3]
|
|
@@ -1217,7 +1180,11 @@ describe('BrsFile', () => {
|
|
|
1217
1180
|
});
|
|
1218
1181
|
//test is not working yet, but will be enabled when brs supports this syntax
|
|
1219
1182
|
it('supports assigning functions to objects', () => {
|
|
1220
|
-
let file = new BrsFile_1.BrsFile(
|
|
1183
|
+
let file = new BrsFile_1.BrsFile({
|
|
1184
|
+
srcPath: 'absolute_path/file.brs',
|
|
1185
|
+
destPath: 'relative_path/file.brs',
|
|
1186
|
+
program: program
|
|
1187
|
+
});
|
|
1221
1188
|
file.parse(`
|
|
1222
1189
|
function main()
|
|
1223
1190
|
o = CreateObject("roAssociativeArray")
|
|
@@ -1228,20 +1195,42 @@ describe('BrsFile', () => {
|
|
|
1228
1195
|
`);
|
|
1229
1196
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
1230
1197
|
});
|
|
1198
|
+
it('supports parameter types in functions in AA literals', () => {
|
|
1199
|
+
program.setFile('source/main.brs', `
|
|
1200
|
+
sub main()
|
|
1201
|
+
aa = {
|
|
1202
|
+
name: "test"
|
|
1203
|
+
addInts: function(a as integer, b as integer) as integer
|
|
1204
|
+
return a + b
|
|
1205
|
+
end function
|
|
1206
|
+
}
|
|
1207
|
+
end sub
|
|
1208
|
+
`);
|
|
1209
|
+
program.validate();
|
|
1210
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
1211
|
+
});
|
|
1231
1212
|
});
|
|
1232
1213
|
describe('findCallables', () => {
|
|
1233
1214
|
it('finds range', () => {
|
|
1234
|
-
let file = new BrsFile_1.BrsFile(
|
|
1215
|
+
let file = new BrsFile_1.BrsFile({
|
|
1216
|
+
srcPath: 'absolute_path/file.brs',
|
|
1217
|
+
destPath: 'relative_path/file.brs',
|
|
1218
|
+
program: program
|
|
1219
|
+
});
|
|
1235
1220
|
file.parse(`
|
|
1236
1221
|
sub Sum()
|
|
1237
1222
|
print "hello world"
|
|
1238
1223
|
end sub
|
|
1239
1224
|
`);
|
|
1240
1225
|
let callable = file.callables[0];
|
|
1241
|
-
(0,
|
|
1226
|
+
(0, chai_config_spec_1.expect)(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 3, 23));
|
|
1242
1227
|
});
|
|
1243
1228
|
it('finds correct body range even with inner function', () => {
|
|
1244
|
-
let file = new BrsFile_1.BrsFile(
|
|
1229
|
+
let file = new BrsFile_1.BrsFile({
|
|
1230
|
+
srcPath: 'absolute_path/file.brs',
|
|
1231
|
+
destPath: 'relative_path/file.brs',
|
|
1232
|
+
program: program
|
|
1233
|
+
});
|
|
1245
1234
|
file.parse(`
|
|
1246
1235
|
sub Sum()
|
|
1247
1236
|
sayHi = sub()
|
|
@@ -1251,101 +1240,117 @@ describe('BrsFile', () => {
|
|
|
1251
1240
|
end sub
|
|
1252
1241
|
`);
|
|
1253
1242
|
let callable = file.callables[0];
|
|
1254
|
-
(0,
|
|
1243
|
+
(0, chai_config_spec_1.expect)(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 6, 23));
|
|
1255
1244
|
});
|
|
1256
1245
|
it('finds callable parameters', () => {
|
|
1257
|
-
let file = new BrsFile_1.BrsFile(
|
|
1246
|
+
let file = new BrsFile_1.BrsFile({
|
|
1247
|
+
srcPath: 'absolute_path/file.brs',
|
|
1248
|
+
destPath: 'relative_path/file.brs',
|
|
1249
|
+
program: program
|
|
1250
|
+
});
|
|
1258
1251
|
file.parse(`
|
|
1259
1252
|
function Sum(a, b, c)
|
|
1260
1253
|
|
|
1261
1254
|
end function
|
|
1262
1255
|
`);
|
|
1263
1256
|
let callable = file.callables[0];
|
|
1264
|
-
(0,
|
|
1257
|
+
(0, chai_config_spec_1.expect)(callable.params[0]).to.deep.include({
|
|
1265
1258
|
name: 'a',
|
|
1266
1259
|
isOptional: false,
|
|
1267
1260
|
isRestArgument: false
|
|
1268
1261
|
});
|
|
1269
|
-
(0,
|
|
1270
|
-
(0,
|
|
1262
|
+
(0, chai_config_spec_1.expect)(callable.params[0].type).instanceof(DynamicType_1.DynamicType);
|
|
1263
|
+
(0, chai_config_spec_1.expect)(callable.params[1]).to.deep.include({
|
|
1271
1264
|
name: 'b',
|
|
1272
1265
|
isOptional: false,
|
|
1273
1266
|
isRestArgument: false
|
|
1274
1267
|
});
|
|
1275
|
-
(0,
|
|
1276
|
-
(0,
|
|
1268
|
+
(0, chai_config_spec_1.expect)(callable.params[1].type).instanceof(DynamicType_1.DynamicType);
|
|
1269
|
+
(0, chai_config_spec_1.expect)(callable.params[2]).to.deep.include({
|
|
1277
1270
|
name: 'c',
|
|
1278
1271
|
isOptional: false,
|
|
1279
1272
|
isRestArgument: false
|
|
1280
1273
|
});
|
|
1281
|
-
(0,
|
|
1274
|
+
(0, chai_config_spec_1.expect)(callable.params[2].type).instanceof(DynamicType_1.DynamicType);
|
|
1282
1275
|
});
|
|
1283
1276
|
it('finds optional parameters', () => {
|
|
1284
|
-
let file = new BrsFile_1.BrsFile(
|
|
1277
|
+
let file = new BrsFile_1.BrsFile({
|
|
1278
|
+
srcPath: 'absolute_path/file.brs',
|
|
1279
|
+
destPath: 'relative_path/file.brs',
|
|
1280
|
+
program: program
|
|
1281
|
+
});
|
|
1285
1282
|
file.parse(`
|
|
1286
1283
|
function Sum(a=2)
|
|
1287
1284
|
|
|
1288
1285
|
end function
|
|
1289
1286
|
`);
|
|
1290
1287
|
let callable = file.callables[0];
|
|
1291
|
-
(0,
|
|
1288
|
+
(0, chai_config_spec_1.expect)(callable.params[0]).to.deep.include({
|
|
1292
1289
|
name: 'a',
|
|
1293
1290
|
isOptional: true,
|
|
1294
1291
|
isRestArgument: false
|
|
1295
1292
|
});
|
|
1296
|
-
(0,
|
|
1293
|
+
(0, chai_config_spec_1.expect)(callable.params[0].type).instanceof(IntegerType_1.IntegerType);
|
|
1297
1294
|
});
|
|
1298
1295
|
it('finds parameter types', () => {
|
|
1299
|
-
let file = new BrsFile_1.BrsFile(
|
|
1296
|
+
let file = new BrsFile_1.BrsFile({
|
|
1297
|
+
srcPath: 'absolute_path/file.brs',
|
|
1298
|
+
destPath: 'relative_path/file.brs',
|
|
1299
|
+
program: program
|
|
1300
|
+
});
|
|
1300
1301
|
file.parse(`
|
|
1301
1302
|
function Sum(a, b as integer, c as string)
|
|
1302
1303
|
|
|
1303
1304
|
end function
|
|
1304
1305
|
`);
|
|
1305
1306
|
let callable = file.callables[0];
|
|
1306
|
-
(0,
|
|
1307
|
+
(0, chai_config_spec_1.expect)(callable.params[0]).to.deep.include({
|
|
1307
1308
|
name: 'a',
|
|
1308
1309
|
isOptional: false,
|
|
1309
1310
|
isRestArgument: false
|
|
1310
1311
|
});
|
|
1311
|
-
(0,
|
|
1312
|
-
(0,
|
|
1312
|
+
(0, chai_config_spec_1.expect)(callable.params[0].type).instanceof(DynamicType_1.DynamicType);
|
|
1313
|
+
(0, chai_config_spec_1.expect)(callable.params[1]).to.deep.include({
|
|
1313
1314
|
name: 'b',
|
|
1314
1315
|
isOptional: false,
|
|
1315
1316
|
isRestArgument: false
|
|
1316
1317
|
});
|
|
1317
|
-
(0,
|
|
1318
|
-
(0,
|
|
1318
|
+
(0, chai_config_spec_1.expect)(callable.params[1].type).instanceof(IntegerType_1.IntegerType);
|
|
1319
|
+
(0, chai_config_spec_1.expect)(callable.params[2]).to.deep.include({
|
|
1319
1320
|
name: 'c',
|
|
1320
1321
|
isOptional: false,
|
|
1321
1322
|
isRestArgument: false
|
|
1322
1323
|
});
|
|
1323
|
-
(0,
|
|
1324
|
+
(0, chai_config_spec_1.expect)(callable.params[2].type).instanceof(StringType_1.StringType);
|
|
1324
1325
|
});
|
|
1325
1326
|
});
|
|
1326
1327
|
describe('findCallableInvocations', () => {
|
|
1327
1328
|
it('finds arguments with literal values', () => {
|
|
1328
|
-
let file = new BrsFile_1.BrsFile(
|
|
1329
|
+
let file = new BrsFile_1.BrsFile({
|
|
1330
|
+
srcPath: 'absolute_path/file.brs',
|
|
1331
|
+
destPath: 'relative_path/file.brs',
|
|
1332
|
+
program: program
|
|
1333
|
+
});
|
|
1329
1334
|
file.parse(`
|
|
1330
1335
|
function Sum()
|
|
1331
1336
|
DoSomething("name", 12, true)
|
|
1332
1337
|
end function
|
|
1333
1338
|
`);
|
|
1334
|
-
(0,
|
|
1339
|
+
(0, chai_config_spec_1.expect)(file.functionCalls.length).to.equal(1);
|
|
1335
1340
|
const argsMap = file.functionCalls[0].args.map(arg => {
|
|
1336
1341
|
// disregard arg.expression, etc.
|
|
1337
1342
|
return { type: arg.type, range: arg.range, text: arg.text };
|
|
1338
1343
|
});
|
|
1339
|
-
(0,
|
|
1340
|
-
type:
|
|
1344
|
+
(0, chai_config_spec_1.expect)(argsMap).to.eql([{
|
|
1345
|
+
type: StringType_1.StringType.instance,
|
|
1341
1346
|
range: util_1.default.createRange(2, 32, 2, 38),
|
|
1342
1347
|
text: '"name"'
|
|
1343
1348
|
}, {
|
|
1344
|
-
type:
|
|
1349
|
+
type: IntegerType_1.IntegerType.instance,
|
|
1345
1350
|
range: util_1.default.createRange(2, 40, 2, 42),
|
|
1346
1351
|
text: '12'
|
|
1347
1352
|
}, {
|
|
1348
|
-
type:
|
|
1353
|
+
type: BooleanType_1.BooleanType.instance,
|
|
1349
1354
|
range: util_1.default.createRange(2, 44, 2, 48),
|
|
1350
1355
|
text: 'true'
|
|
1351
1356
|
}]);
|
|
@@ -1360,11 +1365,15 @@ describe('BrsFile', () => {
|
|
|
1360
1365
|
`);
|
|
1361
1366
|
program.validate();
|
|
1362
1367
|
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1363
|
-
DiagnosticMessages_1.DiagnosticMessages.
|
|
1368
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('DoesNotExist')
|
|
1364
1369
|
]);
|
|
1365
1370
|
});
|
|
1366
1371
|
it('finds arguments with variable values', () => {
|
|
1367
|
-
let file = new BrsFile_1.BrsFile(
|
|
1372
|
+
let file = new BrsFile_1.BrsFile({
|
|
1373
|
+
srcPath: 'absolute_path/file.brs',
|
|
1374
|
+
destPath: 'relative_path/file.brs',
|
|
1375
|
+
program: program
|
|
1376
|
+
});
|
|
1368
1377
|
file.parse(`
|
|
1369
1378
|
function Sum()
|
|
1370
1379
|
count = 1
|
|
@@ -1373,17 +1382,17 @@ describe('BrsFile', () => {
|
|
|
1373
1382
|
DoSomething(count, name, isAlive)
|
|
1374
1383
|
end function
|
|
1375
1384
|
`);
|
|
1376
|
-
(0,
|
|
1377
|
-
(0,
|
|
1378
|
-
type: new
|
|
1385
|
+
(0, chai_config_spec_1.expect)(file.functionCalls.length).to.equal(1);
|
|
1386
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[0].args[0]).deep.include({
|
|
1387
|
+
type: new DynamicType_1.DynamicType(),
|
|
1379
1388
|
text: 'count'
|
|
1380
1389
|
});
|
|
1381
|
-
(0,
|
|
1382
|
-
type: new
|
|
1390
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[0].args[1]).deep.include({
|
|
1391
|
+
type: new DynamicType_1.DynamicType(),
|
|
1383
1392
|
text: 'name'
|
|
1384
1393
|
});
|
|
1385
|
-
(0,
|
|
1386
|
-
type: new
|
|
1394
|
+
(0, chai_config_spec_1.expect)(file.functionCalls[0].args[2]).deep.include({
|
|
1395
|
+
type: new DynamicType_1.DynamicType(),
|
|
1387
1396
|
text: 'isAlive'
|
|
1388
1397
|
});
|
|
1389
1398
|
});
|
|
@@ -1391,32 +1400,36 @@ describe('BrsFile', () => {
|
|
|
1391
1400
|
describe('findCallables', () => {
|
|
1392
1401
|
//this test is to help with code coverage
|
|
1393
1402
|
it('skips top-level statements', () => {
|
|
1394
|
-
let file = new BrsFile_1.BrsFile(
|
|
1403
|
+
let file = new BrsFile_1.BrsFile({
|
|
1404
|
+
srcPath: 'absolute',
|
|
1405
|
+
destPath: 'relative',
|
|
1406
|
+
program: program
|
|
1407
|
+
});
|
|
1395
1408
|
file.parse('name = "Bob"');
|
|
1396
|
-
(0,
|
|
1409
|
+
(0, chai_config_spec_1.expect)(file.callables.length).to.equal(0);
|
|
1397
1410
|
});
|
|
1398
1411
|
it('finds return type', () => {
|
|
1399
1412
|
let file = program.setFile('source/main.brs', `
|
|
1400
1413
|
function DoSomething() as string
|
|
1401
1414
|
end function
|
|
1402
1415
|
`);
|
|
1403
|
-
(0,
|
|
1416
|
+
(0, chai_config_spec_1.expect)(file.callables[0]).to.deep.include({
|
|
1404
1417
|
file: file,
|
|
1405
1418
|
nameRange: vscode_languageserver_1.Range.create(1, 25, 1, 36),
|
|
1406
1419
|
name: 'DoSomething',
|
|
1407
1420
|
params: []
|
|
1408
1421
|
});
|
|
1409
|
-
(0,
|
|
1422
|
+
(0, chai_config_spec_1.expect)(file.callables[0].type.returnType).instanceof(StringType_1.StringType);
|
|
1410
1423
|
});
|
|
1411
1424
|
});
|
|
1412
|
-
describe('
|
|
1425
|
+
describe('createFunctionScopes', () => {
|
|
1413
1426
|
it('creates range properly', () => {
|
|
1414
1427
|
file.parse(`
|
|
1415
1428
|
sub Main()
|
|
1416
1429
|
name = 'bob"
|
|
1417
1430
|
end sub
|
|
1418
1431
|
`);
|
|
1419
|
-
(0,
|
|
1432
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[0].range).to.eql(vscode_languageserver_1.Range.create(1, 16, 3, 23));
|
|
1420
1433
|
});
|
|
1421
1434
|
it('creates scopes for parent and child functions', () => {
|
|
1422
1435
|
file.parse(`
|
|
@@ -1430,9 +1443,23 @@ describe('BrsFile', () => {
|
|
|
1430
1443
|
end sub)
|
|
1431
1444
|
end sub
|
|
1432
1445
|
`);
|
|
1433
|
-
(0,
|
|
1446
|
+
(0, chai_config_spec_1.expect)(file.functionScopes).to.length(3);
|
|
1447
|
+
});
|
|
1448
|
+
it('outer function does not capture inner statements', () => {
|
|
1449
|
+
file.parse(`
|
|
1450
|
+
sub Main()
|
|
1451
|
+
name = "john"
|
|
1452
|
+
sayHi = sub()
|
|
1453
|
+
age = 12
|
|
1454
|
+
end sub
|
|
1455
|
+
end sub
|
|
1456
|
+
`);
|
|
1457
|
+
let outerScope = file.getFunctionScopeAtPosition(vscode_languageserver_1.Position.create(2, 25));
|
|
1458
|
+
(0, chai_config_spec_1.expect)(outerScope.variableDeclarations).to.be.lengthOf(2);
|
|
1459
|
+
let innerScope = file.getFunctionScopeAtPosition(vscode_languageserver_1.Position.create(4, 10));
|
|
1460
|
+
(0, chai_config_spec_1.expect)(innerScope.variableDeclarations).to.be.lengthOf(1);
|
|
1434
1461
|
});
|
|
1435
|
-
it('finds variables declared in function
|
|
1462
|
+
it('finds variables declared in function scopes', () => {
|
|
1436
1463
|
file.parse(`
|
|
1437
1464
|
sub Main()
|
|
1438
1465
|
sayHi = sub()
|
|
@@ -1444,15 +1471,24 @@ describe('BrsFile', () => {
|
|
|
1444
1471
|
end sub)
|
|
1445
1472
|
end sub
|
|
1446
1473
|
`);
|
|
1447
|
-
(0,
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
]);
|
|
1453
|
-
(0,
|
|
1454
|
-
|
|
1455
|
-
|
|
1474
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations).to.be.length(1);
|
|
1475
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[0]).to.deep.include({
|
|
1476
|
+
lineIndex: 2,
|
|
1477
|
+
name: 'sayHi'
|
|
1478
|
+
});
|
|
1479
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[0].getType()).instanceof(TypedFunctionType_1.TypedFunctionType);
|
|
1480
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[1].variableDeclarations).to.be.length(1);
|
|
1481
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[1].variableDeclarations[0]).to.deep.include({
|
|
1482
|
+
lineIndex: 3,
|
|
1483
|
+
name: 'age'
|
|
1484
|
+
});
|
|
1485
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[1].variableDeclarations[0].getType()).instanceof(IntegerType_1.IntegerType);
|
|
1486
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[2].variableDeclarations).to.be.length(1);
|
|
1487
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[2].variableDeclarations[0]).to.deep.include({
|
|
1488
|
+
lineIndex: 7,
|
|
1489
|
+
name: 'name'
|
|
1490
|
+
});
|
|
1491
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[2].variableDeclarations[0].getType()).instanceof(StringType_1.StringType);
|
|
1456
1492
|
});
|
|
1457
1493
|
it('finds variable declarations inside of if statements', () => {
|
|
1458
1494
|
file.parse(`
|
|
@@ -1462,9 +1498,9 @@ describe('BrsFile', () => {
|
|
|
1462
1498
|
end if
|
|
1463
1499
|
end sub
|
|
1464
1500
|
`);
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
]);
|
|
1501
|
+
let scope = file.getFunctionScopeAtPosition(vscode_languageserver_1.Position.create(3, 0));
|
|
1502
|
+
(0, chai_config_spec_1.expect)(scope.variableDeclarations[0]).to.exist;
|
|
1503
|
+
(0, chai_config_spec_1.expect)(scope.variableDeclarations[0].name).to.equal('theLength');
|
|
1468
1504
|
});
|
|
1469
1505
|
it('finds value from global return', () => {
|
|
1470
1506
|
let file = program.setFile('source/main.brs', `
|
|
@@ -1476,21 +1512,31 @@ describe('BrsFile', () => {
|
|
|
1476
1512
|
return "bob"
|
|
1477
1513
|
end function
|
|
1478
1514
|
`);
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1515
|
+
// Types are only guaranteed after validation
|
|
1516
|
+
program.validate();
|
|
1517
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
1518
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations).to.be.length(1);
|
|
1519
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[0]).to.deep.include({
|
|
1520
|
+
lineIndex: 2,
|
|
1521
|
+
name: 'myName'
|
|
1522
|
+
});
|
|
1523
|
+
(0, testHelpers_spec_1.expectTypeToBe)(file.functionScopes[0].variableDeclarations[0].getType(), StringType_1.StringType);
|
|
1482
1524
|
});
|
|
1483
1525
|
it('finds variable type from other variable', () => {
|
|
1484
|
-
file.
|
|
1526
|
+
let file = program.setFile('source/main.brs', `
|
|
1485
1527
|
sub Main()
|
|
1486
|
-
|
|
1487
|
-
|
|
1528
|
+
name = "bob"
|
|
1529
|
+
nameCopy = name
|
|
1488
1530
|
end sub
|
|
1489
1531
|
`);
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
])
|
|
1532
|
+
// Types are only guaranteed after validation
|
|
1533
|
+
program.validate();
|
|
1534
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations).to.be.length(2);
|
|
1535
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[1]).to.deep.include({
|
|
1536
|
+
lineIndex: 3,
|
|
1537
|
+
name: 'nameCopy'
|
|
1538
|
+
});
|
|
1539
|
+
(0, testHelpers_spec_1.expectTypeToBe)(file.functionScopes[0].variableDeclarations[1].getType(), StringType_1.StringType);
|
|
1494
1540
|
});
|
|
1495
1541
|
it('sets proper range for functions', () => {
|
|
1496
1542
|
file.parse(`
|
|
@@ -1500,432 +1546,39 @@ describe('BrsFile', () => {
|
|
|
1500
1546
|
end function
|
|
1501
1547
|
end sub
|
|
1502
1548
|
`);
|
|
1503
|
-
(0,
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
]);
|
|
1549
|
+
(0, chai_config_spec_1.expect)(file.functionScopes).to.be.length(2);
|
|
1550
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[0].range).to.eql(vscode_languageserver_1.Range.create(1, 16, 5, 23));
|
|
1551
|
+
(0, chai_config_spec_1.expect)(file.functionScopes[1].range).to.eql(vscode_languageserver_1.Range.create(2, 30, 4, 32));
|
|
1507
1552
|
});
|
|
1508
1553
|
});
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
`);
|
|
1535
|
-
//hover over the `as `
|
|
1536
|
-
(0, chai_1.expect)(file.getHover(vscode_languageserver_1.Position.create(1, 31))).not.to.exist;
|
|
1537
|
-
//hover over the `string`
|
|
1538
|
-
(0, chai_1.expect)(file.getHover(vscode_languageserver_1.Position.create(1, 36))).not.to.exist;
|
|
1539
|
-
});
|
|
1540
|
-
it('finds declared function', () => {
|
|
1541
|
-
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
1542
|
-
function Main(count = 1)
|
|
1543
|
-
firstName = "bob"
|
|
1544
|
-
age = 21
|
|
1545
|
-
shoeSize = 10
|
|
1546
|
-
end function
|
|
1547
|
-
`);
|
|
1548
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(1, 28));
|
|
1549
|
-
(0, chai_1.expect)(hover).to.exist;
|
|
1550
|
-
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 29));
|
|
1551
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1552
|
-
'```brightscript',
|
|
1553
|
-
'function Main(count? as integer) as dynamic',
|
|
1554
|
-
'```'
|
|
1555
|
-
].join('\n'));
|
|
1556
|
-
});
|
|
1557
|
-
it('finds declared namespace function', () => {
|
|
1558
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1559
|
-
namespace mySpace
|
|
1560
|
-
function Main(count = 1)
|
|
1561
|
-
firstName = "bob"
|
|
1562
|
-
age = 21
|
|
1563
|
-
shoeSize = 10
|
|
1564
|
-
end function
|
|
1565
|
-
end namespace
|
|
1566
|
-
`);
|
|
1567
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(2, 28));
|
|
1568
|
-
(0, chai_1.expect)(hover).to.exist;
|
|
1569
|
-
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 25, 2, 29));
|
|
1570
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1571
|
-
'```brightscript',
|
|
1572
|
-
'function Main(count? as integer) as dynamic',
|
|
1573
|
-
'```'
|
|
1574
|
-
].join('\n'));
|
|
1575
|
-
});
|
|
1576
|
-
it('finds variable function hover in same scope', () => {
|
|
1577
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1578
|
-
sub Main()
|
|
1579
|
-
sayMyName = sub(name as string)
|
|
1580
|
-
end sub
|
|
1581
|
-
|
|
1582
|
-
sayMyName()
|
|
1583
|
-
end sub
|
|
1584
|
-
`);
|
|
1585
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(5, 24));
|
|
1586
|
-
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 29));
|
|
1587
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1588
|
-
'```brightscript',
|
|
1589
|
-
'sub (name as string) as void',
|
|
1590
|
-
'```'
|
|
1591
|
-
].join('\n'));
|
|
1592
|
-
});
|
|
1593
|
-
it('does not crash when hovering on built-in functions', async () => {
|
|
1594
|
-
let file = program.setFile('source/main.brs', `
|
|
1595
|
-
function doUcase(text)
|
|
1596
|
-
return ucase(text)
|
|
1597
|
-
end function
|
|
1598
|
-
`);
|
|
1599
|
-
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 30))).contents).to.equal([
|
|
1600
|
-
'```brightscript',
|
|
1601
|
-
'function UCase(s as string) as string',
|
|
1602
|
-
'```'
|
|
1603
|
-
].join('\n'));
|
|
1604
|
-
});
|
|
1605
|
-
it('does not crash when hovering on object method call', async () => {
|
|
1606
|
-
let file = program.setFile('source/main.brs', `
|
|
1607
|
-
function getInstr(url, text)
|
|
1608
|
-
return url.instr(text)
|
|
1609
|
-
end function
|
|
1610
|
-
`);
|
|
1611
|
-
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 35))).contents).to.equal([
|
|
1612
|
-
'```brightscript',
|
|
1613
|
-
'instr as dynamic',
|
|
1614
|
-
'```'
|
|
1615
|
-
].join('\n'));
|
|
1616
|
-
});
|
|
1617
|
-
it('finds function hover in file scope', () => {
|
|
1618
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1619
|
-
sub Main()
|
|
1620
|
-
sayMyName()
|
|
1621
|
-
end sub
|
|
1622
|
-
|
|
1623
|
-
sub sayMyName()
|
|
1624
|
-
|
|
1625
|
-
end sub
|
|
1626
|
-
`);
|
|
1627
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(2, 25));
|
|
1628
|
-
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1629
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1630
|
-
'```brightscript',
|
|
1631
|
-
'sub sayMyName() as void',
|
|
1632
|
-
'```'
|
|
1633
|
-
].join('\n'));
|
|
1634
|
-
});
|
|
1635
|
-
it('finds namespace function hover in file scope', () => {
|
|
1636
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1637
|
-
namespace mySpace
|
|
1638
|
-
sub Main()
|
|
1639
|
-
sayMyName()
|
|
1640
|
-
end sub
|
|
1641
|
-
|
|
1642
|
-
sub sayMyName()
|
|
1643
|
-
|
|
1644
|
-
end sub
|
|
1645
|
-
end namespace
|
|
1646
|
-
`);
|
|
1647
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(3, 25));
|
|
1648
|
-
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(3, 20, 3, 29));
|
|
1649
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1650
|
-
'```brightscript',
|
|
1651
|
-
'sub sayMyName() as void',
|
|
1652
|
-
'```'
|
|
1653
|
-
].join('\n'));
|
|
1654
|
-
});
|
|
1655
|
-
it('finds function hover in scope', () => {
|
|
1656
|
-
let rootDir = process.cwd();
|
|
1657
|
-
program = new Program_1.Program({
|
|
1658
|
-
rootDir: rootDir
|
|
1659
|
-
});
|
|
1660
|
-
let mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1661
|
-
sub Main()
|
|
1662
|
-
sayMyName()
|
|
1663
|
-
end sub
|
|
1664
|
-
`);
|
|
1665
|
-
program.setFile({ src: `${rootDir}/source/lib.brs`, dest: 'source/lib.brs' }, `
|
|
1666
|
-
sub sayMyName(name as string)
|
|
1667
|
-
|
|
1668
|
-
end sub
|
|
1669
|
-
`);
|
|
1670
|
-
let hover = mainFile.getHover(vscode_languageserver_1.Position.create(2, 25));
|
|
1671
|
-
(0, chai_1.expect)(hover).to.exist;
|
|
1672
|
-
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1673
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1674
|
-
'```brightscript',
|
|
1675
|
-
'sub sayMyName(name as string) as void',
|
|
1676
|
-
'```'
|
|
1677
|
-
].join('\n'));
|
|
1678
|
-
});
|
|
1679
|
-
it('finds namespace function hover in scope', () => {
|
|
1680
|
-
let rootDir = process.cwd();
|
|
1681
|
-
program = new Program_1.Program({
|
|
1682
|
-
rootDir: rootDir
|
|
1683
|
-
});
|
|
1684
|
-
let mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1685
|
-
sub Main()
|
|
1686
|
-
mySpace.sayMyName()
|
|
1687
|
-
end sub
|
|
1688
|
-
`);
|
|
1689
|
-
program.setFile({ src: `${rootDir}/source/lib.brs`, dest: 'source/lib.brs' }, `
|
|
1690
|
-
namespace mySpace
|
|
1691
|
-
sub sayMyName(name as string)
|
|
1692
|
-
end sub
|
|
1693
|
-
end namespace
|
|
1694
|
-
`);
|
|
1695
|
-
let hover = mainFile.getHover(vscode_languageserver_1.Position.create(2, 34));
|
|
1696
|
-
(0, chai_1.expect)(hover).to.exist;
|
|
1697
|
-
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 28, 2, 37));
|
|
1698
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1699
|
-
'```brightscript',
|
|
1700
|
-
'sub sayMyName(name as string) as void',
|
|
1701
|
-
'```'
|
|
1702
|
-
].join('\n'));
|
|
1703
|
-
});
|
|
1704
|
-
it('includes markdown comments in hover.', async () => {
|
|
1705
|
-
let rootDir = process.cwd();
|
|
1706
|
-
program = new Program_1.Program({
|
|
1707
|
-
rootDir: rootDir
|
|
1708
|
-
});
|
|
1709
|
-
const file = program.setFile('source/lib.brs', `
|
|
1710
|
-
'
|
|
1711
|
-
' The main function
|
|
1712
|
-
'
|
|
1713
|
-
sub main()
|
|
1714
|
-
log("hello")
|
|
1715
|
-
end sub
|
|
1716
|
-
|
|
1717
|
-
'
|
|
1718
|
-
' Prints a message to the log.
|
|
1719
|
-
' Works with *markdown* **content**
|
|
1720
|
-
'
|
|
1721
|
-
sub log(message as string)
|
|
1722
|
-
print message
|
|
1723
|
-
end sub
|
|
1724
|
-
`);
|
|
1725
|
-
//hover over log("hello")
|
|
1726
|
-
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(5, 22))).contents).to.equal([
|
|
1727
|
-
'```brightscript',
|
|
1728
|
-
'sub log(message as string) as void',
|
|
1729
|
-
'```',
|
|
1730
|
-
'***',
|
|
1731
|
-
'',
|
|
1732
|
-
' Prints a message to the log.',
|
|
1733
|
-
' Works with *markdown* **content**',
|
|
1734
|
-
''
|
|
1735
|
-
].join('\n'));
|
|
1736
|
-
//hover over sub ma|in()
|
|
1737
|
-
(0, chai_1.expect)((0, testHelpers_spec_1.trim)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(4, 22))).contents.toString())).to.equal((0, testHelpers_spec_1.trim) `
|
|
1738
|
-
\`\`\`brightscript
|
|
1739
|
-
sub main() as void
|
|
1740
|
-
\`\`\`
|
|
1741
|
-
***
|
|
1742
|
-
|
|
1743
|
-
The main function
|
|
1744
|
-
`);
|
|
1745
|
-
});
|
|
1746
|
-
it('handles mixed case `then` partions of conditionals', () => {
|
|
1747
|
-
let mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1748
|
-
sub Main()
|
|
1749
|
-
if true then
|
|
1750
|
-
print "works"
|
|
1751
|
-
end if
|
|
1752
|
-
end sub
|
|
1753
|
-
`);
|
|
1754
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1755
|
-
mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1756
|
-
sub Main()
|
|
1757
|
-
if true Then
|
|
1758
|
-
print "works"
|
|
1759
|
-
end if
|
|
1760
|
-
end sub
|
|
1761
|
-
`);
|
|
1762
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1763
|
-
mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1764
|
-
sub Main()
|
|
1765
|
-
if true THEN
|
|
1766
|
-
print "works"
|
|
1767
|
-
end if
|
|
1768
|
-
end sub
|
|
1769
|
-
`);
|
|
1770
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1771
|
-
});
|
|
1772
|
-
it('displays the context from multiple scopes', () => {
|
|
1773
|
-
let commonFile = program.setFile('source/common.brs', `
|
|
1774
|
-
sub displayPi()
|
|
1775
|
-
pi = getPi()
|
|
1776
|
-
print pi
|
|
1777
|
-
end sub
|
|
1778
|
-
`);
|
|
1779
|
-
let scope1File = program.setFile('components/comp1/scope1.brs', `
|
|
1780
|
-
function getPi() as string
|
|
1781
|
-
return "apple"
|
|
1782
|
-
end function
|
|
1783
|
-
`);
|
|
1784
|
-
(0, chai_1.expect)(scope1File.getDiagnostics()).to.be.lengthOf(0);
|
|
1785
|
-
program.setFile('components/comp1/comp1.xml', (0, testHelpers_spec_1.trim) `
|
|
1786
|
-
<?xml version="1.0" encoding="utf-8" ?>
|
|
1787
|
-
<component name="Component1" extends="Group">
|
|
1788
|
-
<script type="text/brightscript" uri="scope1.brs" />
|
|
1789
|
-
<script type="text/brightscript" uri="pkg:/source/common.brs" />
|
|
1790
|
-
</component>
|
|
1791
|
-
`);
|
|
1792
|
-
let scope2File = program.setFile('components/comp2/scope2.brs', `
|
|
1793
|
-
function getPi() as float
|
|
1794
|
-
return 3.14
|
|
1795
|
-
end function
|
|
1796
|
-
`);
|
|
1797
|
-
(0, chai_1.expect)(scope2File.getDiagnostics()).to.be.lengthOf(0);
|
|
1798
|
-
program.setFile('components/comp2/comp2.xml', (0, testHelpers_spec_1.trim) `
|
|
1799
|
-
<?xml version="1.0" encoding="utf-8" ?>
|
|
1800
|
-
<component name="Component2" extends="Group">
|
|
1801
|
-
<script type="text/brightscript" uri="scope2.brs" />
|
|
1802
|
-
<script type="text/brightscript" uri="pkg:/source/common.brs" />
|
|
1803
|
-
</component>
|
|
1804
|
-
`);
|
|
1805
|
-
program.validate();
|
|
1806
|
-
let funcCallHover = commonFile.getHover(vscode_languageserver_1.Position.create(2, 27));
|
|
1807
|
-
(0, chai_1.expect)(funcCallHover === null || funcCallHover === void 0 ? void 0 : funcCallHover.contents).to.equal([
|
|
1808
|
-
'```brightscript',
|
|
1809
|
-
'function getPi() as string | function getPi() as float | getPi as uninitialized',
|
|
1810
|
-
'```'
|
|
1811
|
-
].join('\n'));
|
|
1812
|
-
let variableHover = commonFile.getHover(vscode_languageserver_1.Position.create(3, 27));
|
|
1813
|
-
(0, chai_1.expect)(variableHover === null || variableHover === void 0 ? void 0 : variableHover.contents).to.equal([
|
|
1814
|
-
'```brightscript',
|
|
1815
|
-
'pi as string | pi as float | pi as uninitialized',
|
|
1816
|
-
'```'
|
|
1817
|
-
].join('\n'));
|
|
1818
|
-
});
|
|
1819
|
-
it('finds function with custom types as parameters and return types', () => {
|
|
1820
|
-
let file = program.setFile('source/main.bs', `
|
|
1821
|
-
sub main()
|
|
1822
|
-
k = new MyKlass()
|
|
1823
|
-
processMyKlass(k)
|
|
1824
|
-
end sub
|
|
1825
|
-
|
|
1826
|
-
function processMyKlass(data as MyKlass) as MyKlass
|
|
1827
|
-
return data
|
|
1828
|
-
end function
|
|
1829
|
-
|
|
1830
|
-
class MyKlass
|
|
1831
|
-
end class
|
|
1832
|
-
`);
|
|
1833
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(3, 29));
|
|
1834
|
-
(0, chai_1.expect)(hover).to.exist;
|
|
1835
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1836
|
-
'```brightscript',
|
|
1837
|
-
'function processMyKlass(data as MyKlass) as MyKlass',
|
|
1838
|
-
'```'
|
|
1839
|
-
].join('\n'));
|
|
1840
|
-
});
|
|
1841
|
-
it('finds function with arrays as parameters and return types', () => {
|
|
1842
|
-
let file = program.setFile('source/main.bs', `
|
|
1843
|
-
sub main()
|
|
1844
|
-
k = new MyKlass()
|
|
1845
|
-
processData([k])
|
|
1846
|
-
end sub
|
|
1847
|
-
|
|
1848
|
-
function processData(data as MyKlass[]) as MyKlass[]
|
|
1849
|
-
return data
|
|
1850
|
-
end function
|
|
1851
|
-
|
|
1852
|
-
class MyKlass
|
|
1853
|
-
end class
|
|
1854
|
-
`);
|
|
1855
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(3, 29));
|
|
1856
|
-
(0, chai_1.expect)(hover).to.exist;
|
|
1857
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1858
|
-
'```brightscript',
|
|
1859
|
-
'function processData(data as MyKlass[]) as MyKlass[]',
|
|
1860
|
-
'```'
|
|
1861
|
-
].join('\n'));
|
|
1862
|
-
});
|
|
1863
|
-
it('display literal enum members', () => {
|
|
1864
|
-
let file = program.setFile('source/main.bs', `
|
|
1865
|
-
enum MyEnum
|
|
1866
|
-
foo
|
|
1867
|
-
bar
|
|
1868
|
-
end enum
|
|
1869
|
-
|
|
1870
|
-
sub main()
|
|
1871
|
-
value = MyEnum.foo
|
|
1872
|
-
print value
|
|
1873
|
-
end sub
|
|
1874
|
-
`);
|
|
1875
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(7, 38)); // 'myEnum.foo' in value assignnmnt
|
|
1876
|
-
(0, chai_1.expect)(hover).to.exist;
|
|
1877
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1878
|
-
'```brightscript',
|
|
1879
|
-
'MyEnum.foo as MyEnum',
|
|
1880
|
-
'```'
|
|
1881
|
-
].join('\n'));
|
|
1882
|
-
});
|
|
1883
|
-
it('finds enum values from assignments', () => {
|
|
1884
|
-
let file = program.setFile('source/main.bs', `
|
|
1885
|
-
enum MyEnum
|
|
1886
|
-
foo
|
|
1887
|
-
bar
|
|
1888
|
-
end enum
|
|
1889
|
-
|
|
1890
|
-
sub main()
|
|
1891
|
-
value = MyEnum.foo
|
|
1892
|
-
print value
|
|
1893
|
-
end sub
|
|
1894
|
-
`);
|
|
1895
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(8, 30)); // 'value' in print statement
|
|
1896
|
-
(0, chai_1.expect)(hover).to.exist;
|
|
1897
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1898
|
-
'```brightscript',
|
|
1899
|
-
'value as MyEnum',
|
|
1900
|
-
'```'
|
|
1901
|
-
].join('\n'));
|
|
1902
|
-
});
|
|
1903
|
-
it('finds enum values as parameters', () => {
|
|
1904
|
-
let file = program.setFile('source/main.bs', `
|
|
1905
|
-
enum MyEnum
|
|
1906
|
-
foo
|
|
1907
|
-
bar
|
|
1908
|
-
end enum
|
|
1909
|
-
|
|
1910
|
-
sub printEnum(enumParamVal as MyEnum)
|
|
1911
|
-
print enumParamVal
|
|
1912
|
-
end sub
|
|
1913
|
-
|
|
1914
|
-
sub main()
|
|
1915
|
-
printEnum(MyEnum.foo)
|
|
1916
|
-
end sub
|
|
1917
|
-
`);
|
|
1918
|
-
let hover = file.getHover(vscode_languageserver_1.Position.create(7, 30)); // 'enumParamVal' in print statement
|
|
1919
|
-
(0, chai_1.expect)(hover).to.exist;
|
|
1920
|
-
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1921
|
-
'```brightscript',
|
|
1922
|
-
'enumParamVal as MyEnum',
|
|
1923
|
-
'```'
|
|
1924
|
-
].join('\n'));
|
|
1925
|
-
});
|
|
1554
|
+
it('handles mixed case `then` partions of conditionals', () => {
|
|
1555
|
+
let mainFile = program.setFile('source/main.brs', `
|
|
1556
|
+
sub Main()
|
|
1557
|
+
if true then
|
|
1558
|
+
print "works"
|
|
1559
|
+
end if
|
|
1560
|
+
end sub
|
|
1561
|
+
`);
|
|
1562
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1563
|
+
mainFile = program.setFile('source/main.brs', `
|
|
1564
|
+
sub Main()
|
|
1565
|
+
if true Then
|
|
1566
|
+
print "works"
|
|
1567
|
+
end if
|
|
1568
|
+
end sub
|
|
1569
|
+
`);
|
|
1570
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1571
|
+
mainFile = program.setFile('source/main.brs', `
|
|
1572
|
+
sub Main()
|
|
1573
|
+
if true THEN
|
|
1574
|
+
print "works"
|
|
1575
|
+
end if
|
|
1576
|
+
end sub
|
|
1577
|
+
`);
|
|
1578
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1926
1579
|
});
|
|
1927
1580
|
it('does not throw when encountering incomplete import statement', () => {
|
|
1928
|
-
program.setFile(
|
|
1581
|
+
program.setFile('source/main.brs', `
|
|
1929
1582
|
import
|
|
1930
1583
|
sub main()
|
|
1931
1584
|
end sub
|
|
@@ -1934,8 +1587,28 @@ describe('BrsFile', () => {
|
|
|
1934
1587
|
//this test will throw an exception if something went wrong
|
|
1935
1588
|
});
|
|
1936
1589
|
describe('transpile', () => {
|
|
1937
|
-
it('
|
|
1938
|
-
|
|
1590
|
+
it('transpilies libpkg:/ paths when encountered', async () => {
|
|
1591
|
+
program.setFile('source/lib.bs', `
|
|
1592
|
+
import "libpkg:/source/numbers.bs"
|
|
1593
|
+
`);
|
|
1594
|
+
program.setFile('source/numbers.bs', `
|
|
1595
|
+
sub test()
|
|
1596
|
+
end sub
|
|
1597
|
+
`);
|
|
1598
|
+
await testTranspile(`
|
|
1599
|
+
<component name="TestButton" extends="Group">
|
|
1600
|
+
<script type="text/brightscript" uri="libpkg:/source/lib.bs"/>
|
|
1601
|
+
</component>
|
|
1602
|
+
`, `
|
|
1603
|
+
<component name="TestButton" extends="Group">
|
|
1604
|
+
<script type="text/brightscript" uri="libpkg:/source/lib.brs" />
|
|
1605
|
+
<script type="text/brightscript" uri="pkg:/source/numbers.brs" />
|
|
1606
|
+
<script type="text/brightscript" uri="pkg:/source/bslib.brs" />
|
|
1607
|
+
</component>
|
|
1608
|
+
`, undefined, 'components/TestButton.xml');
|
|
1609
|
+
});
|
|
1610
|
+
it('excludes trailing commas in array literals', async () => {
|
|
1611
|
+
await testTranspile(`
|
|
1939
1612
|
sub main()
|
|
1940
1613
|
arr = [
|
|
1941
1614
|
1,
|
|
@@ -1963,72 +1636,79 @@ describe('BrsFile', () => {
|
|
|
1963
1636
|
end sub
|
|
1964
1637
|
`);
|
|
1965
1638
|
});
|
|
1966
|
-
it('transpiles if statement keywords as provided', () => {
|
|
1639
|
+
it('transpiles if statement keywords as provided', async () => {
|
|
1967
1640
|
const code = `
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1641
|
+
sub main()
|
|
1642
|
+
If True Then
|
|
1643
|
+
Print True
|
|
1644
|
+
Else If True Then
|
|
1645
|
+
print True
|
|
1646
|
+
Else If False Then
|
|
1647
|
+
Print False
|
|
1648
|
+
Else
|
|
1649
|
+
Print False
|
|
1650
|
+
End If
|
|
1651
|
+
end sub
|
|
1977
1652
|
`;
|
|
1978
|
-
testTranspile(code);
|
|
1979
|
-
testTranspile(code.toLowerCase());
|
|
1980
|
-
testTranspile(code.toUpperCase());
|
|
1653
|
+
await testTranspile(code);
|
|
1654
|
+
await testTranspile(code.toLowerCase());
|
|
1655
|
+
await testTranspile(code.toUpperCase());
|
|
1981
1656
|
});
|
|
1982
|
-
it('does not transpile `then` tokens', () => {
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
`;
|
|
1990
|
-
testTranspile(code);
|
|
1991
|
-
});
|
|
1992
|
-
it('honors spacing between multi-word tokens', () => {
|
|
1993
|
-
testTranspile(`
|
|
1994
|
-
if true
|
|
1995
|
-
print true
|
|
1996
|
-
elseif true
|
|
1997
|
-
print false
|
|
1998
|
-
endif
|
|
1999
|
-
`);
|
|
2000
|
-
});
|
|
2001
|
-
it('handles when only some of the statements have `then`', () => {
|
|
2002
|
-
testTranspile(`
|
|
2003
|
-
if true
|
|
2004
|
-
else if true then
|
|
2005
|
-
else if true
|
|
2006
|
-
else if true then
|
|
2007
|
-
if true then
|
|
2008
|
-
return true
|
|
1657
|
+
it('does not transpile `then` tokens', async () => {
|
|
1658
|
+
await testTranspile(`
|
|
1659
|
+
sub main()
|
|
1660
|
+
if true
|
|
1661
|
+
print true
|
|
1662
|
+
else if true
|
|
1663
|
+
print false
|
|
2009
1664
|
end if
|
|
2010
|
-
end
|
|
1665
|
+
end sub
|
|
1666
|
+
`);
|
|
1667
|
+
});
|
|
1668
|
+
it('honors spacing between multi-word tokens', async () => {
|
|
1669
|
+
await testTranspile(`
|
|
1670
|
+
sub main()
|
|
1671
|
+
if true
|
|
1672
|
+
print true
|
|
1673
|
+
elseif true
|
|
1674
|
+
print false
|
|
1675
|
+
endif
|
|
1676
|
+
end sub
|
|
2011
1677
|
`);
|
|
2012
1678
|
});
|
|
2013
|
-
it('
|
|
2014
|
-
|
|
2015
|
-
|
|
1679
|
+
it('handles when only some of the statements have `then`', async () => {
|
|
1680
|
+
await testTranspile(`
|
|
1681
|
+
sub main()
|
|
1682
|
+
if true
|
|
1683
|
+
else if true then
|
|
1684
|
+
else if true
|
|
1685
|
+
else if true then
|
|
1686
|
+
if true then
|
|
1687
|
+
return
|
|
1688
|
+
end if
|
|
1689
|
+
end if
|
|
1690
|
+
end sub
|
|
1691
|
+
`);
|
|
1692
|
+
});
|
|
1693
|
+
it('retains casing of parameter types', async () => {
|
|
1694
|
+
async function test(type) {
|
|
1695
|
+
await testTranspile(`
|
|
2016
1696
|
sub one(a as ${type}, b as ${type.toUpperCase()}, c as ${type.toLowerCase()})
|
|
2017
1697
|
end sub
|
|
2018
1698
|
`);
|
|
2019
1699
|
}
|
|
2020
|
-
test('Boolean');
|
|
2021
|
-
test('Double');
|
|
2022
|
-
test('Dynamic');
|
|
2023
|
-
test('Float');
|
|
2024
|
-
test('Integer');
|
|
2025
|
-
test('LongInteger');
|
|
2026
|
-
test('Object');
|
|
2027
|
-
test('String');
|
|
2028
|
-
});
|
|
2029
|
-
it('retains casing of return types', () => {
|
|
2030
|
-
function test(type) {
|
|
2031
|
-
testTranspile(`
|
|
1700
|
+
await test('Boolean');
|
|
1701
|
+
await test('Double');
|
|
1702
|
+
await test('Dynamic');
|
|
1703
|
+
await test('Float');
|
|
1704
|
+
await test('Integer');
|
|
1705
|
+
await test('LongInteger');
|
|
1706
|
+
await test('Object');
|
|
1707
|
+
await test('String');
|
|
1708
|
+
});
|
|
1709
|
+
it('retains casing of return types', async () => {
|
|
1710
|
+
async function test(type) {
|
|
1711
|
+
await testTranspile(`
|
|
2032
1712
|
sub one() as ${type}
|
|
2033
1713
|
end sub
|
|
2034
1714
|
|
|
@@ -2039,19 +1719,19 @@ describe('BrsFile', () => {
|
|
|
2039
1719
|
end sub
|
|
2040
1720
|
`);
|
|
2041
1721
|
}
|
|
2042
|
-
test('Boolean');
|
|
2043
|
-
test('Double');
|
|
2044
|
-
test('Dynamic');
|
|
2045
|
-
test('Float');
|
|
2046
|
-
test('Integer');
|
|
2047
|
-
test('LongInteger');
|
|
2048
|
-
test('Object');
|
|
2049
|
-
test('String');
|
|
2050
|
-
test('Void');
|
|
2051
|
-
});
|
|
2052
|
-
it('retains casing of literal types', () => {
|
|
2053
|
-
function test(type) {
|
|
2054
|
-
testTranspile(`
|
|
1722
|
+
await test('Boolean');
|
|
1723
|
+
await test('Double');
|
|
1724
|
+
await test('Dynamic');
|
|
1725
|
+
await test('Float');
|
|
1726
|
+
await test('Integer');
|
|
1727
|
+
await test('LongInteger');
|
|
1728
|
+
await test('Object');
|
|
1729
|
+
await test('String');
|
|
1730
|
+
await test('Void');
|
|
1731
|
+
});
|
|
1732
|
+
it('retains casing of literal types', async () => {
|
|
1733
|
+
async function test(type) {
|
|
1734
|
+
await testTranspile(`
|
|
2055
1735
|
sub main()
|
|
2056
1736
|
thing = ${type}
|
|
2057
1737
|
thing = ${type.toLowerCase()}
|
|
@@ -2059,13 +1739,13 @@ describe('BrsFile', () => {
|
|
|
2059
1739
|
end sub
|
|
2060
1740
|
`);
|
|
2061
1741
|
}
|
|
2062
|
-
test('Invalid');
|
|
2063
|
-
test('True');
|
|
2064
|
-
test('False');
|
|
1742
|
+
await test('Invalid');
|
|
1743
|
+
await test('True');
|
|
1744
|
+
await test('False');
|
|
2065
1745
|
});
|
|
2066
1746
|
describe('throwStatement', () => {
|
|
2067
|
-
it('transpiles properly', () => {
|
|
2068
|
-
testTranspile(`
|
|
1747
|
+
it('transpiles properly', async () => {
|
|
1748
|
+
await testTranspile(`
|
|
2069
1749
|
sub main()
|
|
2070
1750
|
try
|
|
2071
1751
|
throw "some message"
|
|
@@ -2076,11 +1756,11 @@ describe('BrsFile', () => {
|
|
|
2076
1756
|
});
|
|
2077
1757
|
});
|
|
2078
1758
|
describe('try/catch', () => {
|
|
2079
|
-
it('transpiles properly', () => {
|
|
2080
|
-
testTranspile(`
|
|
1759
|
+
it('transpiles properly', async () => {
|
|
1760
|
+
await testTranspile(`
|
|
2081
1761
|
sub main()
|
|
2082
1762
|
try
|
|
2083
|
-
print
|
|
1763
|
+
print m.b.c
|
|
2084
1764
|
catch e
|
|
2085
1765
|
print e
|
|
2086
1766
|
end try
|
|
@@ -2089,8 +1769,8 @@ describe('BrsFile', () => {
|
|
|
2089
1769
|
});
|
|
2090
1770
|
});
|
|
2091
1771
|
describe('namespaces', () => {
|
|
2092
|
-
it('properly transpiles namespace functions for assignments', () => {
|
|
2093
|
-
testTranspile(`
|
|
1772
|
+
it('properly transpiles namespace functions for assignments', async () => {
|
|
1773
|
+
await testTranspile(`
|
|
2094
1774
|
namespace NameA.NameB
|
|
2095
1775
|
sub Speak()
|
|
2096
1776
|
end sub
|
|
@@ -2098,7 +1778,7 @@ describe('BrsFile', () => {
|
|
|
2098
1778
|
sub main()
|
|
2099
1779
|
sayHello = NameA.NameB.Speak
|
|
2100
1780
|
sayHello()
|
|
2101
|
-
someOtherObject =
|
|
1781
|
+
someOtherObject = m.other.object
|
|
2102
1782
|
end sub
|
|
2103
1783
|
`, `
|
|
2104
1784
|
sub NameA_NameB_Speak()
|
|
@@ -2107,12 +1787,12 @@ describe('BrsFile', () => {
|
|
|
2107
1787
|
sub main()
|
|
2108
1788
|
sayHello = NameA_NameB_Speak
|
|
2109
1789
|
sayHello()
|
|
2110
|
-
someOtherObject =
|
|
1790
|
+
someOtherObject = m.other.object
|
|
2111
1791
|
end sub
|
|
2112
1792
|
`);
|
|
2113
1793
|
});
|
|
2114
|
-
it('properly transpiles inferred namespace function for assignment', () => {
|
|
2115
|
-
testTranspile(`
|
|
1794
|
+
it('properly transpiles inferred namespace function for assignment', async () => {
|
|
1795
|
+
await testTranspile(`
|
|
2116
1796
|
namespace NameA.NameB
|
|
2117
1797
|
sub Speak()
|
|
2118
1798
|
end sub
|
|
@@ -2132,24 +1812,47 @@ describe('BrsFile', () => {
|
|
|
2132
1812
|
`);
|
|
2133
1813
|
});
|
|
2134
1814
|
});
|
|
2135
|
-
it('includes all text to end of line for a non-terminated string', () => {
|
|
2136
|
-
testTranspile('sub main()\n name = "john \nend sub', 'sub main()\n name = "john "\nend sub', null, 'source/main.bs', false);
|
|
1815
|
+
it('includes all text to end of line for a non-terminated string', async () => {
|
|
1816
|
+
await testTranspile('sub main()\n name = "john \nend sub', 'sub main()\n name = "john "\nend sub', null, 'source/main.bs', false);
|
|
2137
1817
|
});
|
|
2138
|
-
it('escapes quotes in string literals', () => {
|
|
2139
|
-
testTranspile(`
|
|
1818
|
+
it('escapes quotes in string literals', async () => {
|
|
1819
|
+
await testTranspile(`
|
|
2140
1820
|
sub main()
|
|
1821
|
+
expected = "Hello"
|
|
2141
1822
|
expected += chr(10) + " version=""2.0"""
|
|
2142
1823
|
end sub
|
|
2143
1824
|
`);
|
|
2144
1825
|
});
|
|
2145
|
-
it('keeps function parameter types in proper order', () => {
|
|
2146
|
-
testTranspile(`
|
|
1826
|
+
it('keeps function parameter types in proper order', async () => {
|
|
1827
|
+
await testTranspile(`
|
|
2147
1828
|
function CreateTestStatistic(name as string, result = "Success" as string, time = 0 as integer, errorCode = 0 as integer, errorMessage = "" as string) as object
|
|
2148
1829
|
end function
|
|
2149
1830
|
`);
|
|
2150
1831
|
});
|
|
2151
|
-
it('
|
|
2152
|
-
|
|
1832
|
+
it('discard parameter types when removeParameterTypes is true', async () => {
|
|
1833
|
+
program.options.removeParameterTypes = true;
|
|
1834
|
+
await testTranspile(`
|
|
1835
|
+
sub one(a as integer, b = "" as string, c = invalid as dynamic)
|
|
1836
|
+
end sub
|
|
1837
|
+
`, `
|
|
1838
|
+
sub one(a, b = "", c = invalid)
|
|
1839
|
+
end sub
|
|
1840
|
+
`);
|
|
1841
|
+
});
|
|
1842
|
+
it('discard return type when removeParameterTypes is true', async () => {
|
|
1843
|
+
program.options.removeParameterTypes = true;
|
|
1844
|
+
await testTranspile(`
|
|
1845
|
+
function one() as string
|
|
1846
|
+
return ""
|
|
1847
|
+
end function
|
|
1848
|
+
`, `
|
|
1849
|
+
function one()
|
|
1850
|
+
return ""
|
|
1851
|
+
end function
|
|
1852
|
+
`);
|
|
1853
|
+
});
|
|
1854
|
+
it('transpiles local var assignment operators', async () => {
|
|
1855
|
+
await testTranspile(`
|
|
2153
1856
|
sub main()
|
|
2154
1857
|
count = 0
|
|
2155
1858
|
count += 1
|
|
@@ -2162,8 +1865,8 @@ describe('BrsFile', () => {
|
|
|
2162
1865
|
end sub
|
|
2163
1866
|
`);
|
|
2164
1867
|
});
|
|
2165
|
-
it('transpiles AA property assignment operators', () => {
|
|
2166
|
-
testTranspile(`
|
|
1868
|
+
it('transpiles AA property assignment operators', async () => {
|
|
1869
|
+
await testTranspile(`
|
|
2167
1870
|
sub main()
|
|
2168
1871
|
person = {
|
|
2169
1872
|
count: 0
|
|
@@ -2172,8 +1875,8 @@ describe('BrsFile', () => {
|
|
|
2172
1875
|
end sub
|
|
2173
1876
|
`);
|
|
2174
1877
|
});
|
|
2175
|
-
it('transpiles AA indexed assignment operators', () => {
|
|
2176
|
-
testTranspile(`
|
|
1878
|
+
it('transpiles AA indexed assignment operators', async () => {
|
|
1879
|
+
await testTranspile(`
|
|
2177
1880
|
sub main()
|
|
2178
1881
|
person = {
|
|
2179
1882
|
count: 0
|
|
@@ -2182,8 +1885,8 @@ describe('BrsFile', () => {
|
|
|
2182
1885
|
end sub
|
|
2183
1886
|
`);
|
|
2184
1887
|
});
|
|
2185
|
-
it('relative-referenced namespaced functions get prefixed', () => {
|
|
2186
|
-
testTranspile(`
|
|
1888
|
+
it('relative-referenced namespaced functions get prefixed', async () => {
|
|
1889
|
+
await testTranspile(`
|
|
2187
1890
|
namespace Vertibrates.Birds
|
|
2188
1891
|
function GetAllBirds()
|
|
2189
1892
|
return [
|
|
@@ -2213,8 +1916,8 @@ describe('BrsFile', () => {
|
|
|
2213
1916
|
end function
|
|
2214
1917
|
`, 'trim', 'source/main.bs');
|
|
2215
1918
|
});
|
|
2216
|
-
it('transpiles namespaced functions', () => {
|
|
2217
|
-
testTranspile(`
|
|
1919
|
+
it('transpiles namespaced functions', async () => {
|
|
1920
|
+
await testTranspile(`
|
|
2218
1921
|
namespace NameA
|
|
2219
1922
|
sub alert()
|
|
2220
1923
|
end sub
|
|
@@ -2230,32 +1933,47 @@ describe('BrsFile', () => {
|
|
|
2230
1933
|
end sub
|
|
2231
1934
|
`, 'trim', 'source/main.bs');
|
|
2232
1935
|
});
|
|
2233
|
-
it('transpiles dim', () => {
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
1936
|
+
it('transpiles dim', async () => {
|
|
1937
|
+
async function doTest(code) {
|
|
1938
|
+
await testTranspile(`
|
|
1939
|
+
sub main()
|
|
1940
|
+
requestList = []
|
|
1941
|
+
${code}
|
|
1942
|
+
end sub
|
|
1943
|
+
`, `
|
|
1944
|
+
sub main()
|
|
1945
|
+
requestList = []
|
|
1946
|
+
${code}
|
|
1947
|
+
end sub
|
|
1948
|
+
`);
|
|
1949
|
+
}
|
|
1950
|
+
await doTest(`Dim c[5]`);
|
|
1951
|
+
await doTest(`Dim c[5, 4]`);
|
|
1952
|
+
await doTest(`Dim c[5, 4, 6]`);
|
|
1953
|
+
await doTest(`Dim requestData[requestList.count()]`);
|
|
1954
|
+
await doTest(`Dim requestData[1, requestList.count()]`);
|
|
1955
|
+
await doTest(`Dim requestData[1, requestList.count(), 2]`);
|
|
1956
|
+
await doTest(`Dim requestData[requestList[2]]`);
|
|
1957
|
+
await doTest(`Dim requestData[1, requestList[2]]`);
|
|
1958
|
+
await doTest(`Dim requestData[1, requestList[2], 2]`);
|
|
1959
|
+
await doTest(`Dim requestData[requestList["2"]]`);
|
|
1960
|
+
await doTest(`Dim requestData[1, requestList["2"]]`);
|
|
1961
|
+
await doTest(`Dim requestData[1, requestList["2"], 2]`);
|
|
1962
|
+
await doTest(`Dim requestData[1, StrToI("1"), 2]`);
|
|
1963
|
+
await testTranspile(`
|
|
1964
|
+
function getValue(param1)
|
|
1965
|
+
end function
|
|
1966
|
+
|
|
1967
|
+
sub main()
|
|
1968
|
+
requestList = []
|
|
1969
|
+
Dim requestData[1, getValue({
|
|
1970
|
+
key: "value"
|
|
1971
|
+
}), 2]
|
|
1972
|
+
end sub
|
|
2255
1973
|
`);
|
|
2256
1974
|
});
|
|
2257
|
-
it('transpiles calls to fully-qualified namespaced functions', () => {
|
|
2258
|
-
testTranspile(`
|
|
1975
|
+
it('transpiles calls to fully-qualified namespaced functions', async () => {
|
|
1976
|
+
await testTranspile(`
|
|
2259
1977
|
namespace NameA
|
|
2260
1978
|
sub alert()
|
|
2261
1979
|
end sub
|
|
@@ -2280,15 +1998,15 @@ describe('BrsFile', () => {
|
|
|
2280
1998
|
end sub
|
|
2281
1999
|
`, 'trim', 'source/main.bs');
|
|
2282
2000
|
});
|
|
2283
|
-
it('keeps end-of-line comments with their line', () => {
|
|
2284
|
-
testTranspile(`
|
|
2001
|
+
it('keeps end-of-line comments with their line', async () => {
|
|
2002
|
+
await testTranspile(`
|
|
2285
2003
|
function DoSomething() 'comment 1
|
|
2286
2004
|
name = "bob" 'comment 2
|
|
2287
2005
|
end function 'comment 3
|
|
2288
2006
|
`);
|
|
2289
2007
|
});
|
|
2290
|
-
it('works for functions', () => {
|
|
2291
|
-
testTranspile(`
|
|
2008
|
+
it('works for functions', async () => {
|
|
2009
|
+
await testTranspile(`
|
|
2292
2010
|
function DoSomething()
|
|
2293
2011
|
'lots of empty white space
|
|
2294
2012
|
'that will be removed during transpile
|
|
@@ -2303,16 +2021,16 @@ describe('BrsFile', () => {
|
|
|
2303
2021
|
end function
|
|
2304
2022
|
`);
|
|
2305
2023
|
});
|
|
2306
|
-
it('keeps empty AAs and arrays on same line', () => {
|
|
2307
|
-
testTranspile(`
|
|
2024
|
+
it('keeps empty AAs and arrays on same line', async () => {
|
|
2025
|
+
await testTranspile(`
|
|
2308
2026
|
sub a()
|
|
2309
2027
|
person = {}
|
|
2310
2028
|
stuff = []
|
|
2311
2029
|
end sub
|
|
2312
2030
|
`, null, 'trim');
|
|
2313
2031
|
});
|
|
2314
|
-
it('does not add leading or trailing newlines', () => {
|
|
2315
|
-
testTranspile(`function abc()\nend function`, undefined, 'none');
|
|
2032
|
+
it('does not add leading or trailing newlines', async () => {
|
|
2033
|
+
await testTranspile(`function abc()\nend function`, undefined, 'none');
|
|
2316
2034
|
});
|
|
2317
2035
|
it('handles sourcemap edge case', async () => {
|
|
2318
2036
|
let source = 'sub main()\n' +
|
|
@@ -2321,18 +2039,18 @@ describe('BrsFile', () => {
|
|
|
2321
2039
|
'\n' +
|
|
2322
2040
|
'end sub';
|
|
2323
2041
|
program.options.sourceMap = true;
|
|
2324
|
-
let result = testTranspile(source, `sub main()\n print 1\nend sub`, 'none', 'source/main.bs');
|
|
2042
|
+
let result = await testTranspile(source, `sub main()\n print 1\nend sub`, 'none', 'source/main.bs');
|
|
2325
2043
|
//load the source map
|
|
2326
|
-
let location = await source_map_1.SourceMapConsumer.with(result.map
|
|
2044
|
+
let location = await source_map_1.SourceMapConsumer.with(result.map, null, (consumer) => {
|
|
2327
2045
|
return consumer.generatedPositionFor({
|
|
2328
2046
|
line: 3,
|
|
2329
2047
|
column: 0,
|
|
2330
|
-
source: (0, util_1.standardizePath) `${rootDir}/source/main.bs`,
|
|
2048
|
+
source: (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.bs`,
|
|
2331
2049
|
bias: source_map_1.SourceMapConsumer.LEAST_UPPER_BOUND
|
|
2332
2050
|
});
|
|
2333
2051
|
});
|
|
2334
|
-
(0,
|
|
2335
|
-
(0,
|
|
2052
|
+
(0, chai_config_spec_1.expect)(location.line).to.eql(2);
|
|
2053
|
+
(0, chai_config_spec_1.expect)(location.column).eql(4);
|
|
2336
2054
|
});
|
|
2337
2055
|
it('computes correct locations for sourcemap', async () => {
|
|
2338
2056
|
let source = `function abc(name)\n firstName = name\nend function`;
|
|
@@ -2340,7 +2058,7 @@ describe('BrsFile', () => {
|
|
|
2340
2058
|
//remove newlines and EOF
|
|
2341
2059
|
.filter(x => x.kind !== TokenKind_1.TokenKind.Eof && x.kind !== TokenKind_1.TokenKind.Newline);
|
|
2342
2060
|
program.options.sourceMap = true;
|
|
2343
|
-
let result = testTranspile(source, source, 'none');
|
|
2061
|
+
let result = await testTranspile(source, source, 'none');
|
|
2344
2062
|
//load the source map
|
|
2345
2063
|
await source_map_1.SourceMapConsumer.with(result.map.toString(), null, (consumer) => {
|
|
2346
2064
|
let tokenResult = tokens.map(token => ({
|
|
@@ -2360,58 +2078,76 @@ describe('BrsFile', () => {
|
|
|
2360
2078
|
originalPosition.line - 1, originalPosition.column)
|
|
2361
2079
|
};
|
|
2362
2080
|
});
|
|
2363
|
-
(0,
|
|
2081
|
+
(0, chai_config_spec_1.expect)(sourcemapResult).to.eql(tokenResult);
|
|
2364
2082
|
});
|
|
2365
2083
|
});
|
|
2366
|
-
it('handles empty if block', () => {
|
|
2367
|
-
testTranspile(`
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2084
|
+
it('handles empty if block', async () => {
|
|
2085
|
+
await testTranspile(`
|
|
2086
|
+
sub main()
|
|
2087
|
+
if true then
|
|
2088
|
+
end if
|
|
2089
|
+
if true then
|
|
2090
|
+
else
|
|
2091
|
+
print "else"
|
|
2092
|
+
end if
|
|
2093
|
+
if true then
|
|
2094
|
+
else if true then
|
|
2095
|
+
print "else"
|
|
2096
|
+
end if
|
|
2097
|
+
if true then
|
|
2098
|
+
else if true then
|
|
2099
|
+
print "elseif"
|
|
2100
|
+
else
|
|
2101
|
+
print "else"
|
|
2102
|
+
end if
|
|
2103
|
+
end sub
|
|
2384
2104
|
`);
|
|
2385
2105
|
});
|
|
2386
|
-
it('handles empty elseif block', () => {
|
|
2387
|
-
testTranspile(`
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2106
|
+
it('handles empty elseif block', async () => {
|
|
2107
|
+
await testTranspile(`
|
|
2108
|
+
sub main()
|
|
2109
|
+
if true then
|
|
2110
|
+
print "if"
|
|
2111
|
+
else if true then
|
|
2112
|
+
end if
|
|
2113
|
+
if true then
|
|
2114
|
+
print "if"
|
|
2115
|
+
else if true then
|
|
2116
|
+
else if true then
|
|
2117
|
+
end if
|
|
2118
|
+
end sub
|
|
2397
2119
|
`);
|
|
2398
2120
|
});
|
|
2399
|
-
it('handles empty else block', () => {
|
|
2400
|
-
testTranspile(`
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2121
|
+
it('handles empty else block', async () => {
|
|
2122
|
+
await testTranspile(`
|
|
2123
|
+
sub main()
|
|
2124
|
+
if true then
|
|
2125
|
+
print "if"
|
|
2126
|
+
else
|
|
2127
|
+
end if
|
|
2128
|
+
if true then
|
|
2129
|
+
print "if"
|
|
2130
|
+
else if true then
|
|
2131
|
+
print "elseif"
|
|
2132
|
+
else
|
|
2133
|
+
end if
|
|
2134
|
+
end sub
|
|
2135
|
+
`);
|
|
2136
|
+
});
|
|
2137
|
+
it('handles else block with a leading comment', async () => {
|
|
2138
|
+
await testTranspile(`
|
|
2139
|
+
sub main()
|
|
2140
|
+
if true then
|
|
2141
|
+
print "if"
|
|
2142
|
+
else
|
|
2143
|
+
' leading comment
|
|
2144
|
+
print "else"
|
|
2145
|
+
end if
|
|
2146
|
+
end sub
|
|
2411
2147
|
`);
|
|
2412
2148
|
});
|
|
2413
|
-
it('works for function parameters', () => {
|
|
2414
|
-
testTranspile(`
|
|
2149
|
+
it('works for function parameters', async () => {
|
|
2150
|
+
await testTranspile(`
|
|
2415
2151
|
function DoSomething(name, age as integer, text as string)
|
|
2416
2152
|
end function
|
|
2417
2153
|
`, `
|
|
@@ -2419,8 +2155,8 @@ describe('BrsFile', () => {
|
|
|
2419
2155
|
end function
|
|
2420
2156
|
`);
|
|
2421
2157
|
});
|
|
2422
|
-
it('adds newlines between top-level statements', () => {
|
|
2423
|
-
testTranspile(`
|
|
2158
|
+
it('adds newlines between top-level statements', async () => {
|
|
2159
|
+
await testTranspile(`
|
|
2424
2160
|
function a()
|
|
2425
2161
|
end function
|
|
2426
2162
|
|
|
@@ -2428,8 +2164,8 @@ describe('BrsFile', () => {
|
|
|
2428
2164
|
end function
|
|
2429
2165
|
`);
|
|
2430
2166
|
});
|
|
2431
|
-
it('properly indents nested AA literals', () => {
|
|
2432
|
-
testTranspile(`
|
|
2167
|
+
it('properly indents nested AA literals', async () => {
|
|
2168
|
+
await testTranspile(`
|
|
2433
2169
|
sub doSomething()
|
|
2434
2170
|
grandparent = {
|
|
2435
2171
|
parent: {
|
|
@@ -2443,8 +2179,8 @@ describe('BrsFile', () => {
|
|
|
2443
2179
|
end sub
|
|
2444
2180
|
`);
|
|
2445
2181
|
});
|
|
2446
|
-
it('does not add comma after final object property even when comments are present', () => {
|
|
2447
|
-
testTranspile(`
|
|
2182
|
+
it('does not add comma after final object property even when comments are present', async () => {
|
|
2183
|
+
await testTranspile(`
|
|
2448
2184
|
sub doSomething()
|
|
2449
2185
|
person = {
|
|
2450
2186
|
age: 12 'comment
|
|
@@ -2467,8 +2203,8 @@ describe('BrsFile', () => {
|
|
|
2467
2203
|
end sub
|
|
2468
2204
|
`);
|
|
2469
2205
|
});
|
|
2470
|
-
it('works for a complex function with comments all over the place', () => {
|
|
2471
|
-
testTranspile(`
|
|
2206
|
+
it('works for a complex function with comments all over the place', async () => {
|
|
2207
|
+
await testTranspile(`
|
|
2472
2208
|
'import some library
|
|
2473
2209
|
library "v30/bslCore.brs" 'comment
|
|
2474
2210
|
|
|
@@ -2517,7 +2253,7 @@ describe('BrsFile', () => {
|
|
|
2517
2253
|
3 'comment
|
|
2518
2254
|
] 'comment
|
|
2519
2255
|
firstIndex = indexes[0] 'comment
|
|
2520
|
-
for each idx in
|
|
2256
|
+
for each idx in indexes 'comment
|
|
2521
2257
|
indexes[idx] = idx + 1 'comment
|
|
2522
2258
|
end for 'comment
|
|
2523
2259
|
if not true then 'comment
|
|
@@ -2558,25 +2294,25 @@ describe('BrsFile', () => {
|
|
|
2558
2294
|
sub logInfo()
|
|
2559
2295
|
end sub
|
|
2560
2296
|
`);
|
|
2561
|
-
file
|
|
2297
|
+
file['needsTranspiled'] = false;
|
|
2562
2298
|
const { code } = file.transpile();
|
|
2563
|
-
(0,
|
|
2299
|
+
(0, chai_config_spec_1.expect)(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
|
|
2564
2300
|
});
|
|
2565
2301
|
it('AST generated files include a reference to the source map', () => {
|
|
2566
2302
|
let file = program.setFile('source/logger.brs', (0, testHelpers_spec_1.trim) `
|
|
2567
2303
|
sub logInfo()
|
|
2568
2304
|
end sub
|
|
2569
2305
|
`);
|
|
2570
|
-
file
|
|
2306
|
+
file['needsTranspiled'] = true;
|
|
2571
2307
|
const { code } = file.transpile();
|
|
2572
|
-
(0,
|
|
2308
|
+
(0, chai_config_spec_1.expect)(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
|
|
2573
2309
|
});
|
|
2574
|
-
it('replaces custom types in parameter types and return types', () => {
|
|
2310
|
+
it('replaces custom types in parameter types and return types', async () => {
|
|
2575
2311
|
program.setFile('source/SomeKlass.bs', `
|
|
2576
2312
|
class SomeKlass
|
|
2577
2313
|
end class
|
|
2578
2314
|
`);
|
|
2579
|
-
testTranspile(`
|
|
2315
|
+
await testTranspile(`
|
|
2580
2316
|
function foo() as SomeKlass
|
|
2581
2317
|
return new SomeKlass()
|
|
2582
2318
|
end function
|
|
@@ -2584,11 +2320,70 @@ describe('BrsFile', () => {
|
|
|
2584
2320
|
sub bar(obj as SomeKlass)
|
|
2585
2321
|
end sub
|
|
2586
2322
|
`, `
|
|
2587
|
-
function foo() as
|
|
2323
|
+
function foo() as dynamic
|
|
2588
2324
|
return SomeKlass()
|
|
2589
2325
|
end function
|
|
2590
2326
|
|
|
2591
|
-
sub bar(obj as
|
|
2327
|
+
sub bar(obj as dynamic)
|
|
2328
|
+
end sub
|
|
2329
|
+
`);
|
|
2330
|
+
});
|
|
2331
|
+
it('allows typecasts wrapped in parens', async () => {
|
|
2332
|
+
program.setFile('source/SomeKlass.bs', `
|
|
2333
|
+
class SomeKlass
|
|
2334
|
+
end class
|
|
2335
|
+
`);
|
|
2336
|
+
await testTranspile(`
|
|
2337
|
+
sub foo(obj as SomeKlass)
|
|
2338
|
+
(obj as roAssociativeArray).append({key:"value"})
|
|
2339
|
+
print 3 + (obj as roAssociativeArray).count()
|
|
2340
|
+
end sub
|
|
2341
|
+
`, `
|
|
2342
|
+
sub foo(obj as dynamic)
|
|
2343
|
+
obj.append({
|
|
2344
|
+
key: "value"
|
|
2345
|
+
})
|
|
2346
|
+
print 3 + obj.count()
|
|
2347
|
+
end sub
|
|
2348
|
+
`);
|
|
2349
|
+
});
|
|
2350
|
+
it('allows multiple typecasts wrapped in parens', async () => {
|
|
2351
|
+
program.setFile('source/SomeKlass.bs', `
|
|
2352
|
+
class SomeKlass
|
|
2353
|
+
function value()
|
|
2354
|
+
return 0.123
|
|
2355
|
+
end function
|
|
2356
|
+
end class
|
|
2357
|
+
`);
|
|
2358
|
+
await testTranspile(`
|
|
2359
|
+
sub foo(obj)
|
|
2360
|
+
print val( sin( (0.707 + (obj as SomeKlass).value()) as float ).toStr() as string)
|
|
2361
|
+
end sub
|
|
2362
|
+
`, `
|
|
2363
|
+
sub foo(obj)
|
|
2364
|
+
print val(sin((0.707 + obj.value())).toStr())
|
|
2365
|
+
end sub
|
|
2366
|
+
`);
|
|
2367
|
+
});
|
|
2368
|
+
it('allows a string of typecasts wrapped in parens', async () => {
|
|
2369
|
+
program.setFile('source/SomeKlass.bs', `
|
|
2370
|
+
class SomeKlass
|
|
2371
|
+
function data()
|
|
2372
|
+
return {key: "value"}
|
|
2373
|
+
end function
|
|
2374
|
+
end class
|
|
2375
|
+
|
|
2376
|
+
interface SomeIFace
|
|
2377
|
+
key
|
|
2378
|
+
end interface
|
|
2379
|
+
`);
|
|
2380
|
+
await testTranspile(`
|
|
2381
|
+
sub foo(obj)
|
|
2382
|
+
print (((obj as SomeKlass).data() as SomeIFace).key as string).len() as integer
|
|
2383
|
+
end sub
|
|
2384
|
+
`, `
|
|
2385
|
+
sub foo(obj)
|
|
2386
|
+
print obj.data().key.len()
|
|
2592
2387
|
end sub
|
|
2593
2388
|
`);
|
|
2594
2389
|
});
|
|
@@ -2597,35 +2392,40 @@ describe('BrsFile', () => {
|
|
|
2597
2392
|
describe('transpile', () => {
|
|
2598
2393
|
it('does not produce diagnostics', () => {
|
|
2599
2394
|
program.setFile('source/main.bs', `
|
|
2600
|
-
sub
|
|
2601
|
-
|
|
2395
|
+
sub test()
|
|
2396
|
+
someNode = createObject("roSGNode", "Rectangle")
|
|
2397
|
+
someNode@.someFunction(test.value)
|
|
2602
2398
|
end sub
|
|
2603
2399
|
`);
|
|
2604
2400
|
program.validate();
|
|
2605
2401
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2606
2402
|
});
|
|
2607
|
-
it('sets invalid on empty callfunc', () => {
|
|
2608
|
-
testTranspile(`
|
|
2403
|
+
it('sets invalid on empty callfunc', async () => {
|
|
2404
|
+
await testTranspile(`
|
|
2609
2405
|
sub main()
|
|
2406
|
+
node = invalid
|
|
2610
2407
|
node@.doSomething()
|
|
2611
2408
|
m.top.node@.doSomething()
|
|
2612
2409
|
m.top.node@.doSomething(1)
|
|
2613
2410
|
end sub
|
|
2614
2411
|
`, `
|
|
2615
2412
|
sub main()
|
|
2413
|
+
node = invalid
|
|
2616
2414
|
node.callfunc("doSomething", invalid)
|
|
2617
2415
|
m.top.node.callfunc("doSomething", invalid)
|
|
2618
2416
|
m.top.node.callfunc("doSomething", 1)
|
|
2619
2417
|
end sub
|
|
2620
2418
|
`);
|
|
2621
2419
|
});
|
|
2622
|
-
it('includes original arguments', () => {
|
|
2623
|
-
testTranspile(`
|
|
2420
|
+
it('includes original arguments', async () => {
|
|
2421
|
+
await testTranspile(`
|
|
2624
2422
|
sub main()
|
|
2423
|
+
node = invalid
|
|
2625
2424
|
node@.doSomething(1, true, m.top.someVal)
|
|
2626
2425
|
end sub
|
|
2627
2426
|
`, `
|
|
2628
2427
|
sub main()
|
|
2428
|
+
node = invalid
|
|
2629
2429
|
node.callfunc("doSomething", 1, true, m.top.someVal)
|
|
2630
2430
|
end sub
|
|
2631
2431
|
`);
|
|
@@ -2642,34 +2442,34 @@ describe('BrsFile', () => {
|
|
|
2642
2442
|
name: 'transform callback',
|
|
2643
2443
|
afterFileParse: onParsed
|
|
2644
2444
|
});
|
|
2645
|
-
file = program.setFile(
|
|
2445
|
+
file = program.setFile(`source/file${ext}`, `
|
|
2646
2446
|
sub Sum()
|
|
2647
|
-
|
|
2447
|
+
print "hello world"
|
|
2648
2448
|
end sub
|
|
2649
2449
|
`);
|
|
2650
|
-
(0,
|
|
2450
|
+
(0, chai_config_spec_1.expect)(file.extension).to.equal(ext);
|
|
2651
2451
|
return file;
|
|
2652
2452
|
}
|
|
2653
2453
|
it('called for BRS file', () => {
|
|
2654
2454
|
const onParsed = sinon.spy();
|
|
2655
2455
|
parseFileWithCallback('.brs', onParsed);
|
|
2656
|
-
(0,
|
|
2456
|
+
(0, chai_config_spec_1.expect)(onParsed.callCount).to.equal(1);
|
|
2657
2457
|
});
|
|
2658
|
-
it('called for
|
|
2458
|
+
it('called for BR file', () => {
|
|
2659
2459
|
const onParsed = sinon.spy();
|
|
2660
2460
|
parseFileWithCallback('.bs', onParsed);
|
|
2661
|
-
(0,
|
|
2461
|
+
(0, chai_config_spec_1.expect)(onParsed.callCount).to.equal(1);
|
|
2662
2462
|
});
|
|
2663
2463
|
});
|
|
2664
2464
|
describe('typedefKey', () => {
|
|
2665
2465
|
it('works for .brs files', () => {
|
|
2666
|
-
(0,
|
|
2466
|
+
(0, chai_config_spec_1.expect)((0, util_1.standardizePath)((program.setFile('source/main.brs', '')).typedefKey)).to.equal((0, util_1.standardizePath) `${testHelpers_spec_2.rootDir.toLowerCase()}/source/main.d.bs`);
|
|
2667
2467
|
});
|
|
2668
2468
|
it('returns undefined for files that should not have a typedef', () => {
|
|
2669
|
-
(0,
|
|
2670
|
-
(0,
|
|
2469
|
+
(0, chai_config_spec_1.expect)((program.setFile('source/main.bs', '')).typedefKey).to.be.undefined;
|
|
2470
|
+
(0, chai_config_spec_1.expect)((program.setFile('source/main.d.bs', '')).typedefKey).to.be.undefined;
|
|
2671
2471
|
const xmlFile = program.setFile('components/comp.xml', '');
|
|
2672
|
-
(0,
|
|
2472
|
+
(0, chai_config_spec_1.expect)(xmlFile.typedefKey).to.be.undefined;
|
|
2673
2473
|
});
|
|
2674
2474
|
});
|
|
2675
2475
|
describe('type definitions', () => {
|
|
@@ -2687,8 +2487,8 @@ describe('BrsFile', () => {
|
|
|
2687
2487
|
`);
|
|
2688
2488
|
const sourceScope = program.getScopeByName('source');
|
|
2689
2489
|
const functionNames = sourceScope.getAllCallables().map(x => x.callable.name);
|
|
2690
|
-
(0,
|
|
2691
|
-
(0,
|
|
2490
|
+
(0, chai_config_spec_1.expect)(functionNames).to.include('main');
|
|
2491
|
+
(0, chai_config_spec_1.expect)(functionNames).not.to.include('speak');
|
|
2692
2492
|
});
|
|
2693
2493
|
it('reacts to typedef file changes', () => {
|
|
2694
2494
|
let file = program.setFile('source/main.brs', `
|
|
@@ -2697,14 +2497,14 @@ describe('BrsFile', () => {
|
|
|
2697
2497
|
sub speak()
|
|
2698
2498
|
end sub
|
|
2699
2499
|
`);
|
|
2700
|
-
(0,
|
|
2701
|
-
(0,
|
|
2500
|
+
(0, chai_config_spec_1.expect)(file.hasTypedef).to.be.false;
|
|
2501
|
+
(0, chai_config_spec_1.expect)(file.typedefFile).not.to.exist;
|
|
2702
2502
|
program.setFile('source/main.d.bs', `
|
|
2703
2503
|
sub main()
|
|
2704
2504
|
end sub
|
|
2705
2505
|
`);
|
|
2706
|
-
(0,
|
|
2707
|
-
(0,
|
|
2506
|
+
(0, chai_config_spec_1.expect)(file.hasTypedef).to.be.true;
|
|
2507
|
+
(0, chai_config_spec_1.expect)(file.typedefFile).to.exist;
|
|
2708
2508
|
//add replace file, does it still find the typedef
|
|
2709
2509
|
file = program.setFile('source/main.brs', `
|
|
2710
2510
|
sub main()
|
|
@@ -2712,46 +2512,72 @@ describe('BrsFile', () => {
|
|
|
2712
2512
|
sub speak()
|
|
2713
2513
|
end sub
|
|
2714
2514
|
`);
|
|
2715
|
-
(0,
|
|
2716
|
-
(0,
|
|
2717
|
-
program.removeFile((0, util_1.standardizePath) `${rootDir}/source/main.d.bs`);
|
|
2718
|
-
(0,
|
|
2719
|
-
(0,
|
|
2515
|
+
(0, chai_config_spec_1.expect)(file.hasTypedef).to.be.true;
|
|
2516
|
+
(0, chai_config_spec_1.expect)(file.typedefFile).to.exist;
|
|
2517
|
+
program.removeFile((0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.d.bs`);
|
|
2518
|
+
(0, chai_config_spec_1.expect)(file.hasTypedef).to.be.false;
|
|
2519
|
+
(0, chai_config_spec_1.expect)(file.typedefFile).not.to.exist;
|
|
2720
2520
|
});
|
|
2721
2521
|
});
|
|
2722
2522
|
describe('typedef', () => {
|
|
2523
|
+
it('includes enum and interface types', async () => {
|
|
2524
|
+
await testGetTypedef(`
|
|
2525
|
+
interface Foo
|
|
2526
|
+
field as string
|
|
2527
|
+
end interface
|
|
2528
|
+
|
|
2529
|
+
enum Bar
|
|
2530
|
+
value
|
|
2531
|
+
end enum
|
|
2532
|
+
|
|
2533
|
+
function baz(parameter as Foo) as Bar
|
|
2534
|
+
return Bar.value
|
|
2535
|
+
end function
|
|
2536
|
+
`, `
|
|
2537
|
+
interface Foo
|
|
2538
|
+
field as string
|
|
2539
|
+
end interface
|
|
2540
|
+
|
|
2541
|
+
enum Bar
|
|
2542
|
+
value
|
|
2543
|
+
end enum
|
|
2544
|
+
function baz(parameter as Foo) as Bar
|
|
2545
|
+
end function
|
|
2546
|
+
`);
|
|
2547
|
+
});
|
|
2723
2548
|
it('sets typedef path properly', () => {
|
|
2724
|
-
(0,
|
|
2725
|
-
(0,
|
|
2726
|
-
(0,
|
|
2549
|
+
(0, chai_config_spec_1.expect)((program.setFile('source/main1.brs', '')).typedefKey).to.equal((0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main1.d.bs`.toLowerCase());
|
|
2550
|
+
(0, chai_config_spec_1.expect)((program.setFile('source/main2.d.bs', '')).typedefKey).to.equal(undefined);
|
|
2551
|
+
(0, chai_config_spec_1.expect)((program.setFile('source/main3.bs', '')).typedefKey).to.equal(undefined);
|
|
2727
2552
|
//works for dest with `.brs` extension
|
|
2728
|
-
(0,
|
|
2553
|
+
(0, chai_config_spec_1.expect)((program.setFile({ src: 'source/main4.bs', dest: 'source/main4.brs' }, '')).typedefKey).to.equal(undefined);
|
|
2729
2554
|
});
|
|
2730
2555
|
it('does not link when missing from program', () => {
|
|
2731
2556
|
const file = program.setFile('source/main.brs', ``);
|
|
2732
|
-
(0,
|
|
2557
|
+
(0, chai_config_spec_1.expect)(file.typedefFile).not.to.exist;
|
|
2733
2558
|
});
|
|
2734
2559
|
it('links typedef when added BEFORE .brs file', () => {
|
|
2735
2560
|
const typedef = program.setFile('source/main.d.bs', ``);
|
|
2736
2561
|
const file = program.setFile('source/main.brs', ``);
|
|
2737
|
-
(0,
|
|
2562
|
+
(0, chai_config_spec_1.expect)(file.typedefFile).to.equal(typedef);
|
|
2738
2563
|
});
|
|
2739
2564
|
it('links typedef when added AFTER .brs file', () => {
|
|
2740
2565
|
const file = program.setFile('source/main.brs', ``);
|
|
2741
2566
|
const typedef = program.setFile('source/main.d.bs', ``);
|
|
2742
|
-
(0,
|
|
2567
|
+
(0, chai_config_spec_1.expect)(file.typedefFile).to.eql(typedef);
|
|
2743
2568
|
});
|
|
2744
2569
|
it('removes typedef link when typedef is removed', () => {
|
|
2745
2570
|
const typedef = program.setFile('source/main.d.bs', ``);
|
|
2746
2571
|
const file = program.setFile('source/main.brs', ``);
|
|
2747
2572
|
program.removeFile(typedef.srcPath);
|
|
2748
|
-
(0,
|
|
2573
|
+
(0, chai_config_spec_1.expect)(file.typedefFile).to.be.undefined;
|
|
2749
2574
|
});
|
|
2750
2575
|
});
|
|
2751
2576
|
describe('getTypedef', () => {
|
|
2752
2577
|
function testTypedef(original, expected) {
|
|
2753
2578
|
let file = program.setFile('source/main.brs', original);
|
|
2754
|
-
|
|
2579
|
+
program.validate();
|
|
2580
|
+
(0, chai_config_spec_1.expect)(file.getTypedef().trimEnd()).to.eql(expected);
|
|
2755
2581
|
}
|
|
2756
2582
|
it('includes namespace on extend class names', () => {
|
|
2757
2583
|
testTypedef(`
|
|
@@ -3040,9 +2866,9 @@ describe('BrsFile', () => {
|
|
|
3040
2866
|
file['_parser'] = undefined;
|
|
3041
2867
|
//force the file to get a new instance of parser
|
|
3042
2868
|
const newParser = file.parser;
|
|
3043
|
-
(0,
|
|
2869
|
+
(0, chai_config_spec_1.expect)(newParser).to.exist.and.to.not.equal(parser);
|
|
3044
2870
|
//reference shouldn't change in subsequent accesses
|
|
3045
|
-
(0,
|
|
2871
|
+
(0, chai_config_spec_1.expect)(file.parser).to.equal(newParser);
|
|
3046
2872
|
});
|
|
3047
2873
|
it('call parse when previously skipped', () => {
|
|
3048
2874
|
program.setFile('source/main.d.bs', `'typedef
|
|
@@ -3054,11 +2880,11 @@ describe('BrsFile', () => {
|
|
|
3054
2880
|
end sub
|
|
3055
2881
|
`);
|
|
3056
2882
|
//no functions should be found since the parser was skipped
|
|
3057
|
-
(0,
|
|
2883
|
+
(0, chai_config_spec_1.expect)(file['_parser']).to.not.exist;
|
|
3058
2884
|
const stub = sinon.stub(file, 'parse').callThrough();
|
|
3059
2885
|
//`file.parser` is a getter, so that should force the parse to occur
|
|
3060
|
-
(0,
|
|
3061
|
-
(0,
|
|
2886
|
+
(0, chai_config_spec_1.expect)(file.parser.ast).to.exist;
|
|
2887
|
+
(0, chai_config_spec_1.expect)(stub.called).to.be.true;
|
|
3062
2888
|
//parse should have been called
|
|
3063
2889
|
});
|
|
3064
2890
|
});
|
|
@@ -3067,12 +2893,12 @@ describe('BrsFile', () => {
|
|
|
3067
2893
|
let idx = 1;
|
|
3068
2894
|
beforeEach(() => {
|
|
3069
2895
|
pluginFileName = `plugin-${idx++}.js`;
|
|
3070
|
-
fsExtra.outputFileSync((0, util_1.standardizePath) `${tempDir}/plugins/${pluginFileName}`, `
|
|
2896
|
+
fsExtra.outputFileSync((0, util_1.standardizePath) `${testHelpers_spec_2.tempDir}/plugins/${pluginFileName}`, `
|
|
3071
2897
|
function plugin() {
|
|
3072
2898
|
return {
|
|
3073
2899
|
name: 'lower-file-name',
|
|
3074
|
-
|
|
3075
|
-
evt.
|
|
2900
|
+
afterProvideFile: (evt) => {
|
|
2901
|
+
evt.files[0]._customProp = true;
|
|
3076
2902
|
}
|
|
3077
2903
|
};
|
|
3078
2904
|
}
|
|
@@ -3080,234 +2906,1000 @@ describe('BrsFile', () => {
|
|
|
3080
2906
|
`);
|
|
3081
2907
|
});
|
|
3082
2908
|
it('can load an absolute plugin which receives callbacks', () => {
|
|
3083
|
-
|
|
3084
|
-
(
|
|
3085
|
-
|
|
2909
|
+
for (const plugin of util_1.default.loadPlugins(testHelpers_spec_2.tempDir, [(0, util_1.standardizePath) `${testHelpers_spec_2.tempDir}/plugins/${pluginFileName}`])) {
|
|
2910
|
+
program.plugins.add(plugin);
|
|
2911
|
+
}
|
|
3086
2912
|
const file = program.setFile('source/MAIN.brs', '');
|
|
3087
|
-
(0,
|
|
2913
|
+
(0, chai_config_spec_1.expect)(file._customProp).to.exist;
|
|
3088
2914
|
});
|
|
3089
2915
|
it('can load a relative plugin which receives callbacks', () => {
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
2916
|
+
for (const plugin of util_1.default.loadPlugins(testHelpers_spec_2.tempDir, [`./plugins/${pluginFileName}`])) {
|
|
2917
|
+
program.plugins.add(plugin);
|
|
2918
|
+
}
|
|
3093
2919
|
const file = program.setFile('source/MAIN.brs', '');
|
|
3094
|
-
(0,
|
|
2920
|
+
(0, chai_config_spec_1.expect)(file._customProp).to.exist;
|
|
3095
2921
|
});
|
|
3096
2922
|
});
|
|
3097
|
-
describe('
|
|
3098
|
-
|
|
3099
|
-
const mainScope = program.getScopesForFile(file)[0];
|
|
3100
|
-
mainScope.linkSymbolTable();
|
|
3101
|
-
for (const lookup of lookups) {
|
|
3102
|
-
const position = vscode_languageserver_1.Position.create(lookup.line, lookup.col);
|
|
3103
|
-
const token = file.parser.getTokenAt(position);
|
|
3104
|
-
const symbol = file.getSymbolTypeFromToken(token, funcExpr, mainScope);
|
|
3105
|
-
const context = {
|
|
3106
|
-
file: file,
|
|
3107
|
-
scope: mainScope,
|
|
3108
|
-
position: position
|
|
3109
|
-
};
|
|
3110
|
-
(0, chai_1.expect)(symbol.expandedTokenText).to.equal(lookup.name);
|
|
3111
|
-
(0, chai_1.expect)(symbol.type.equals(lookup.type, context)).be.true;
|
|
3112
|
-
}
|
|
3113
|
-
}
|
|
3114
|
-
it('gets simple types based on the containing function expression', () => {
|
|
2923
|
+
describe('getDefinition', () => {
|
|
2924
|
+
it('returns const locations', () => {
|
|
3115
2925
|
const file = program.setFile('source/main.bs', `
|
|
3116
|
-
sub
|
|
3117
|
-
print
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
{ line: 5, col: 28, name: 'aBool', type: new BooleanType_1.BooleanType() },
|
|
3130
|
-
{ line: 6, col: 28, name: 'aObj', type: new ObjectType_1.ObjectType() }
|
|
3131
|
-
];
|
|
3132
|
-
checkSymbolLookups(file, funcExpr, lookups);
|
|
3133
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2926
|
+
sub main()
|
|
2927
|
+
print alpha.beta.charlie
|
|
2928
|
+
end sub
|
|
2929
|
+
namespace alpha.beta
|
|
2930
|
+
const CHARLIE = true
|
|
2931
|
+
end namespace
|
|
2932
|
+
`);
|
|
2933
|
+
program.validate();
|
|
2934
|
+
//print alpha.beta.char|lie
|
|
2935
|
+
(0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(2, 41))).to.eql([{
|
|
2936
|
+
uri: vscode_uri_1.URI.file(file.srcPath).toString(),
|
|
2937
|
+
range: util_1.default.createRange(5, 26, 5, 33)
|
|
2938
|
+
}]);
|
|
3134
2939
|
});
|
|
3135
|
-
it('
|
|
2940
|
+
it('returns enum locations', () => {
|
|
3136
2941
|
const file = program.setFile('source/main.bs', `
|
|
3137
|
-
sub
|
|
3138
|
-
print
|
|
2942
|
+
sub main()
|
|
2943
|
+
print alpha.beta.people.charlie
|
|
3139
2944
|
end sub
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
2945
|
+
namespace alpha.beta
|
|
2946
|
+
enum people
|
|
2947
|
+
charlie = "charles"
|
|
2948
|
+
end enum
|
|
2949
|
+
end namespace
|
|
3143
2950
|
`);
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
const classStmt = file.parser.references.classStatements[0];
|
|
3151
|
-
(0, chai_1.expect)(classStmt.name.text).to.equal('MyKlass');
|
|
3152
|
-
(0, chai_1.expect)(symbol.type.isAssignableTo(classStmt.getThisBscType())).be.true;
|
|
3153
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2951
|
+
program.validate();
|
|
2952
|
+
//print alpha.beta.char|lie
|
|
2953
|
+
(0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(2, 40))).to.eql([{
|
|
2954
|
+
uri: vscode_uri_1.URI.file(file.srcPath).toString(),
|
|
2955
|
+
range: util_1.default.createRange(5, 25, 5, 31)
|
|
2956
|
+
}]);
|
|
3154
2957
|
});
|
|
3155
|
-
it('
|
|
2958
|
+
it('returns interface location', () => {
|
|
3156
2959
|
const file = program.setFile('source/main.bs', `
|
|
3157
|
-
sub
|
|
3158
|
-
|
|
3159
|
-
print klass.name
|
|
3160
|
-
print klass.age
|
|
3161
|
-
' verify case insensitivity
|
|
3162
|
-
print KLASS.NAME
|
|
3163
|
-
print klass.AGE
|
|
2960
|
+
sub test(selectedMovie as Movie)
|
|
2961
|
+
print selectedMovie
|
|
3164
2962
|
end sub
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
2963
|
+
interface Movie
|
|
2964
|
+
url as string
|
|
2965
|
+
end interface
|
|
2966
|
+
`);
|
|
2967
|
+
program.validate();
|
|
2968
|
+
// sub test(selectedMovie as Mo|vie)
|
|
2969
|
+
(0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(1, 44))).to.eql([{
|
|
2970
|
+
uri: vscode_uri_1.URI.file(file.srcPath).toString(),
|
|
2971
|
+
range: util_1.default.createRange(4, 26, 4, 31)
|
|
2972
|
+
}]);
|
|
2973
|
+
});
|
|
2974
|
+
it('returns namespaced interface location', () => {
|
|
2975
|
+
const file = program.setFile('source/main.bs', `
|
|
2976
|
+
sub test(selectedMovie as interfaces.Movie)
|
|
2977
|
+
print selectedMovie
|
|
2978
|
+
end sub
|
|
2979
|
+
namespace interfaces
|
|
2980
|
+
interface Movie
|
|
2981
|
+
url as string
|
|
2982
|
+
end interface
|
|
2983
|
+
end namespace
|
|
2984
|
+
`);
|
|
2985
|
+
program.validate();
|
|
2986
|
+
//sub test(selectedMovie as interfaces.Mo|vie)
|
|
2987
|
+
(0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(1, 55))).to.eql([{
|
|
2988
|
+
uri: vscode_uri_1.URI.file(file.srcPath).toString(),
|
|
2989
|
+
range: util_1.default.createRange(5, 30, 5, 35)
|
|
2990
|
+
}]);
|
|
2991
|
+
});
|
|
2992
|
+
it('returns class location', () => {
|
|
2993
|
+
const file = program.setFile('source/main.bs', `
|
|
2994
|
+
sub test(selectedMovie as Movie)
|
|
2995
|
+
print selectedMovie
|
|
2996
|
+
end sub
|
|
2997
|
+
class Movie
|
|
2998
|
+
url as string
|
|
3169
2999
|
end class
|
|
3170
3000
|
`);
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
3001
|
+
program.validate();
|
|
3002
|
+
//sub test(selectedMovie as Mo|vie)
|
|
3003
|
+
(0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(1, 44))).to.eql([{
|
|
3004
|
+
uri: vscode_uri_1.URI.file(file.srcPath).toString(),
|
|
3005
|
+
range: util_1.default.createRange(4, 22, 4, 27)
|
|
3006
|
+
}]);
|
|
3178
3007
|
});
|
|
3179
|
-
it('
|
|
3008
|
+
it('returns namespaced class location', () => {
|
|
3180
3009
|
const file = program.setFile('source/main.bs', `
|
|
3181
|
-
sub
|
|
3182
|
-
|
|
3183
|
-
print obj.name
|
|
3184
|
-
print obj.age
|
|
3010
|
+
sub test(selectedMovie as classes.Movie)
|
|
3011
|
+
print selectedMovie
|
|
3185
3012
|
end sub
|
|
3013
|
+
namespace classes
|
|
3014
|
+
class Movie
|
|
3015
|
+
url as string
|
|
3016
|
+
end class
|
|
3017
|
+
end namespace
|
|
3186
3018
|
`);
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
3019
|
+
program.validate();
|
|
3020
|
+
//sub test(selectedMovie as classes.Mo|vie)
|
|
3021
|
+
(0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(1, 52))).to.eql([{
|
|
3022
|
+
uri: vscode_uri_1.URI.file(file.srcPath).toString(),
|
|
3023
|
+
range: util_1.default.createRange(5, 26, 5, 31)
|
|
3024
|
+
}]);
|
|
3194
3025
|
});
|
|
3195
|
-
it('
|
|
3026
|
+
it('does not crash on nulls', () => {
|
|
3196
3027
|
const file = program.setFile('source/main.bs', `
|
|
3197
|
-
sub
|
|
3198
|
-
|
|
3199
|
-
|
|
3028
|
+
sub main()
|
|
3029
|
+
print alpha.beta
|
|
3030
|
+
end sub
|
|
3031
|
+
`);
|
|
3032
|
+
program.validate();
|
|
3033
|
+
sinon.stub(util_1.default, 'getAllDottedGetParts').returns(null);
|
|
3034
|
+
// print alpha.be|ta
|
|
3035
|
+
(0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(2, 34))).to.eql([]);
|
|
3036
|
+
});
|
|
3037
|
+
it('returns enum member locations', () => {
|
|
3038
|
+
const file = program.setFile('source/main.bs', `
|
|
3039
|
+
sub main()
|
|
3040
|
+
print alpha.beta.people.charlie
|
|
3041
|
+
end sub
|
|
3042
|
+
namespace alpha.beta
|
|
3043
|
+
enum people
|
|
3044
|
+
charlie = "charles"
|
|
3045
|
+
end enum
|
|
3046
|
+
end namespace
|
|
3047
|
+
`);
|
|
3048
|
+
program.validate();
|
|
3049
|
+
//print alpha.beta.char|lie
|
|
3050
|
+
(0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(2, 48))).to.eql([{
|
|
3051
|
+
uri: vscode_uri_1.URI.file(file.srcPath).toString(),
|
|
3052
|
+
range: util_1.default.createRange(6, 24, 6, 31)
|
|
3053
|
+
}]);
|
|
3054
|
+
});
|
|
3055
|
+
});
|
|
3056
|
+
it('catches mismatched `end` keywords for functions', () => {
|
|
3057
|
+
program.setFile('source/main.brs', `
|
|
3058
|
+
function speak()
|
|
3059
|
+
end sub
|
|
3060
|
+
sub walk()
|
|
3061
|
+
end function
|
|
3062
|
+
`);
|
|
3063
|
+
program.validate();
|
|
3064
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedEndCallableKeyword('function', 'sub')), { range: util_1.default.createRange(2, 12, 2, 19) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedEndCallableKeyword('sub', 'function')), { range: util_1.default.createRange(4, 12, 4, 24) })]);
|
|
3065
|
+
});
|
|
3066
|
+
describe('requiredSymbols', () => {
|
|
3067
|
+
it('should be empty for a simple file', () => {
|
|
3068
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3069
|
+
function someFunc() as integer
|
|
3070
|
+
return 1
|
|
3071
|
+
end function
|
|
3072
|
+
`);
|
|
3073
|
+
const validateFileEvent = {
|
|
3074
|
+
program: program,
|
|
3075
|
+
file: mainFile
|
|
3076
|
+
};
|
|
3077
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3078
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(0);
|
|
3079
|
+
});
|
|
3080
|
+
it('should be empty if the file needs no external symbols', () => {
|
|
3081
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3082
|
+
function someFunc() as integer
|
|
3083
|
+
return 1
|
|
3084
|
+
end function
|
|
3085
|
+
|
|
3086
|
+
sub useKlass()
|
|
3087
|
+
k = new Klass()
|
|
3088
|
+
k.addTwo()
|
|
3200
3089
|
end sub
|
|
3201
3090
|
|
|
3202
|
-
|
|
3203
|
-
|
|
3091
|
+
class Klass
|
|
3092
|
+
sub addTwo()
|
|
3093
|
+
print someFunc() + someFunc()
|
|
3094
|
+
end sub
|
|
3095
|
+
end class
|
|
3096
|
+
`);
|
|
3097
|
+
const validateFileEvent = {
|
|
3098
|
+
program: program,
|
|
3099
|
+
file: mainFile
|
|
3100
|
+
};
|
|
3101
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3102
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(0);
|
|
3103
|
+
});
|
|
3104
|
+
it('should not include global callables or types', () => {
|
|
3105
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3106
|
+
function printLower(s as string) as integer
|
|
3107
|
+
print lcase(s.trim())
|
|
3204
3108
|
end function
|
|
3205
3109
|
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3110
|
+
sub setLabelText( label as roSGNodeLabel, text as string)
|
|
3111
|
+
label.text = text
|
|
3112
|
+
end sub
|
|
3113
|
+
`);
|
|
3114
|
+
const validateFileEvent = {
|
|
3115
|
+
program: program,
|
|
3116
|
+
file: mainFile
|
|
3117
|
+
};
|
|
3118
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3119
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(0);
|
|
3120
|
+
});
|
|
3121
|
+
it('should include unknown param and return types', () => {
|
|
3122
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3123
|
+
function someFunc(arg as OneType) as TwoType
|
|
3124
|
+
return arg.getTwo()
|
|
3125
|
+
end function
|
|
3126
|
+
`);
|
|
3127
|
+
const validateFileEvent = {
|
|
3128
|
+
program: program,
|
|
3129
|
+
file: mainFile
|
|
3130
|
+
};
|
|
3131
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3132
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(2);
|
|
3133
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.map(x => x.typeChain[0].name)).to.have.same.members([
|
|
3134
|
+
'TwoType', 'OneType'
|
|
3135
|
+
]);
|
|
3136
|
+
});
|
|
3137
|
+
it('should include unknown param and return types on class methods', () => {
|
|
3138
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3139
|
+
class Klass
|
|
3140
|
+
function someFunc(arg as OneType) as TwoType
|
|
3141
|
+
return arg.getTwo()
|
|
3209
3142
|
end function
|
|
3143
|
+
end class
|
|
3144
|
+
`);
|
|
3145
|
+
const validateFileEvent = {
|
|
3146
|
+
program: program,
|
|
3147
|
+
file: mainFile
|
|
3148
|
+
};
|
|
3149
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3150
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(2);
|
|
3151
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.map(x => x.typeChain[0].name)).to.have.same.members([
|
|
3152
|
+
'TwoType', 'OneType'
|
|
3153
|
+
]);
|
|
3154
|
+
});
|
|
3155
|
+
it('should not include assigned symbols', () => {
|
|
3156
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3157
|
+
sub someFunc(arg as SomeOtherType)
|
|
3158
|
+
x = arg.member
|
|
3159
|
+
print x+1
|
|
3160
|
+
end sub
|
|
3161
|
+
`);
|
|
3162
|
+
const validateFileEvent = {
|
|
3163
|
+
program: program,
|
|
3164
|
+
file: mainFile
|
|
3165
|
+
};
|
|
3166
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3167
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(1);
|
|
3168
|
+
// x and arg are assigned.. they are not included in the required symbols
|
|
3169
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols[0].typeChain[0].name).to.equal('SomeOtherType');
|
|
3170
|
+
});
|
|
3171
|
+
it('should include functions called that are not in the file', () => {
|
|
3172
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3173
|
+
sub someFunc()
|
|
3174
|
+
x = otherFileFunc1()
|
|
3175
|
+
print x+1
|
|
3176
|
+
end sub
|
|
3177
|
+
|
|
3178
|
+
function deepFunctionCall(i as integer)
|
|
3179
|
+
x = 2*i and otherFileFunc2()
|
|
3180
|
+
y = sin(x+fix(78.2)*log(otherFileFunc3()))
|
|
3181
|
+
' this is a comment otherFileFunc5()
|
|
3182
|
+
return y-otherFileFunc4()
|
|
3183
|
+
end function
|
|
3184
|
+
`);
|
|
3185
|
+
const validateFileEvent = {
|
|
3186
|
+
program: program,
|
|
3187
|
+
file: mainFile
|
|
3188
|
+
};
|
|
3189
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3190
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(4);
|
|
3191
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.map(x => x.typeChain[0].name)).to.have.same.members([
|
|
3192
|
+
'otherFileFunc1', 'otherFileFunc2', 'otherFileFunc3', 'otherFileFunc4'
|
|
3193
|
+
]);
|
|
3194
|
+
});
|
|
3195
|
+
it('should include classes called that are not in the file', () => {
|
|
3196
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3197
|
+
function someFunc(other as OtherKlass) as NS1.Thing
|
|
3198
|
+
x = new AnotherClass()
|
|
3199
|
+
return other.getThing(x)
|
|
3200
|
+
end function
|
|
3201
|
+
`);
|
|
3202
|
+
const validateFileEvent = {
|
|
3203
|
+
program: program,
|
|
3204
|
+
file: mainFile
|
|
3205
|
+
};
|
|
3206
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3207
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(3);
|
|
3208
|
+
const requiredTypeChains = mainFile.requiredSymbols.map(x => x.typeChain.map(tc => tc.name).join('.'));
|
|
3209
|
+
(0, chai_config_spec_1.expect)(requiredTypeChains).to.have.same.members([
|
|
3210
|
+
'OtherKlass', 'NS1.Thing', 'AnotherClass'
|
|
3211
|
+
]);
|
|
3212
|
+
const requiredSymbolsFlags = mainFile.requiredSymbols.map(x => x.flags);
|
|
3213
|
+
(0, chai_config_spec_1.expect)(requiredSymbolsFlags).to.have.same.members([
|
|
3214
|
+
SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.runtime
|
|
3215
|
+
]);
|
|
3216
|
+
});
|
|
3217
|
+
it('should include enums and consts that are not in the file', () => {
|
|
3218
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3219
|
+
sub someFunc(myEnum as SomeEnum)
|
|
3220
|
+
if myEnum = SomeEnum.value1
|
|
3221
|
+
print 1
|
|
3222
|
+
else if myEnum = SomeEnum.value2
|
|
3223
|
+
print 2
|
|
3224
|
+
else if myEnum = SomeConstValue
|
|
3225
|
+
print 3
|
|
3226
|
+
end if
|
|
3227
|
+
end sub
|
|
3228
|
+
`);
|
|
3229
|
+
const validateFileEvent = {
|
|
3230
|
+
program: program,
|
|
3231
|
+
file: mainFile
|
|
3232
|
+
};
|
|
3233
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3234
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(4);
|
|
3235
|
+
const requiredTypeChains = mainFile.requiredSymbols.map(x => x.typeChain.map(tc => tc.name).join('.'));
|
|
3236
|
+
(0, chai_config_spec_1.expect)(requiredTypeChains).to.have.same.members([
|
|
3237
|
+
'SomeEnum', 'SomeEnum.value1', 'SomeEnum.value2', 'SomeConstValue'
|
|
3238
|
+
]);
|
|
3239
|
+
const requiredSymbolsFlags = mainFile.requiredSymbols.map(x => x.flags);
|
|
3240
|
+
(0, chai_config_spec_1.expect)(requiredSymbolsFlags).to.have.same.members([
|
|
3241
|
+
SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.runtime, SymbolTable_1.SymbolTypeFlag.runtime, SymbolTable_1.SymbolTypeFlag.runtime
|
|
3242
|
+
]);
|
|
3243
|
+
});
|
|
3244
|
+
it('should include types not defined in the file', () => {
|
|
3245
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3246
|
+
interface Data
|
|
3247
|
+
kind as DataKind
|
|
3248
|
+
getObj as DataObject
|
|
3249
|
+
subData as SubData
|
|
3250
|
+
end interface
|
|
3210
3251
|
|
|
3211
|
-
|
|
3212
|
-
|
|
3252
|
+
class DataObject extends BaseData
|
|
3253
|
+
kind as DataKind
|
|
3254
|
+
function process(dataProcess as DataProcessor) as ProcessedData
|
|
3255
|
+
return dataProcess.work(m)
|
|
3213
3256
|
end function
|
|
3214
3257
|
end class
|
|
3215
3258
|
`);
|
|
3216
|
-
const
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3259
|
+
const validateFileEvent = {
|
|
3260
|
+
program: program,
|
|
3261
|
+
file: mainFile
|
|
3262
|
+
};
|
|
3263
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3264
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(5);
|
|
3265
|
+
const requiredTypeChains = mainFile.requiredSymbols.map(x => x.typeChain.map(tc => tc.name).join('.'));
|
|
3266
|
+
(0, chai_config_spec_1.expect)(requiredTypeChains).to.have.same.members([
|
|
3267
|
+
'DataKind', 'SubData', 'BaseData', 'DataProcessor', 'ProcessedData'
|
|
3268
|
+
]);
|
|
3269
|
+
const requiredSymbolsFlags = mainFile.requiredSymbols.map(x => x.flags);
|
|
3270
|
+
(0, chai_config_spec_1.expect)(requiredSymbolsFlags).to.have.same.members([
|
|
3271
|
+
SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime
|
|
3272
|
+
]);
|
|
3229
3273
|
});
|
|
3230
|
-
it('
|
|
3231
|
-
const
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3274
|
+
it('includes namespace details', () => {
|
|
3275
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3276
|
+
namespace Alpha.Beta
|
|
3277
|
+
sub printConstVal()
|
|
3278
|
+
print CONST_VALUE
|
|
3279
|
+
end sub
|
|
3280
|
+
end namespace
|
|
3281
|
+
|
|
3282
|
+
namespace Delta
|
|
3283
|
+
namespace Gamma
|
|
3284
|
+
namespace Eta
|
|
3285
|
+
sub doStuff(x as OtherType)
|
|
3286
|
+
x.something()
|
|
3287
|
+
end sub
|
|
3288
|
+
end namespace
|
|
3289
|
+
end namespace
|
|
3290
|
+
end namespace
|
|
3291
|
+
`);
|
|
3292
|
+
const validateFileEvent = {
|
|
3293
|
+
program: program,
|
|
3294
|
+
file: mainFile
|
|
3295
|
+
};
|
|
3296
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3297
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(2);
|
|
3298
|
+
const requiredTypeChains = mainFile.requiredSymbols.map(x => x.typeChain.map(tc => tc.name).join('.'));
|
|
3299
|
+
(0, chai_config_spec_1.expect)(requiredTypeChains).to.have.same.members([
|
|
3300
|
+
'CONST_VALUE', 'OtherType'
|
|
3301
|
+
]);
|
|
3302
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols[0].containingNamespaces).to.have.same.members(['Alpha', 'Beta']);
|
|
3303
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols[1].containingNamespaces).to.have.same.members(['Delta', 'Gamma', 'Eta']);
|
|
3304
|
+
});
|
|
3305
|
+
it('does not include namespaces that are defined in the file', () => {
|
|
3306
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3307
|
+
namespace name1
|
|
3308
|
+
const PI = 3.14
|
|
3238
3309
|
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3310
|
+
namespace name2
|
|
3311
|
+
function getPi() as float
|
|
3312
|
+
return name1.PI
|
|
3313
|
+
end function
|
|
3314
|
+
end namespace
|
|
3315
|
+
end namespace
|
|
3316
|
+
`);
|
|
3317
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3318
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(0);
|
|
3319
|
+
});
|
|
3320
|
+
it('should put types from typecasts as typetime required', () => {
|
|
3321
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3322
|
+
function takesIface(z) as string
|
|
3323
|
+
return (z as MyInterface).name
|
|
3324
|
+
end function
|
|
3325
|
+
`);
|
|
3326
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3327
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(1);
|
|
3328
|
+
(0, chai_config_spec_1.expect)(mainFile.requiredSymbols[0].flags).to.eq(SymbolTable_1.SymbolTypeFlag.typetime);
|
|
3329
|
+
});
|
|
3330
|
+
});
|
|
3331
|
+
describe('providedSymbols', () => {
|
|
3332
|
+
it('includes functions defined in the file', () => {
|
|
3333
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3334
|
+
function someFunc() as integer
|
|
3335
|
+
return 1
|
|
3336
|
+
end function
|
|
3337
|
+
|
|
3338
|
+
function someFunc2() as float
|
|
3339
|
+
return 2.3
|
|
3340
|
+
end function
|
|
3341
|
+
`);
|
|
3342
|
+
const validateFileEvent = {
|
|
3343
|
+
program: program,
|
|
3344
|
+
file: mainFile
|
|
3345
|
+
};
|
|
3346
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3347
|
+
const runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3348
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
|
|
3349
|
+
const someFuncType = runtimeSymbols.get('somefunc').type;
|
|
3350
|
+
(0, testHelpers_spec_1.expectTypeToBe)(someFuncType, TypedFunctionType_1.TypedFunctionType);
|
|
3351
|
+
const someFunc2Type = runtimeSymbols.get('somefunc2').type;
|
|
3352
|
+
(0, testHelpers_spec_1.expectTypeToBe)(someFunc2Type, TypedFunctionType_1.TypedFunctionType);
|
|
3353
|
+
});
|
|
3354
|
+
it('includes functions with unresolved params/return types', () => {
|
|
3355
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3356
|
+
function someFunc() as OtherFileType
|
|
3357
|
+
return new OtherFileType()
|
|
3358
|
+
end function
|
|
3359
|
+
`);
|
|
3360
|
+
const validateFileEvent = {
|
|
3361
|
+
program: program,
|
|
3362
|
+
file: mainFile
|
|
3363
|
+
};
|
|
3364
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3365
|
+
const runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3366
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3367
|
+
const someFuncType = runtimeSymbols.get('somefunc').type;
|
|
3368
|
+
(0, testHelpers_spec_1.expectTypeToBe)(someFuncType, TypedFunctionType_1.TypedFunctionType);
|
|
3369
|
+
const requiredSymbols = mainFile.requiredSymbols.map(x => x.typeChain[0].name);
|
|
3370
|
+
(0, chai_config_spec_1.expect)(requiredSymbols).to.have.same.members(['OtherFileType', 'OtherFileType']);
|
|
3371
|
+
const requiredSymbolTypes = mainFile.requiredSymbols.map(x => x.flags);
|
|
3372
|
+
(0, chai_config_spec_1.expect)(requiredSymbolTypes).to.have.same.members([SymbolTable_1.SymbolTypeFlag.runtime, SymbolTable_1.SymbolTypeFlag.typetime]);
|
|
3373
|
+
});
|
|
3374
|
+
it('includes classes defined in the file', () => {
|
|
3375
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3376
|
+
class Klass
|
|
3377
|
+
name as string
|
|
3378
|
+
end class
|
|
3379
|
+
|
|
3380
|
+
class Klass2 extends Klass
|
|
3381
|
+
age as integer
|
|
3382
|
+
|
|
3383
|
+
function getId() as string
|
|
3384
|
+
return m.name + " " + m.age.toStr()
|
|
3242
3385
|
end function
|
|
3243
3386
|
end class
|
|
3387
|
+
|
|
3388
|
+
class Klass3
|
|
3389
|
+
propClass = new Klass2()
|
|
3390
|
+
end class
|
|
3244
3391
|
`);
|
|
3245
|
-
const
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
(0,
|
|
3392
|
+
const validateFileEvent = {
|
|
3393
|
+
program: program,
|
|
3394
|
+
file: mainFile
|
|
3395
|
+
};
|
|
3396
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3397
|
+
const runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3398
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(3);
|
|
3399
|
+
(0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass').type, types_1.ClassType);
|
|
3400
|
+
(0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass2').type, types_1.ClassType);
|
|
3401
|
+
(0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass3').type, types_1.ClassType);
|
|
3402
|
+
const typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
|
|
3403
|
+
(0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(3);
|
|
3404
|
+
(0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass').type, types_1.ClassType);
|
|
3405
|
+
(0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass2').type, types_1.ClassType);
|
|
3406
|
+
(0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass3').type, types_1.ClassType);
|
|
3407
|
+
});
|
|
3408
|
+
it('includes other types defined in the file', () => {
|
|
3409
|
+
const mainFile = program.setFile('source/main.bs', `
|
|
3410
|
+
interface MyInterface
|
|
3411
|
+
name as string
|
|
3412
|
+
end interface
|
|
3413
|
+
|
|
3414
|
+
enum MyEnum
|
|
3415
|
+
val1
|
|
3416
|
+
val2
|
|
3417
|
+
end enum
|
|
3418
|
+
|
|
3419
|
+
namespace MyNamespace
|
|
3420
|
+
const MyConst = 3.14
|
|
3421
|
+
end namespace
|
|
3422
|
+
`);
|
|
3423
|
+
const validateFileEvent = {
|
|
3424
|
+
program: program,
|
|
3425
|
+
file: mainFile
|
|
3426
|
+
};
|
|
3427
|
+
program.plugins.emit('onFileValidate', validateFileEvent);
|
|
3428
|
+
const runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3429
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
|
|
3430
|
+
(0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('myenum').type, types_1.EnumType);
|
|
3431
|
+
(0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('mynamespace.myconst').type, types_1.FloatType);
|
|
3432
|
+
const typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
|
|
3433
|
+
(0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(2);
|
|
3434
|
+
(0, testHelpers_spec_1.expectTypeToBe)(typetimeSymbols.get('myinterface').type, types_1.InterfaceType);
|
|
3435
|
+
(0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('myenum').type, types_1.EnumType);
|
|
3436
|
+
});
|
|
3437
|
+
describe('changes', () => {
|
|
3438
|
+
it('new symbols are added to the changes set', () => {
|
|
3439
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3440
|
+
sub someFunc()
|
|
3441
|
+
print 1
|
|
3442
|
+
end sub
|
|
3443
|
+
`);
|
|
3444
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3445
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3446
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3447
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3448
|
+
sub someFunc()
|
|
3449
|
+
print 1
|
|
3450
|
+
end sub
|
|
3451
|
+
|
|
3452
|
+
sub someFunc2()
|
|
3453
|
+
print 2
|
|
3454
|
+
end sub
|
|
3455
|
+
`);
|
|
3456
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3457
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3458
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
|
|
3459
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3460
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
|
|
3461
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.has('somefunc2')).to.be.true;
|
|
3462
|
+
});
|
|
3463
|
+
it('removed symbols are added to the changes set', () => {
|
|
3464
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3465
|
+
sub someFunc()
|
|
3466
|
+
print 1
|
|
3467
|
+
end sub
|
|
3468
|
+
|
|
3469
|
+
sub someFunc2()
|
|
3470
|
+
print 2
|
|
3471
|
+
end sub
|
|
3472
|
+
`);
|
|
3473
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3474
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3475
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
|
|
3476
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3477
|
+
sub someFunc()
|
|
3478
|
+
print 1
|
|
3479
|
+
end sub
|
|
3480
|
+
`);
|
|
3481
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3482
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3483
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3484
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3485
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
|
|
3486
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.has('somefunc2')).to.be.true;
|
|
3487
|
+
});
|
|
3488
|
+
it('new symbols in a namespace are added to the changes set', () => {
|
|
3489
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3490
|
+
namespace Alpha
|
|
3491
|
+
end namespace
|
|
3492
|
+
`);
|
|
3493
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3494
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3495
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(0);
|
|
3496
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3497
|
+
namespace Alpha
|
|
3498
|
+
const ABC = "abc"
|
|
3499
|
+
end namespace
|
|
3500
|
+
`);
|
|
3501
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3502
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3503
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3504
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3505
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
|
|
3506
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.has('alpha.abc')).to.be.true;
|
|
3507
|
+
});
|
|
3508
|
+
it('should be empty if no changes in actual provided symbols', () => {
|
|
3509
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3510
|
+
sub printSomething()
|
|
3511
|
+
print "Something"
|
|
3512
|
+
end sub
|
|
3513
|
+
|
|
3514
|
+
namespace alpha.beta
|
|
3515
|
+
const PI = 3.14
|
|
3516
|
+
end namespace
|
|
3517
|
+
`);
|
|
3518
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3519
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3520
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
|
|
3521
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3522
|
+
sub printSomething()
|
|
3523
|
+
print "Something Else"
|
|
3524
|
+
end sub
|
|
3525
|
+
|
|
3526
|
+
namespace alpha.beta
|
|
3527
|
+
const PI = 3.14159
|
|
3528
|
+
end namespace
|
|
3529
|
+
`);
|
|
3530
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3531
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3532
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
|
|
3533
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3534
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
|
|
3535
|
+
});
|
|
3536
|
+
it('should include changes in function signatures', () => {
|
|
3537
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3538
|
+
function someFunc(x)
|
|
3539
|
+
return x
|
|
3540
|
+
end function
|
|
3541
|
+
`);
|
|
3542
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3543
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3544
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3545
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3546
|
+
function someFunc(x, y)
|
|
3547
|
+
return x+y
|
|
3548
|
+
end function
|
|
3549
|
+
`);
|
|
3550
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3551
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3552
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3553
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3554
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
|
|
3555
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.has('somefunc'));
|
|
3556
|
+
});
|
|
3557
|
+
it('should include changes in classes', () => {
|
|
3558
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3559
|
+
class MyKlass
|
|
3560
|
+
name as string
|
|
3561
|
+
function getValue() as float
|
|
3562
|
+
return 3.14
|
|
3563
|
+
end function
|
|
3564
|
+
end class
|
|
3565
|
+
`);
|
|
3566
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3567
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3568
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3569
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3570
|
+
class MyKlass
|
|
3571
|
+
name as string
|
|
3572
|
+
function getValue() as string
|
|
3573
|
+
return "hello"
|
|
3574
|
+
end function
|
|
3575
|
+
end class
|
|
3576
|
+
`);
|
|
3577
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3578
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3579
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3580
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3581
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
|
|
3582
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.has('myklass'));
|
|
3583
|
+
let typeTimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.typetime);
|
|
3584
|
+
(0, chai_config_spec_1.expect)(typeTimeChanges.size).to.eq(1);
|
|
3585
|
+
(0, chai_config_spec_1.expect)(typeTimeChanges.has('myklass'));
|
|
3586
|
+
});
|
|
3587
|
+
it('should include changes in interfaces', () => {
|
|
3588
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3589
|
+
interface Iface1
|
|
3590
|
+
name as string
|
|
3591
|
+
function doStuff() as float
|
|
3592
|
+
end interface
|
|
3593
|
+
`);
|
|
3594
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3595
|
+
let typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
|
|
3596
|
+
(0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(1);
|
|
3597
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3598
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(0);
|
|
3599
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3600
|
+
interface Iface1
|
|
3601
|
+
name as string
|
|
3602
|
+
age as integer
|
|
3603
|
+
function doStuff() as float
|
|
3604
|
+
end interface
|
|
3605
|
+
`);
|
|
3606
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3607
|
+
typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
|
|
3608
|
+
(0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(1);
|
|
3609
|
+
let typeTimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.typetime);
|
|
3610
|
+
(0, chai_config_spec_1.expect)(typeTimeChanges.size).to.eq(1);
|
|
3611
|
+
(0, chai_config_spec_1.expect)(typeTimeChanges.has('iface1'));
|
|
3612
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3613
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
|
|
3614
|
+
});
|
|
3615
|
+
it('should not include changes in enum values, if inner type is the same', () => {
|
|
3616
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3617
|
+
enum MyEnum
|
|
3618
|
+
north = 4
|
|
3619
|
+
east = 3
|
|
3620
|
+
south = 2
|
|
3621
|
+
west = 1
|
|
3622
|
+
end enum
|
|
3623
|
+
`);
|
|
3624
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3625
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3626
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3627
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3628
|
+
enum MyEnum
|
|
3629
|
+
north = 1
|
|
3630
|
+
east = 2
|
|
3631
|
+
south = 3
|
|
3632
|
+
west = 4
|
|
3633
|
+
end enum
|
|
3634
|
+
`);
|
|
3635
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3636
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3637
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3638
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3639
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
|
|
3640
|
+
let typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
|
|
3641
|
+
(0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(1);
|
|
3642
|
+
let typetimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.typetime);
|
|
3643
|
+
(0, chai_config_spec_1.expect)(typetimeChanges.size).to.eq(0);
|
|
3644
|
+
});
|
|
3645
|
+
it('should include changes in enum, if different number of members', () => {
|
|
3646
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3647
|
+
enum Direction
|
|
3648
|
+
north = 1
|
|
3649
|
+
east = 2
|
|
3650
|
+
south = 3
|
|
3651
|
+
west = 4
|
|
3652
|
+
end enum
|
|
3653
|
+
|
|
3654
|
+
enum Weather
|
|
3655
|
+
rainy
|
|
3656
|
+
sunny
|
|
3657
|
+
end enum
|
|
3658
|
+
|
|
3659
|
+
enum Colors
|
|
3660
|
+
blue
|
|
3661
|
+
red
|
|
3662
|
+
green
|
|
3663
|
+
purple
|
|
3664
|
+
end enum
|
|
3665
|
+
`);
|
|
3666
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3667
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3668
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(3);
|
|
3669
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3670
|
+
enum Direction ' same
|
|
3671
|
+
north = 1
|
|
3672
|
+
east = 2
|
|
3673
|
+
south = 3
|
|
3674
|
+
west = 4
|
|
3675
|
+
end enum
|
|
3676
|
+
|
|
3677
|
+
enum Weather 'added member
|
|
3678
|
+
rainy
|
|
3679
|
+
sunny
|
|
3680
|
+
snowy
|
|
3681
|
+
end enum
|
|
3682
|
+
|
|
3683
|
+
enum Colors 'removed member
|
|
3684
|
+
blue
|
|
3685
|
+
red
|
|
3686
|
+
green
|
|
3687
|
+
end enum
|
|
3688
|
+
`);
|
|
3689
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3690
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3691
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(3);
|
|
3692
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3693
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(2);
|
|
3694
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.has('weather'));
|
|
3695
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.has('colors'));
|
|
3696
|
+
});
|
|
3697
|
+
it('should include changes in enum, if different underlying type', () => {
|
|
3698
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3699
|
+
enum Direction
|
|
3700
|
+
north = 1
|
|
3701
|
+
east = 2
|
|
3702
|
+
south = 3
|
|
3703
|
+
west = 4
|
|
3704
|
+
end enum
|
|
3705
|
+
`);
|
|
3706
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3707
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3708
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3709
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3710
|
+
enum Direction ' now is a string
|
|
3711
|
+
north = "N"
|
|
3712
|
+
east = "E"
|
|
3713
|
+
south = "S"
|
|
3714
|
+
west = "W"
|
|
3715
|
+
end enum
|
|
3716
|
+
`);
|
|
3717
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3718
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3719
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3720
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3721
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
|
|
3722
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.has('direction'));
|
|
3723
|
+
});
|
|
3724
|
+
it('should include changes in const, if different underlying type', () => {
|
|
3725
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3726
|
+
namespace alpha.beta
|
|
3727
|
+
const PI = 3.14
|
|
3728
|
+
end namespace
|
|
3729
|
+
`);
|
|
3730
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3731
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3732
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3733
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3734
|
+
namespace alpha.beta
|
|
3735
|
+
const PI = "lemon chiffon"
|
|
3736
|
+
end namespace
|
|
3737
|
+
`);
|
|
3738
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3739
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3740
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
|
|
3741
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3742
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
|
|
3743
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.has('alpha.beta.pi'));
|
|
3744
|
+
});
|
|
3745
|
+
it('should not include changes inside a function if the param types are known', () => {
|
|
3746
|
+
let mainFile = program.setFile('source/main.bs', `
|
|
3747
|
+
function func1(p as string) as integer
|
|
3748
|
+
return len(p)
|
|
3749
|
+
end function
|
|
3750
|
+
|
|
3751
|
+
sub displayModelTypeInLabel(myLabel as roSgNodeLabel)
|
|
3752
|
+
print myLabel.text
|
|
3753
|
+
di = createObject("roDeviceInfo")' as roDeviceInfo
|
|
3754
|
+
myLabel.text = di.GetFriendlyName()
|
|
3755
|
+
print myLabel.getChildren(0, -1)
|
|
3756
|
+
end sub
|
|
3757
|
+
`);
|
|
3758
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3759
|
+
let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3760
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
|
|
3761
|
+
mainFile = program.setFile('source/main.bs', `
|
|
3762
|
+
function func1(p as string) as integer
|
|
3763
|
+
return len(p)+1
|
|
3764
|
+
end function
|
|
3765
|
+
|
|
3766
|
+
sub displayModelTypeInLabel(myLabel as roSgNodeLabel)
|
|
3767
|
+
print myLabel.text
|
|
3768
|
+
di = createObject("roDeviceInfo") as roDeviceInfo
|
|
3769
|
+
myLabel.text = di.GetFriendlyName()
|
|
3770
|
+
print myLabel.getChildren(0, -1)
|
|
3771
|
+
end sub
|
|
3772
|
+
`);
|
|
3773
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3774
|
+
runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3775
|
+
(0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
|
|
3776
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3777
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
|
|
3778
|
+
});
|
|
3779
|
+
it('classes that override AA built-in methods show change properly', () => {
|
|
3780
|
+
const classFileContent = `
|
|
3781
|
+
class AAOverRide
|
|
3782
|
+
sub count(num as integer) as void
|
|
3783
|
+
print num
|
|
3784
|
+
end sub
|
|
3785
|
+
end class
|
|
3786
|
+
`;
|
|
3787
|
+
let mainFile = program.setFile('source/class.bs', classFileContent);
|
|
3788
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3789
|
+
// No changes!
|
|
3790
|
+
mainFile = program.setFile('source/class.bs', classFileContent);
|
|
3791
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3792
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3793
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
|
|
3794
|
+
});
|
|
3795
|
+
it('functions in a namespace that return classes show change properly', () => {
|
|
3796
|
+
const fileContent = `
|
|
3797
|
+
namespace Alpha.Beta
|
|
3798
|
+
|
|
3799
|
+
class SomeKlass
|
|
3800
|
+
name as string
|
|
3801
|
+
function combineName(klass as SomeKlass)
|
|
3802
|
+
m.name = m.name+klass.name
|
|
3803
|
+
end function
|
|
3804
|
+
end class
|
|
3805
|
+
|
|
3806
|
+
function getSomeKlass(name as string) as SomeKlass
|
|
3807
|
+
k = new SomeKlass()
|
|
3808
|
+
k.name = name
|
|
3809
|
+
return k
|
|
3810
|
+
end function
|
|
3811
|
+
end namespace
|
|
3812
|
+
`;
|
|
3813
|
+
let mainFile = program.setFile('source/class.bs', fileContent);
|
|
3814
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3815
|
+
// No changes!
|
|
3816
|
+
mainFile = program.setFile('source/class.bs', fileContent);
|
|
3817
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3818
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3819
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
|
|
3820
|
+
});
|
|
3821
|
+
it('functions in a namespace that have class params show change properly', () => {
|
|
3822
|
+
const fileContent = `
|
|
3823
|
+
namespace Alpha.Beta
|
|
3824
|
+
|
|
3825
|
+
class SomeKlass
|
|
3826
|
+
name as string
|
|
3827
|
+
function combineName(klass as SomeKlass)
|
|
3828
|
+
m.name = m.name+klass.name
|
|
3829
|
+
end function
|
|
3830
|
+
end class
|
|
3831
|
+
|
|
3832
|
+
function combineKlass(klass1 as SomeKlass, klass2 as SomeKlass) as SomeKlass
|
|
3833
|
+
klass1.combineName(klass2)
|
|
3834
|
+
return klass1
|
|
3835
|
+
end function
|
|
3836
|
+
end namespace
|
|
3837
|
+
`;
|
|
3838
|
+
let mainFile = program.setFile('source/class.bs', fileContent);
|
|
3839
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3840
|
+
// No changes!
|
|
3841
|
+
mainFile = program.setFile('source/class.bs', fileContent);
|
|
3842
|
+
program.plugins.emit('onFileValidate', { program: program, file: mainFile });
|
|
3843
|
+
let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
3844
|
+
(0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
|
|
3845
|
+
});
|
|
3257
3846
|
});
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3847
|
+
});
|
|
3848
|
+
describe('propertyHints', () => {
|
|
3849
|
+
it('extracts property names for completion', () => {
|
|
3850
|
+
const file = program.setFile('source/main.brs', `
|
|
3851
|
+
function main(arg as string)
|
|
3852
|
+
aa1 = {
|
|
3853
|
+
"sprop1": 0,
|
|
3854
|
+
prop1: 1
|
|
3855
|
+
prop2: {
|
|
3856
|
+
prop3: 2
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3859
|
+
aa2 = {
|
|
3860
|
+
prop4: {
|
|
3861
|
+
prop5: 5,
|
|
3862
|
+
"sprop2": 0,
|
|
3863
|
+
prop6: 6
|
|
3864
|
+
},
|
|
3865
|
+
prop7: 7
|
|
3866
|
+
}
|
|
3867
|
+
calling({
|
|
3868
|
+
prop8: 8,
|
|
3869
|
+
prop9: 9
|
|
3870
|
+
})
|
|
3871
|
+
aa1.field1 = 1
|
|
3872
|
+
aa1.field2.field3 = 2
|
|
3873
|
+
calling(aa2.field4, 3 + aa2.field5.field6)
|
|
3264
3874
|
end function
|
|
3265
3875
|
`);
|
|
3266
|
-
const
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
const lookups = [
|
|
3270
|
-
{ line: 2, col: 26, name: 'firstFloat', type: new FloatType_1.FloatType() },
|
|
3271
|
-
{ line: 3, col: 32, name: 'firstFloat', type: new FloatType_1.FloatType() }
|
|
3876
|
+
const expected = [
|
|
3877
|
+
'field1', 'field2', 'field3', 'field4', 'field5', 'field6',
|
|
3878
|
+
'prop1', 'prop2', 'prop3', 'prop4', 'prop5', 'prop6', 'prop7', 'prop8', 'prop9'
|
|
3272
3879
|
];
|
|
3273
|
-
|
|
3274
|
-
(0,
|
|
3880
|
+
const { propertyHints } = file['_cachedLookups'];
|
|
3881
|
+
(0, chai_config_spec_1.expect)(Object.keys(propertyHints).sort()).to.deep.equal(expected, 'Initial hints');
|
|
3275
3882
|
});
|
|
3276
|
-
it('
|
|
3277
|
-
const file = program.setFile('source/main.
|
|
3278
|
-
function
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3883
|
+
it('extracts property names matching JavaScript reserved names', () => {
|
|
3884
|
+
const file = program.setFile('source/main.brs', `
|
|
3885
|
+
function main(arg as string)
|
|
3886
|
+
aa1 = {
|
|
3887
|
+
"constructor": 0,
|
|
3888
|
+
constructor: 1
|
|
3889
|
+
valueOf: {
|
|
3890
|
+
toString: 2
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
aa1.constructor = 1
|
|
3894
|
+
aa1.valueOf.toString = 2
|
|
3286
3895
|
end function
|
|
3287
3896
|
`);
|
|
3288
|
-
const
|
|
3289
|
-
|
|
3290
|
-
const funcExpr = file.parser.references.functionExpressions[0];
|
|
3291
|
-
const lookups = [
|
|
3292
|
-
{ line: 6, col: 26, name: 'firstFloat', type: new FloatType_1.FloatType() },
|
|
3293
|
-
{ line: 7, col: 32, name: 'firstFloat', type: new FloatType_1.FloatType() }
|
|
3897
|
+
const expected = [
|
|
3898
|
+
'constructor', 'tostring', 'valueof'
|
|
3294
3899
|
];
|
|
3295
|
-
|
|
3296
|
-
(0,
|
|
3900
|
+
const { propertyHints } = file['_cachedLookups'];
|
|
3901
|
+
(0, chai_config_spec_1.expect)(Object.keys(propertyHints).sort()).to.deep.equal(expected, 'Initial hints');
|
|
3297
3902
|
});
|
|
3298
3903
|
});
|
|
3299
|
-
it('defaults to `dynamic` type for a complex expression', () => {
|
|
3300
|
-
const file = program.setFile('source/main.brs', `
|
|
3301
|
-
sub main()
|
|
3302
|
-
name = "cat"
|
|
3303
|
-
thing = m["key"](true)
|
|
3304
|
-
end sub
|
|
3305
|
-
`);
|
|
3306
|
-
program.validate();
|
|
3307
|
-
//sanity check
|
|
3308
|
-
(0, chai_1.expect)(file.parser.references.assignmentStatements[0].containingFunction.symbolTable.getSymbolType('name')).be.instanceof(StringType_1.StringType);
|
|
3309
|
-
//this complex expression should resolve to dynamic type when not known
|
|
3310
|
-
(0, chai_1.expect)(file.parser.references.assignmentStatements[0].containingFunction.symbolTable.getSymbolType('thing')).be.instanceof(DynamicType_1.DynamicType);
|
|
3311
|
-
});
|
|
3312
3904
|
});
|
|
3313
3905
|
//# sourceMappingURL=BrsFile.spec.js.map
|