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