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