brighterscript 1.0.0-alpha.24 → 1.0.0-alpha.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +521 -233
- package/README.md +45 -139
- package/bsconfig.schema.json +46 -0
- package/dist/ActionPipeline.d.ts +10 -0
- package/dist/ActionPipeline.js +40 -0
- package/dist/ActionPipeline.js.map +1 -0
- package/dist/AstValidationSegmenter.d.ts +25 -0
- package/dist/AstValidationSegmenter.js +152 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +40 -4
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.js +3 -3
- package/dist/Cache.js.map +1 -1
- package/dist/CacheVerifier.d.ts +7 -0
- package/dist/CacheVerifier.js +20 -0
- package/dist/CacheVerifier.js.map +1 -0
- package/dist/CodeActionUtil.d.ts +3 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +3 -2
- package/dist/CommentFlagProcessor.js +5 -4
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +3 -2
- package/dist/DependencyGraph.js +11 -10
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.js +9 -5
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +1 -0
- package/dist/DiagnosticFilterer.js +5 -3
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +61 -13
- package/dist/DiagnosticMessages.js +116 -19
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
- package/dist/DiagnosticSeverityAdjuster.js +41 -0
- package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
- package/dist/FunctionScope.d.ts +28 -0
- package/dist/FunctionScope.js +52 -0
- package/dist/FunctionScope.js.map +1 -0
- package/dist/KeyedThrottler.d.ts +3 -3
- package/dist/KeyedThrottler.js +3 -3
- package/dist/KeyedThrottler.js.map +1 -1
- package/dist/LanguageServer.d.ts +23 -11
- package/dist/LanguageServer.js +150 -69
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +3 -2
- package/dist/Logger.js +11 -3
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +21 -3
- package/dist/PluginInterface.js +74 -6
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +158 -79
- package/dist/Program.js +841 -706
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +22 -12
- package/dist/ProgramBuilder.js +130 -103
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +86 -137
- package/dist/Scope.js +453 -519
- package/dist/Scope.js.map +1 -1
- package/dist/Stopwatch.js +1 -1
- package/dist/Stopwatch.js.map +1 -1
- package/dist/SymbolTable.d.ts +89 -34
- package/dist/SymbolTable.js +239 -114
- package/dist/SymbolTable.js.map +1 -1
- package/dist/Throttler.d.ts +12 -0
- package/dist/Throttler.js +39 -0
- package/dist/Throttler.js.map +1 -1
- package/dist/Watcher.d.ts +0 -3
- package/dist/Watcher.js +0 -3
- package/dist/Watcher.js.map +1 -1
- package/dist/XmlScope.d.ts +4 -11
- package/dist/XmlScope.js +75 -88
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +48 -0
- package/dist/astUtils/CachedLookups.js +323 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +9 -5
- package/dist/astUtils/{AstEditor.js → Editor.js} +10 -4
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +69 -65
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +10 -10
- package/dist/astUtils/creators.js +54 -24
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +5 -5
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +132 -104
- package/dist/astUtils/reflection.js +220 -174
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +256 -157
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +12 -12
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +53 -35
- package/dist/astUtils/visitors.js +29 -3
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +208 -52
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -9
- package/dist/astUtils/xml.js +9 -9
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +11 -2
- package/dist/bscPlugin/BscPlugin.js +37 -3
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
- package/dist/bscPlugin/CallExpressionInfo.js +131 -0
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
- package/dist/bscPlugin/FileWriter.d.ts +6 -0
- package/dist/bscPlugin/FileWriter.js +24 -0
- package/dist/bscPlugin/FileWriter.js.map +1 -0
- package/dist/bscPlugin/SignatureHelpUtil.d.ts +10 -0
- package/dist/bscPlugin/SignatureHelpUtil.js +136 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +16 -13
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +16 -16
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +52 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.js +517 -26
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1909 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js +210 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js +88 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
- package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +7 -7
- package/dist/bscPlugin/hover/HoverProcessor.js +123 -125
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +371 -53
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +2 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +83 -23
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +83 -6
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +1 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
- package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
- package/dist/bscPlugin/serialize/BslibManager.js +40 -0
- package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
- package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
- package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
- package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
- package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.d.ts → BrsFileTranspileProcessor.d.ts} +4 -2
- package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.js → BrsFileTranspileProcessor.js} +38 -12
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +12 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +13 -5
- package/dist/bscPlugin/validation/BrsFileValidator.js +262 -52
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +230 -14
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
- package/dist/bscPlugin/validation/ProgramValidator.d.ts +10 -0
- package/dist/bscPlugin/validation/ProgramValidator.js +32 -0
- package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +58 -27
- package/dist/bscPlugin/validation/ScopeValidator.js +514 -286
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2527 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js +44 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
- package/dist/cli.js +104 -13
- package/dist/cli.js.map +1 -1
- package/dist/deferred.d.ts +3 -3
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +8 -2
- package/dist/diagnosticUtils.js +47 -17
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +8 -10
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +26 -0
- package/dist/files/AssetFile.js +26 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +523 -493
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +111 -117
- package/dist/files/BrsFile.js +684 -1142
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1783 -1233
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +104 -0
- package/dist/files/BscFile.js +16 -0
- package/dist/files/BscFile.js.map +1 -0
- package/dist/files/Factory.d.ts +25 -0
- package/dist/files/Factory.js +22 -0
- package/dist/files/Factory.js.map +1 -0
- package/dist/files/LazyFileData.d.ts +20 -0
- package/dist/files/LazyFileData.js +54 -0
- package/dist/files/LazyFileData.js.map +1 -0
- package/dist/files/LazyFileData.spec.d.ts +1 -0
- package/dist/files/LazyFileData.spec.js +27 -0
- package/dist/files/LazyFileData.spec.js.map +1 -0
- package/dist/files/XmlFile.d.ts +70 -32
- package/dist/files/XmlFile.js +106 -118
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +325 -262
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +48 -40
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.js +84 -24
- package/dist/files/tests/optionalChaning.spec.js.map +1 -1
- package/dist/globalCallables.js +16 -21
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +421 -162
- package/dist/interfaces.js +27 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Character.spec.js +5 -5
- package/dist/lexer/Character.spec.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +12 -5
- package/dist/lexer/Lexer.js +28 -13
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +181 -135
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +9 -1
- package/dist/lexer/Token.js +9 -1
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +8 -0
- package/dist/lexer/TokenKind.js +24 -4
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +162 -0
- package/dist/parser/AstNode.js +225 -0
- package/dist/parser/AstNode.js.map +1 -0
- package/dist/parser/AstNode.spec.d.ts +1 -0
- package/dist/parser/AstNode.spec.js +165 -0
- package/dist/parser/AstNode.spec.js.map +1 -0
- package/dist/parser/BrsTranspileState.d.ts +4 -7
- package/dist/parser/BrsTranspileState.js +4 -12
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +376 -283
- package/dist/parser/Expression.js +742 -585
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +151 -145
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +48 -201
- package/dist/parser/Parser.js +705 -1026
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +861 -848
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +9 -8
- package/dist/parser/SGParser.js +10 -8
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +27 -38
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +98 -35
- package/dist/parser/SGTypes.js +169 -99
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +468 -272
- package/dist/parser/Statement.js +904 -631
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +47 -23
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +1 -1
- package/dist/parser/TranspileState.js +7 -12
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.js +3 -2
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +33 -23
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +25 -20
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +96 -94
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +22 -16
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +8 -8
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +58 -21
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +62 -21
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +8 -8
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +129 -21
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +5 -5
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +36 -36
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +92 -22
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +9 -9
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +59 -59
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +12 -12
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +12 -12
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/Relational.spec.js +13 -13
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +96 -57
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +89 -89
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js +127 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +15 -15
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/ConstStatement.spec.js +82 -33
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Continue.spec.d.ts +1 -0
- package/dist/parser/tests/statement/Continue.spec.js +119 -0
- package/dist/parser/tests/statement/Continue.spec.js.map +1 -0
- package/dist/parser/tests/statement/Declaration.spec.js +19 -19
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +22 -22
- package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.js +98 -302
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
- package/dist/parser/tests/statement/For.spec.js +9 -10
- package/dist/parser/tests/statement/For.spec.js.map +1 -1
- package/dist/parser/tests/statement/ForEach.spec.js +8 -9
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/statement/Function.spec.js +44 -35
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +5 -5
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +20 -20
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +30 -196
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +11 -11
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +16 -78
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +36 -34
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +14 -12
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +48 -35
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +6 -6
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +6 -6
- package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +18 -16
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +1 -1
- package/dist/preprocessor/Manifest.js +2 -2
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/preprocessor/Manifest.spec.js +8 -8
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/preprocessor/Preprocessor.d.ts +5 -6
- package/dist/preprocessor/Preprocessor.js +5 -5
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/preprocessor/Preprocessor.spec.js +25 -25
- package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.d.ts +1 -1
- package/dist/preprocessor/PreprocessorParser.js +7 -1
- package/dist/preprocessor/PreprocessorParser.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +13 -13
- package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
- package/dist/roku-types/data.json +5892 -10081
- package/dist/roku-types/index.d.ts +622 -1719
- package/dist/types/ArrayType.d.ts +10 -9
- package/dist/types/ArrayType.js +65 -60
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +36 -68
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +11 -0
- package/dist/types/AssociativeArrayType.js +52 -0
- package/dist/types/AssociativeArrayType.js.map +1 -0
- package/dist/types/BaseFunctionType.d.ts +9 -0
- package/dist/types/BaseFunctionType.js +25 -0
- package/dist/types/BaseFunctionType.js.map +1 -0
- package/dist/types/BooleanType.d.ts +8 -5
- package/dist/types/BooleanType.js +14 -7
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +10 -6
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +32 -21
- package/dist/types/BscType.js +118 -21
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BscTypeKind.d.ts +25 -0
- package/dist/types/BscTypeKind.js +30 -0
- package/dist/types/BscTypeKind.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
- package/dist/types/BuiltInInterfaceAdder.js +171 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +116 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
- package/dist/types/ClassType.d.ts +17 -0
- package/dist/types/ClassType.js +58 -0
- package/dist/types/ClassType.js.map +1 -0
- package/dist/types/ClassType.spec.d.ts +1 -0
- package/dist/types/ClassType.spec.js +77 -0
- package/dist/types/ClassType.spec.js.map +1 -0
- package/dist/types/ComponentType.d.ts +26 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +8 -5
- package/dist/types/DoubleType.js +18 -16
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +12 -6
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +9 -5
- package/dist/types/DynamicType.js +15 -4
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/DynamicType.spec.js +16 -5
- package/dist/types/DynamicType.spec.js.map +1 -1
- package/dist/types/EnumType.d.ts +30 -12
- package/dist/types/EnumType.js +43 -17
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/EnumType.spec.d.ts +1 -0
- package/dist/types/EnumType.spec.js +33 -0
- package/dist/types/EnumType.spec.js.map +1 -0
- package/dist/types/FloatType.d.ts +8 -5
- package/dist/types/FloatType.js +18 -16
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -6
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +13 -8
- package/dist/types/FunctionType.js +30 -14
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +28 -0
- package/dist/types/InheritableType.js +152 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +8 -5
- package/dist/types/IntegerType.js +18 -16
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +8 -6
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +12 -13
- package/dist/types/InterfaceType.js +20 -48
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +90 -56
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/InvalidType.d.ts +7 -5
- package/dist/types/InvalidType.js +13 -7
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +8 -6
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +8 -5
- package/dist/types/LongIntegerType.js +17 -15
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +10 -6
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/NamespaceType.d.ts +12 -0
- package/dist/types/NamespaceType.js +28 -0
- package/dist/types/NamespaceType.js.map +1 -0
- package/dist/types/ObjectType.d.ts +9 -8
- package/dist/types/ObjectType.js +21 -11
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ObjectType.spec.js +3 -3
- package/dist/types/ObjectType.spec.js.map +1 -1
- package/dist/types/ReferenceType.d.ts +63 -0
- package/dist/types/ReferenceType.js +423 -0
- package/dist/types/ReferenceType.js.map +1 -0
- package/dist/types/ReferenceType.spec.d.ts +1 -0
- package/dist/types/ReferenceType.spec.js +137 -0
- package/dist/types/ReferenceType.spec.js.map +1 -0
- package/dist/types/StringType.d.ts +11 -5
- package/dist/types/StringType.js +18 -7
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +3 -5
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +22 -17
- package/dist/types/TypedFunctionType.js +78 -60
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/TypedFunctionType.spec.js +105 -20
- package/dist/types/TypedFunctionType.spec.js.map +1 -1
- package/dist/types/UninitializedType.d.ts +8 -6
- package/dist/types/UninitializedType.js +13 -7
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +20 -0
- package/dist/types/UnionType.js +123 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +130 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +8 -5
- package/dist/types/VoidType.js +14 -7
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/VoidType.spec.js +3 -3
- package/dist/types/VoidType.spec.js.map +1 -1
- package/dist/types/helper.spec.d.ts +1 -0
- package/dist/types/helper.spec.js +145 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +19 -37
- package/dist/types/helpers.js +159 -99
- package/dist/types/helpers.js.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.js +39 -0
- package/dist/types/index.js.map +1 -0
- package/dist/util.d.ts +143 -139
- package/dist/util.js +864 -385
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +8 -25
- package/dist/validators/ClassValidator.js +99 -179
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +165 -152
- package/dist/astUtils/AstEditor.js.map +0 -1
- package/dist/astUtils/AstEditor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -32
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
- package/dist/parser/SGTypes.spec.js +0 -351
- package/dist/parser/SGTypes.spec.js.map +0 -1
- package/dist/types/CustomType.d.ts +0 -12
- package/dist/types/CustomType.js +0 -44
- package/dist/types/CustomType.js.map +0 -1
- package/dist/types/LazyType.d.ts +0 -16
- package/dist/types/LazyType.js +0 -44
- package/dist/types/LazyType.js.map +0 -1
- /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
- /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{parser/SGTypes.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.failStatementType = exports.rangeToArray = void 0;
|
|
4
|
-
const
|
|
3
|
+
exports.failStatementType = exports.rangeToArray = exports.parse = void 0;
|
|
4
|
+
const chai_config_spec_1 = require("../chai-config.spec");
|
|
5
5
|
const Lexer_1 = require("../lexer/Lexer");
|
|
6
6
|
const TokenKind_1 = require("../lexer/TokenKind");
|
|
7
7
|
const Expression_1 = require("./Expression");
|
|
@@ -11,212 +11,19 @@ const vscode_languageserver_1 = require("vscode-languageserver");
|
|
|
11
11
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
12
12
|
const reflection_1 = require("../astUtils/reflection");
|
|
13
13
|
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
14
|
-
const BrsTranspileState_1 = require("./BrsTranspileState");
|
|
15
|
-
const source_map_1 = require("source-map");
|
|
16
|
-
const BrsFile_1 = require("../files/BrsFile");
|
|
17
|
-
const Program_1 = require("../Program");
|
|
18
14
|
const visitors_1 = require("../astUtils/visitors");
|
|
19
15
|
const SymbolTable_1 = require("../SymbolTable");
|
|
20
|
-
const ArrayType_1 = require("../types/ArrayType");
|
|
21
|
-
const CustomType_1 = require("../types/CustomType");
|
|
22
|
-
const DynamicType_1 = require("../types/DynamicType");
|
|
23
16
|
const IntegerType_1 = require("../types/IntegerType");
|
|
24
|
-
const
|
|
25
|
-
const ObjectType_1 = require("../types/ObjectType");
|
|
17
|
+
const FloatType_1 = require("../types/FloatType");
|
|
26
18
|
const StringType_1 = require("../types/StringType");
|
|
27
|
-
const
|
|
28
|
-
const VoidType_1 = require("../types/VoidType");
|
|
29
|
-
const util_1 = require("../util");
|
|
19
|
+
const types_1 = require("../types");
|
|
30
20
|
describe('parser', () => {
|
|
31
21
|
it('emits empty object when empty token list is provided', () => {
|
|
32
|
-
(0,
|
|
22
|
+
(0, chai_config_spec_1.expect)(Parser_1.Parser.parse([])).to.deep.include({
|
|
33
23
|
statements: [],
|
|
34
24
|
diagnostics: []
|
|
35
25
|
});
|
|
36
26
|
});
|
|
37
|
-
describe('findReferences', () => {
|
|
38
|
-
it('recomputes localVars', () => {
|
|
39
|
-
const parser = Parser_1.Parser.parse(`
|
|
40
|
-
sub main(herd)
|
|
41
|
-
for each zombie in herd
|
|
42
|
-
isAlive = false
|
|
43
|
-
end for
|
|
44
|
-
for i = 0 to 10 step 1
|
|
45
|
-
j = i
|
|
46
|
-
end for
|
|
47
|
-
humansAreAlive = false
|
|
48
|
-
end sub
|
|
49
|
-
`);
|
|
50
|
-
(0, chai_1.expect)(parser.references.functionExpressions[0].symbolTable.getOwnSymbols().map(x => x.name).sort()).to.eql([
|
|
51
|
-
'herd',
|
|
52
|
-
'humansAreAlive',
|
|
53
|
-
'i',
|
|
54
|
-
'isAlive',
|
|
55
|
-
'j',
|
|
56
|
-
'zombie'
|
|
57
|
-
]);
|
|
58
|
-
parser.invalidateReferences();
|
|
59
|
-
(0, chai_1.expect)(parser.references.functionExpressions[0].symbolTable.getOwnSymbols().map(x => x.name).sort()).to.eql([
|
|
60
|
-
'herd',
|
|
61
|
-
'humansAreAlive',
|
|
62
|
-
'i',
|
|
63
|
-
'isAlive',
|
|
64
|
-
'j',
|
|
65
|
-
'zombie'
|
|
66
|
-
]);
|
|
67
|
-
});
|
|
68
|
-
it('assigns localVars to correct function expression bucket', () => {
|
|
69
|
-
const parser = Parser_1.Parser.parse(`
|
|
70
|
-
sub main()
|
|
71
|
-
outerName = "bob"
|
|
72
|
-
speak = sub()
|
|
73
|
-
innerName = "innerBob"
|
|
74
|
-
end sub
|
|
75
|
-
age = 12
|
|
76
|
-
end sub
|
|
77
|
-
`);
|
|
78
|
-
parser.invalidateReferences();
|
|
79
|
-
(0, chai_1.expect)(parser.references.functionExpressions.map(x => {
|
|
80
|
-
return x.symbolTable.getOwnSymbols().map(x => x.name);
|
|
81
|
-
})).to.eql([
|
|
82
|
-
[
|
|
83
|
-
'outerName',
|
|
84
|
-
'speak',
|
|
85
|
-
'age'
|
|
86
|
-
],
|
|
87
|
-
[
|
|
88
|
-
'innerName'
|
|
89
|
-
]
|
|
90
|
-
]);
|
|
91
|
-
});
|
|
92
|
-
it('gets called if references are missing', () => {
|
|
93
|
-
const parser = Parser_1.Parser.parse(`
|
|
94
|
-
sub main()
|
|
95
|
-
end sub
|
|
96
|
-
|
|
97
|
-
sub UnusedFunction()
|
|
98
|
-
end sub
|
|
99
|
-
`);
|
|
100
|
-
(0, chai_1.expect)(parser.references.functionStatements.map(x => x.name.text)).to.eql([
|
|
101
|
-
'main',
|
|
102
|
-
'UnusedFunction'
|
|
103
|
-
]);
|
|
104
|
-
//simulate a tree-shaking plugin by removing the `UnusedFunction`
|
|
105
|
-
parser.ast.statements.splice(1);
|
|
106
|
-
//tell the parser we modified the AST and need to regenerate references
|
|
107
|
-
parser.invalidateReferences();
|
|
108
|
-
(0, chai_1.expect)(parser['_references']).not.to.exist;
|
|
109
|
-
//calling `references` automatically regenerates the references
|
|
110
|
-
(0, chai_1.expect)(parser.references.functionStatements.map(x => x.name.text)).to.eql([
|
|
111
|
-
'main'
|
|
112
|
-
]);
|
|
113
|
-
});
|
|
114
|
-
function expressionsToStrings(expressions) {
|
|
115
|
-
return [...expressions.values()].map(x => {
|
|
116
|
-
const file = new BrsFile_1.BrsFile('', '', new Program_1.Program({}));
|
|
117
|
-
const state = new BrsTranspileState_1.BrsTranspileState(file);
|
|
118
|
-
return new source_map_1.SourceNode(null, null, null, x.transpile(state)).toString();
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
it('works for references.expressions', () => {
|
|
122
|
-
const parser = Parser_1.Parser.parse(`
|
|
123
|
-
b += "plus-equal"
|
|
124
|
-
a += 1 + 2
|
|
125
|
-
b += getValue1() + getValue2()
|
|
126
|
-
increment++
|
|
127
|
-
decrement--
|
|
128
|
-
some.node@.doCallfunc()
|
|
129
|
-
bravo(3 + 4).jump(callMe())
|
|
130
|
-
obj = {
|
|
131
|
-
val1: someValue
|
|
132
|
-
}
|
|
133
|
-
arr = [
|
|
134
|
-
one
|
|
135
|
-
]
|
|
136
|
-
thing = alpha.bravo
|
|
137
|
-
alpha.charlie()
|
|
138
|
-
delta(alpha.delta)
|
|
139
|
-
call1().a.b.call2()
|
|
140
|
-
class Person
|
|
141
|
-
name as string = "bob"
|
|
142
|
-
end class
|
|
143
|
-
function thing(p1 = name.space.getSomething())
|
|
144
|
-
|
|
145
|
-
end function
|
|
146
|
-
`);
|
|
147
|
-
const expected = [
|
|
148
|
-
'"plus-equal"',
|
|
149
|
-
'b',
|
|
150
|
-
'b += "plus-equal"',
|
|
151
|
-
'1',
|
|
152
|
-
'2',
|
|
153
|
-
'a',
|
|
154
|
-
'a += 1 + 2',
|
|
155
|
-
'getValue1()',
|
|
156
|
-
'getValue2()',
|
|
157
|
-
'b',
|
|
158
|
-
'b += getValue1() + getValue2()',
|
|
159
|
-
'increment++',
|
|
160
|
-
'decrement--',
|
|
161
|
-
//currently the "toString" does a transpile, so that's why this is different.
|
|
162
|
-
'some.node.callfunc("doCallfunc", invalid)',
|
|
163
|
-
'3',
|
|
164
|
-
'4',
|
|
165
|
-
'3 + 4',
|
|
166
|
-
'callMe()',
|
|
167
|
-
'bravo(3 + 4).jump(callMe())',
|
|
168
|
-
'someValue',
|
|
169
|
-
'{\n val1: someValue\n}',
|
|
170
|
-
'one',
|
|
171
|
-
'[\n one\n]',
|
|
172
|
-
'alpha.bravo',
|
|
173
|
-
'alpha.charlie()',
|
|
174
|
-
'alpha.delta',
|
|
175
|
-
'delta(alpha.delta)',
|
|
176
|
-
'call1().a.b.call2()',
|
|
177
|
-
'"bob"',
|
|
178
|
-
'name.space.getSomething()'
|
|
179
|
-
];
|
|
180
|
-
(0, chai_1.expect)(expressionsToStrings(parser.references.expressions)).to.eql(expected);
|
|
181
|
-
//tell the parser we modified the AST and need to regenerate references
|
|
182
|
-
parser.invalidateReferences();
|
|
183
|
-
(0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected.sort());
|
|
184
|
-
});
|
|
185
|
-
it('works for references.expressions', () => {
|
|
186
|
-
const parser = Parser_1.Parser.parse(`
|
|
187
|
-
value = true or type(true) = "something" or Enums.A.Value = "value" and Enum1.Value = Name.Space.Enum2.Value
|
|
188
|
-
`);
|
|
189
|
-
const expected = [
|
|
190
|
-
'true',
|
|
191
|
-
'type(true)',
|
|
192
|
-
'"something"',
|
|
193
|
-
'true',
|
|
194
|
-
'Enums.A.Value',
|
|
195
|
-
'"value"',
|
|
196
|
-
'Enum1.Value',
|
|
197
|
-
'Name.Space.Enum2.Value',
|
|
198
|
-
'true or type(true) = "something" or Enums.A.Value = "value" and Enum1.Value = Name.Space.Enum2.Value'
|
|
199
|
-
];
|
|
200
|
-
(0, chai_1.expect)(expressionsToStrings(parser.references.expressions)).to.eql(expected);
|
|
201
|
-
//tell the parser we modified the AST and need to regenerate references
|
|
202
|
-
parser.invalidateReferences();
|
|
203
|
-
(0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected.sort());
|
|
204
|
-
});
|
|
205
|
-
it('works for logical expression', () => {
|
|
206
|
-
const parser = Parser_1.Parser.parse(`
|
|
207
|
-
value = Enums.A.Value = "value"
|
|
208
|
-
`);
|
|
209
|
-
const expected = [
|
|
210
|
-
'Enums.A.Value',
|
|
211
|
-
'"value"',
|
|
212
|
-
'Enums.A.Value = "value"'
|
|
213
|
-
];
|
|
214
|
-
(0, chai_1.expect)(expressionsToStrings(parser.references.expressions)).to.eql(expected);
|
|
215
|
-
//tell the parser we modified the AST and need to regenerate references
|
|
216
|
-
parser.invalidateReferences();
|
|
217
|
-
(0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected.sort());
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
27
|
describe('callfunc operator', () => {
|
|
221
28
|
it('is not allowed in brightscript mode', () => {
|
|
222
29
|
var _a;
|
|
@@ -225,7 +32,7 @@ describe('parser', () => {
|
|
|
225
32
|
node@.doSomething(1, 2)
|
|
226
33
|
end sub
|
|
227
34
|
`, Parser_1.ParseMode.BrightScript);
|
|
228
|
-
(0,
|
|
35
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('callfunc operator').message);
|
|
229
36
|
});
|
|
230
37
|
it('does not cause parse errors', () => {
|
|
231
38
|
var _a, _b, _c, _d, _e;
|
|
@@ -234,15 +41,15 @@ describe('parser', () => {
|
|
|
234
41
|
node@.doSomething(1, 2)
|
|
235
42
|
end sub
|
|
236
43
|
`, Parser_1.ParseMode.BrighterScript);
|
|
237
|
-
(0,
|
|
238
|
-
(0,
|
|
44
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
45
|
+
(0, chai_config_spec_1.expect)((_e = (_d = (_c = (_b = parser.statements[0]) === null || _b === void 0 ? void 0 : _b.func) === null || _c === void 0 ? void 0 : _c.body) === null || _d === void 0 ? void 0 : _d.statements[0]) === null || _e === void 0 ? void 0 : _e.expression).to.be.instanceof(Expression_1.CallfuncExpression);
|
|
239
46
|
});
|
|
240
47
|
});
|
|
241
48
|
describe('optional chaining operator', () => {
|
|
242
49
|
function getExpression(text, options) {
|
|
243
50
|
const parser = parse(text, options === null || options === void 0 ? void 0 : options.parseMode);
|
|
244
51
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
245
|
-
const expressions =
|
|
52
|
+
const expressions = parser.ast.findChildren(reflection_1.isExpression);
|
|
246
53
|
if (options === null || options === void 0 ? void 0 : options.matcher) {
|
|
247
54
|
return expressions.find(options.matcher);
|
|
248
55
|
}
|
|
@@ -252,50 +59,50 @@ describe('parser', () => {
|
|
|
252
59
|
}
|
|
253
60
|
it('works for ?.', () => {
|
|
254
61
|
const expression = getExpression(`value = person?.name`);
|
|
255
|
-
(0,
|
|
256
|
-
(0,
|
|
62
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.DottedGetExpression);
|
|
63
|
+
(0, chai_config_spec_1.expect)(expression.tokens.dot.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
|
|
257
64
|
});
|
|
258
65
|
it('works for ?[', () => {
|
|
259
66
|
const expression = getExpression(`value = person?["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
260
|
-
(0,
|
|
261
|
-
(0,
|
|
262
|
-
(0,
|
|
67
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
|
|
68
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftSquare);
|
|
69
|
+
(0, chai_config_spec_1.expect)(expression.tokens.questionDot).not.to.exist;
|
|
263
70
|
});
|
|
264
71
|
it('works for ?.[', () => {
|
|
265
72
|
var _a;
|
|
266
73
|
const expression = getExpression(`value = person?.["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
267
|
-
(0,
|
|
268
|
-
(0,
|
|
269
|
-
(0,
|
|
74
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
|
|
75
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.LeftSquareBracket);
|
|
76
|
+
(0, chai_config_spec_1.expect)((_a = expression.tokens.questionDot) === null || _a === void 0 ? void 0 : _a.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
|
|
270
77
|
});
|
|
271
78
|
it('works for ?@', () => {
|
|
272
79
|
const expression = getExpression(`value = someXml?@someAttr`);
|
|
273
|
-
(0,
|
|
274
|
-
(0,
|
|
80
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.XmlAttributeGetExpression);
|
|
81
|
+
(0, chai_config_spec_1.expect)(expression.tokens.at.kind).to.eql(TokenKind_1.TokenKind.QuestionAt);
|
|
275
82
|
});
|
|
276
83
|
it('works for ?(', () => {
|
|
277
84
|
const expression = getExpression(`value = person.getName?()`);
|
|
278
|
-
(0,
|
|
279
|
-
(0,
|
|
85
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
|
|
86
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
280
87
|
});
|
|
281
88
|
it('works for print statements using question mark', () => {
|
|
282
89
|
const { statements } = parse(`
|
|
283
90
|
?[1]
|
|
284
91
|
?(1+1)
|
|
285
92
|
`);
|
|
286
|
-
(0,
|
|
287
|
-
(0,
|
|
93
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceOf(Statement_1.PrintStatement);
|
|
94
|
+
(0, chai_config_spec_1.expect)(statements[1]).to.be.instanceOf(Statement_1.PrintStatement);
|
|
288
95
|
});
|
|
289
96
|
//TODO enable this once we properly parse IIFEs
|
|
290
97
|
it.skip('works for ?( in anonymous function', () => {
|
|
291
98
|
const expression = getExpression(`thing = (function() : end function)?()`);
|
|
292
|
-
(0,
|
|
293
|
-
(0,
|
|
99
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
|
|
100
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
294
101
|
});
|
|
295
102
|
it('works for ?( in new call', () => {
|
|
296
103
|
const expression = getExpression(`thing = new Person?()`, { parseMode: Parser_1.ParseMode.BrighterScript });
|
|
297
|
-
(0,
|
|
298
|
-
(0,
|
|
104
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.NewExpression);
|
|
105
|
+
(0, chai_config_spec_1.expect)(expression.call.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
299
106
|
});
|
|
300
107
|
it('distinguishes between optional chaining and ternary expression', () => {
|
|
301
108
|
const parser = parse(`
|
|
@@ -305,8 +112,9 @@ describe('parser', () => {
|
|
|
305
112
|
key = isTrue ? ["name"] : ["age"]
|
|
306
113
|
end sub
|
|
307
114
|
`, Parser_1.ParseMode.BrighterScript);
|
|
308
|
-
|
|
309
|
-
(0,
|
|
115
|
+
const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
|
|
116
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
|
|
117
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[2].value).is.instanceof(Expression_1.TernaryExpression);
|
|
310
118
|
});
|
|
311
119
|
it('distinguishes between optional chaining and ternary expression', () => {
|
|
312
120
|
const parser = parse(`
|
|
@@ -317,13 +125,14 @@ describe('parser', () => {
|
|
|
317
125
|
key = isTrue ? ["name"] : getDefault()
|
|
318
126
|
end sub
|
|
319
127
|
`, Parser_1.ParseMode.BrighterScript);
|
|
320
|
-
|
|
321
|
-
(0,
|
|
128
|
+
const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
|
|
129
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
|
|
130
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[1].value).is.instanceof(Expression_1.TernaryExpression);
|
|
322
131
|
});
|
|
323
132
|
});
|
|
324
133
|
describe('diagnostic locations', () => {
|
|
325
134
|
it('tracks basic diagnostic locations', () => {
|
|
326
|
-
(0,
|
|
135
|
+
(0, chai_config_spec_1.expect)(parse(`
|
|
327
136
|
sub main()
|
|
328
137
|
call()a
|
|
329
138
|
end sub
|
|
@@ -339,8 +148,8 @@ describe('parser', () => {
|
|
|
339
148
|
return "6c5cdf1"
|
|
340
149
|
end functionasdf
|
|
341
150
|
`).diagnostics;
|
|
342
|
-
(0,
|
|
343
|
-
(0,
|
|
151
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist.and.to.eql(DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression().message);
|
|
152
|
+
(0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.range).to.eql(vscode_languageserver_1.Range.create(3, 20, 3, 32));
|
|
344
153
|
});
|
|
345
154
|
});
|
|
346
155
|
describe('parse', () => {
|
|
@@ -377,20 +186,37 @@ describe('parser', () => {
|
|
|
377
186
|
});
|
|
378
187
|
it('supports using "interface" as parameter name', () => {
|
|
379
188
|
var _a;
|
|
380
|
-
(0,
|
|
189
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
381
190
|
sub main(interface as object)
|
|
382
191
|
end sub
|
|
383
192
|
`, Parser_1.ParseMode.BrighterScript).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
384
193
|
});
|
|
194
|
+
it('does not scrap the entire function when encountering unknown parameter type', () => {
|
|
195
|
+
const parser = parse(`
|
|
196
|
+
sub test(param1 as unknownType)
|
|
197
|
+
end sub
|
|
198
|
+
`);
|
|
199
|
+
// type validation happens at scope validation, not at the parser
|
|
200
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
201
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(parser.ast.statements[0])).to.be.true;
|
|
202
|
+
});
|
|
385
203
|
describe('namespace', () => {
|
|
386
|
-
it('
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
204
|
+
it('allows namespaces declared inside other namespaces', () => {
|
|
205
|
+
const parser = parse(`
|
|
206
|
+
namespace Level1
|
|
207
|
+
namespace Level2.Level3
|
|
208
|
+
sub main()
|
|
209
|
+
end sub
|
|
391
210
|
end namespace
|
|
392
|
-
end
|
|
393
|
-
`, Parser_1.ParseMode.BrighterScript)
|
|
211
|
+
end namespace
|
|
212
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
213
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
214
|
+
// We expect these names to be "as given" in this context, because we aren't evaluating a full program.
|
|
215
|
+
const namespaceStatements = parser.ast.findChildren(reflection_1.isNamespaceStatement);
|
|
216
|
+
(0, chai_config_spec_1.expect)(namespaceStatements.map(statement => statement.getName(Parser_1.ParseMode.BrighterScript))).to.have.deep.members([
|
|
217
|
+
'Level1.Level2.Level3',
|
|
218
|
+
'Level1'
|
|
219
|
+
]);
|
|
394
220
|
});
|
|
395
221
|
it('parses empty namespace', () => {
|
|
396
222
|
var _a;
|
|
@@ -398,8 +224,8 @@ describe('parser', () => {
|
|
|
398
224
|
namespace Name.Space
|
|
399
225
|
end namespace
|
|
400
226
|
`, Parser_1.ParseMode.BrighterScript);
|
|
401
|
-
(0,
|
|
402
|
-
(0,
|
|
227
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
228
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
403
229
|
});
|
|
404
230
|
it('includes body', () => {
|
|
405
231
|
var _a;
|
|
@@ -409,9 +235,9 @@ describe('parser', () => {
|
|
|
409
235
|
end sub
|
|
410
236
|
end namespace
|
|
411
237
|
`, Parser_1.ParseMode.BrighterScript);
|
|
412
|
-
(0,
|
|
413
|
-
(0,
|
|
414
|
-
(0,
|
|
238
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
239
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
240
|
+
(0, chai_config_spec_1.expect)(statements[0].body.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
415
241
|
});
|
|
416
242
|
it('supports comments and newlines', () => {
|
|
417
243
|
var _a;
|
|
@@ -427,7 +253,7 @@ describe('parser', () => {
|
|
|
427
253
|
'comment
|
|
428
254
|
end namespace 'comment
|
|
429
255
|
`, Parser_1.ParseMode.BrighterScript);
|
|
430
|
-
(0,
|
|
256
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
431
257
|
});
|
|
432
258
|
it('catches missing name', () => {
|
|
433
259
|
var _a;
|
|
@@ -435,7 +261,7 @@ describe('parser', () => {
|
|
|
435
261
|
namespace
|
|
436
262
|
end namespace
|
|
437
263
|
`, Parser_1.ParseMode.BrighterScript);
|
|
438
|
-
(0,
|
|
264
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('namespace').message);
|
|
439
265
|
});
|
|
440
266
|
it('recovers after missing `end namespace`', () => {
|
|
441
267
|
var _a, _b, _c;
|
|
@@ -444,9 +270,9 @@ describe('parser', () => {
|
|
|
444
270
|
sub main()
|
|
445
271
|
end sub
|
|
446
272
|
`, Parser_1.ParseMode.BrighterScript);
|
|
447
|
-
(0,
|
|
448
|
-
(0,
|
|
449
|
-
(0,
|
|
273
|
+
(0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
274
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('namespace').message);
|
|
275
|
+
(0, chai_config_spec_1.expect)((_c = (_b = parser.ast.statements[0]) === null || _b === void 0 ? void 0 : _b.body) === null || _c === void 0 ? void 0 : _c.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
450
276
|
});
|
|
451
277
|
it('adds diagnostic when encountering namespace in brightscript mode', () => {
|
|
452
278
|
var _a;
|
|
@@ -454,47 +280,12 @@ describe('parser', () => {
|
|
|
454
280
|
namespace Name.Space
|
|
455
281
|
end namespace
|
|
456
282
|
`);
|
|
457
|
-
(0,
|
|
458
|
-
});
|
|
459
|
-
it('declares a symbol table for the namespace', () => {
|
|
460
|
-
let parser = parse(`
|
|
461
|
-
namespace Name.Space
|
|
462
|
-
function funcInt() as integer
|
|
463
|
-
return 3
|
|
464
|
-
end function
|
|
465
|
-
|
|
466
|
-
function funcStr() as string
|
|
467
|
-
return "hello"
|
|
468
|
-
end function
|
|
469
|
-
end namespace
|
|
470
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
471
|
-
(0, chai_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
472
|
-
const namespaceStmt = parser.ast.statements[0];
|
|
473
|
-
(0, chai_1.expect)(namespaceStmt.symbolTable).to.be.instanceof(SymbolTable_1.SymbolTable);
|
|
474
|
-
(0, chai_1.expect)(namespaceStmt.symbolTable.getSymbolType('funcInt').toString()).to.equal('function funcInt() as integer');
|
|
475
|
-
(0, chai_1.expect)(namespaceStmt.symbolTable.getSymbolType('funcStr')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
|
|
476
|
-
const strFunctionType = namespaceStmt.symbolTable.getSymbolType('funcStr');
|
|
477
|
-
(0, chai_1.expect)(strFunctionType.returnType.toString()).to.equal('string');
|
|
478
|
-
});
|
|
479
|
-
it('adds a transpiled name of a function in a namespace to the parsers symbol table', () => {
|
|
480
|
-
let parser = parse(`
|
|
481
|
-
namespace Name.Space
|
|
482
|
-
function funcInt() as integer
|
|
483
|
-
return 3
|
|
484
|
-
end function
|
|
485
|
-
|
|
486
|
-
function funcStr() as string
|
|
487
|
-
return "hello"
|
|
488
|
-
end function
|
|
489
|
-
end namespace
|
|
490
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
491
|
-
(0, chai_1.expect)(parser.symbolTable.getSymbolType('Name_Space_funcInt')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
|
|
492
|
-
(0, chai_1.expect)(parser.symbolTable.getSymbolType('Name_Space_funcStr')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
|
|
283
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('namespace').message);
|
|
493
284
|
});
|
|
494
285
|
});
|
|
495
286
|
it('supports << operator', () => {
|
|
496
287
|
var _a;
|
|
497
|
-
(0,
|
|
288
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
498
289
|
sub main()
|
|
499
290
|
print ((r << 24) + (g << 16) + (b << 8) + a)
|
|
500
291
|
end sub
|
|
@@ -502,7 +293,7 @@ describe('parser', () => {
|
|
|
502
293
|
});
|
|
503
294
|
it('supports >> operator', () => {
|
|
504
295
|
var _a;
|
|
505
|
-
(0,
|
|
296
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
506
297
|
sub main()
|
|
507
298
|
print ((r >> 24) + (g >> 16) + (b >> 8) + a)
|
|
508
299
|
end sub
|
|
@@ -510,7 +301,7 @@ describe('parser', () => {
|
|
|
510
301
|
});
|
|
511
302
|
it('allows global function names with same as token to be called', () => {
|
|
512
303
|
var _a;
|
|
513
|
-
(0,
|
|
304
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
514
305
|
sub main()
|
|
515
306
|
print string(123)
|
|
516
307
|
end sub
|
|
@@ -524,18 +315,18 @@ describe('parser', () => {
|
|
|
524
315
|
age = personXml.firstChild@age
|
|
525
316
|
end sub
|
|
526
317
|
`);
|
|
527
|
-
(0,
|
|
318
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
528
319
|
let statements = parser.statements[0].func.body.statements;
|
|
529
320
|
let first = statements[0].value;
|
|
530
|
-
(0,
|
|
531
|
-
(0,
|
|
532
|
-
(0,
|
|
533
|
-
(0,
|
|
321
|
+
(0, chai_config_spec_1.expect)(first).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
|
|
322
|
+
(0, chai_config_spec_1.expect)(first.tokens.name.text).to.equal('firstName');
|
|
323
|
+
(0, chai_config_spec_1.expect)(first.tokens.at.text).to.equal('@');
|
|
324
|
+
(0, chai_config_spec_1.expect)(first.obj.tokens.name.text).to.equal('personXml');
|
|
534
325
|
let second = statements[1].value;
|
|
535
|
-
(0,
|
|
536
|
-
(0,
|
|
537
|
-
(0,
|
|
538
|
-
(0,
|
|
326
|
+
(0, chai_config_spec_1.expect)(second).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
|
|
327
|
+
(0, chai_config_spec_1.expect)(second.tokens.name.text).to.equal('age');
|
|
328
|
+
(0, chai_config_spec_1.expect)(second.tokens.at.text).to.equal('@');
|
|
329
|
+
(0, chai_config_spec_1.expect)(second.obj.tokens.name.text).to.equal('firstChild');
|
|
539
330
|
});
|
|
540
331
|
it('does not allow chaining of @ symbols', () => {
|
|
541
332
|
let parser = parse(`
|
|
@@ -544,58 +335,58 @@ describe('parser', () => {
|
|
|
544
335
|
name = personXml@name@age@shoeSize
|
|
545
336
|
end sub
|
|
546
337
|
`);
|
|
547
|
-
(0,
|
|
338
|
+
(0, chai_config_spec_1.expect)(parser.diagnostics).not.to.be.empty;
|
|
548
339
|
});
|
|
549
340
|
it('unknown function type does not invalidate rest of function', () => {
|
|
550
341
|
let { statements, diagnostics } = parse(`
|
|
551
342
|
function log() as UNKNOWN_TYPE
|
|
552
343
|
end function
|
|
553
344
|
`, Parser_1.ParseMode.BrightScript);
|
|
554
|
-
(0,
|
|
555
|
-
(0,
|
|
345
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics); // type validation happens at scope validation step
|
|
346
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
556
347
|
});
|
|
557
348
|
it('unknown function type is not a problem in Brighterscript mode', () => {
|
|
558
349
|
let { statements, diagnostics } = parse(`
|
|
559
350
|
function log() as UNKNOWN_TYPE
|
|
560
351
|
end function
|
|
561
352
|
`, Parser_1.ParseMode.BrighterScript);
|
|
562
|
-
(0,
|
|
563
|
-
(0,
|
|
353
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
354
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
564
355
|
});
|
|
565
356
|
it('allows namespaced function type in Brighterscript mode', () => {
|
|
566
357
|
let { statements, diagnostics } = parse(`
|
|
567
358
|
function log() as SOME_NAMESPACE.UNKNOWN_TYPE
|
|
568
359
|
end function
|
|
569
360
|
`, Parser_1.ParseMode.BrighterScript);
|
|
570
|
-
(0,
|
|
571
|
-
(0,
|
|
361
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
362
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
572
363
|
});
|
|
573
364
|
it('allows custom parameter types in BrighterscriptMode', () => {
|
|
574
365
|
let { statements, diagnostics } = parse(`
|
|
575
366
|
sub foo(value as UNKNOWN_TYPE)
|
|
576
367
|
end sub
|
|
577
368
|
`, Parser_1.ParseMode.BrighterScript);
|
|
578
|
-
(0,
|
|
579
|
-
(0,
|
|
369
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
370
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
580
371
|
});
|
|
581
|
-
it('does not
|
|
372
|
+
it('does not cause any diagnostics when custom parameter types are used in Brightscript Mode', () => {
|
|
582
373
|
let { diagnostics } = parse(`
|
|
583
374
|
sub foo(value as UNKNOWN_TYPE)
|
|
584
375
|
end sub
|
|
585
376
|
`, Parser_1.ParseMode.BrightScript);
|
|
586
|
-
(0,
|
|
377
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
587
378
|
});
|
|
588
379
|
it('allows custom namespaced parameter types in BrighterscriptMode', () => {
|
|
589
380
|
let { statements, diagnostics } = parse(`
|
|
590
381
|
sub foo(value as SOME_NAMESPACE.UNKNOWN_TYPE)
|
|
591
382
|
end sub
|
|
592
383
|
`, Parser_1.ParseMode.BrighterScript);
|
|
593
|
-
(0,
|
|
594
|
-
(0,
|
|
384
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
385
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
595
386
|
});
|
|
596
387
|
it('works with conditionals', () => {
|
|
597
388
|
var _a;
|
|
598
|
-
(0,
|
|
389
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
599
390
|
function printNumber()
|
|
600
391
|
if true then
|
|
601
392
|
print 1
|
|
@@ -607,7 +398,7 @@ describe('parser', () => {
|
|
|
607
398
|
});
|
|
608
399
|
it('supports single-line if statements', () => {
|
|
609
400
|
var _a;
|
|
610
|
-
(0,
|
|
401
|
+
(0, chai_config_spec_1.expect)((_a = parse(`If true Then print "error" : Stop`).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
611
402
|
});
|
|
612
403
|
it('works with excess newlines', () => {
|
|
613
404
|
var _a;
|
|
@@ -620,7 +411,7 @@ describe('parser', () => {
|
|
|
620
411
|
' print 1\n\n' +
|
|
621
412
|
' end if\n\n' +
|
|
622
413
|
'end function\n\n');
|
|
623
|
-
(0,
|
|
414
|
+
(0, chai_config_spec_1.expect)((_a = Parser_1.Parser.parse(tokens).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
624
415
|
});
|
|
625
416
|
it('does not invalidate entire file when line ends with a period', () => {
|
|
626
417
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -630,15 +421,101 @@ describe('parser', () => {
|
|
|
630
421
|
|
|
631
422
|
`);
|
|
632
423
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
633
|
-
(0,
|
|
424
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1, 'Error count should be 0');
|
|
634
425
|
});
|
|
635
|
-
it
|
|
426
|
+
it('allows printing object with trailing period', () => {
|
|
636
427
|
let { tokens } = Lexer_1.Lexer.scan(`print a.`);
|
|
637
|
-
let {
|
|
428
|
+
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
638
429
|
let printStatement = statements[0];
|
|
639
|
-
(0,
|
|
640
|
-
(0,
|
|
641
|
-
(0,
|
|
430
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod());
|
|
431
|
+
(0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
|
|
432
|
+
(0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.VariableExpression);
|
|
433
|
+
});
|
|
434
|
+
it('allows printing object with trailing period with multiple dotted gets', () => {
|
|
435
|
+
let { tokens } = Lexer_1.Lexer.scan(`print a.b.`);
|
|
436
|
+
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
437
|
+
let printStatement = statements[0];
|
|
438
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod());
|
|
439
|
+
(0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
|
|
440
|
+
(0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.DottedGetExpression);
|
|
441
|
+
});
|
|
442
|
+
describe('incomplete statements in the ast', () => {
|
|
443
|
+
it('adds variable expressions to the ast', () => {
|
|
444
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
445
|
+
function a()
|
|
446
|
+
NameA.
|
|
447
|
+
end function
|
|
448
|
+
|
|
449
|
+
namespace NameA
|
|
450
|
+
sub noop()
|
|
451
|
+
end sub
|
|
452
|
+
end namespace
|
|
453
|
+
`);
|
|
454
|
+
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
455
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression());
|
|
456
|
+
let stmt = statements[0].func.body.statements[0];
|
|
457
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
458
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)((stmt).expression)).to.be.true;
|
|
459
|
+
(0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('NameA');
|
|
460
|
+
});
|
|
461
|
+
it('adds unended call statements', () => {
|
|
462
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
463
|
+
function a()
|
|
464
|
+
lcase(
|
|
465
|
+
end function
|
|
466
|
+
`);
|
|
467
|
+
let { statements } = Parser_1.Parser.parse(tokens);
|
|
468
|
+
let stmt = statements[0].func.body.statements[0];
|
|
469
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
470
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)((stmt).expression)).to.be.true;
|
|
471
|
+
(0, chai_config_spec_1.expect)(stmt.expression.callee.tokens.name.text).to.equal('lcase');
|
|
472
|
+
});
|
|
473
|
+
it('adds unended indexed get statements', () => {
|
|
474
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
475
|
+
function a()
|
|
476
|
+
nums[
|
|
477
|
+
end function
|
|
478
|
+
|
|
479
|
+
const nums = [1, 2, 3]
|
|
480
|
+
`);
|
|
481
|
+
let { statements } = Parser_1.Parser.parse(tokens);
|
|
482
|
+
let stmt = statements[0].func.body.statements[0];
|
|
483
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
484
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isIndexedGetExpression)((stmt).expression)).to.be.true;
|
|
485
|
+
(0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('nums');
|
|
486
|
+
});
|
|
487
|
+
it('adds dotted gets', () => {
|
|
488
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
489
|
+
function foo(a as KlassA)
|
|
490
|
+
a.b.
|
|
491
|
+
end function
|
|
492
|
+
|
|
493
|
+
class KlassA
|
|
494
|
+
b as KlassB
|
|
495
|
+
end class
|
|
496
|
+
|
|
497
|
+
class KlassB
|
|
498
|
+
sub noop()
|
|
499
|
+
end sub
|
|
500
|
+
end class
|
|
501
|
+
`);
|
|
502
|
+
let { statements } = Parser_1.Parser.parse(tokens);
|
|
503
|
+
let stmt = statements[0].func.body.statements[0];
|
|
504
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
505
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)((stmt).expression)).to.be.true;
|
|
506
|
+
(0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('a');
|
|
507
|
+
(0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('b');
|
|
508
|
+
});
|
|
509
|
+
it('adds function statement with missing type after as', () => {
|
|
510
|
+
var _a;
|
|
511
|
+
let parser = parse(`
|
|
512
|
+
sub foo(thing as )
|
|
513
|
+
print thing
|
|
514
|
+
end sub
|
|
515
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
516
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
517
|
+
(0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
518
|
+
});
|
|
642
519
|
});
|
|
643
520
|
describe('comments', () => {
|
|
644
521
|
it('combines multi-line comments', () => {
|
|
@@ -648,8 +525,8 @@ describe('parser', () => {
|
|
|
648
525
|
'line 3
|
|
649
526
|
`);
|
|
650
527
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
651
|
-
(0,
|
|
652
|
-
(0,
|
|
528
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
529
|
+
(0, chai_config_spec_1.expect)(statements[0].text).to.equal(`'line 1\n'line 2\n'line 3`);
|
|
653
530
|
});
|
|
654
531
|
it('does not combile comments separated by newlines', () => {
|
|
655
532
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -660,11 +537,11 @@ describe('parser', () => {
|
|
|
660
537
|
'line 3
|
|
661
538
|
`);
|
|
662
539
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
663
|
-
(0,
|
|
664
|
-
(0,
|
|
665
|
-
(0,
|
|
666
|
-
(0,
|
|
667
|
-
(0,
|
|
540
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
541
|
+
(0, chai_config_spec_1.expect)(statements).to.be.lengthOf(3);
|
|
542
|
+
(0, chai_config_spec_1.expect)(statements[0].text).to.equal(`'line 1`);
|
|
543
|
+
(0, chai_config_spec_1.expect)(statements[1].text).to.equal(`'line 2`);
|
|
544
|
+
(0, chai_config_spec_1.expect)(statements[2].text).to.equal(`'line 3`);
|
|
668
545
|
});
|
|
669
546
|
it('works after print statement', () => {
|
|
670
547
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -673,8 +550,8 @@ describe('parser', () => {
|
|
|
673
550
|
end sub
|
|
674
551
|
`);
|
|
675
552
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
676
|
-
(0,
|
|
677
|
-
(0,
|
|
553
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
554
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 1`);
|
|
678
555
|
});
|
|
679
556
|
it('declaration-level', () => {
|
|
680
557
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -684,9 +561,9 @@ describe('parser', () => {
|
|
|
684
561
|
'comment 2
|
|
685
562
|
`);
|
|
686
563
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
687
|
-
(0,
|
|
688
|
-
(0,
|
|
689
|
-
(0,
|
|
564
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
565
|
+
(0, chai_config_spec_1.expect)(statements[0].text).to.equal(`'comment 1`);
|
|
566
|
+
(0, chai_config_spec_1.expect)(statements[2].text).to.equal(`'comment 2`);
|
|
690
567
|
});
|
|
691
568
|
it('works in aa literal as its own statement', () => {
|
|
692
569
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -696,7 +573,7 @@ describe('parser', () => {
|
|
|
696
573
|
}
|
|
697
574
|
`);
|
|
698
575
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
699
|
-
(0,
|
|
576
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
700
577
|
});
|
|
701
578
|
it('parses after function call', () => {
|
|
702
579
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -706,8 +583,8 @@ describe('parser', () => {
|
|
|
706
583
|
end sub
|
|
707
584
|
`);
|
|
708
585
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
709
|
-
(0,
|
|
710
|
-
(0,
|
|
586
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
587
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[2].text).to.equal(`'comment 1`);
|
|
711
588
|
});
|
|
712
589
|
it('function', () => {
|
|
713
590
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -718,11 +595,11 @@ describe('parser', () => {
|
|
|
718
595
|
end function 'comment 4
|
|
719
596
|
`);
|
|
720
597
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
721
|
-
(0,
|
|
722
|
-
(0,
|
|
723
|
-
(0,
|
|
724
|
-
(0,
|
|
725
|
-
(0,
|
|
598
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
599
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[0].text).to.equal(`'comment 1`);
|
|
600
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 2`);
|
|
601
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[3].text).to.equal(`'comment 3`);
|
|
602
|
+
(0, chai_config_spec_1.expect)(statements[1].text).to.equal(`'comment 4`);
|
|
726
603
|
});
|
|
727
604
|
it('if statement`', () => {
|
|
728
605
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -743,7 +620,7 @@ describe('parser', () => {
|
|
|
743
620
|
end function
|
|
744
621
|
`);
|
|
745
622
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
746
|
-
(0,
|
|
623
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
747
624
|
let fnSmt = statements[0];
|
|
748
625
|
if ((0, reflection_1.isFunctionStatement)(fnSmt)) {
|
|
749
626
|
let ifStmt = fnSmt.func.body.statements[0];
|
|
@@ -790,12 +667,12 @@ describe('parser', () => {
|
|
|
790
667
|
end function
|
|
791
668
|
`);
|
|
792
669
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
793
|
-
(0,
|
|
670
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
794
671
|
let stmt = statements[0].func.body.statements[0];
|
|
795
|
-
(0,
|
|
796
|
-
(0,
|
|
797
|
-
(0,
|
|
798
|
-
(0,
|
|
672
|
+
(0, chai_config_spec_1.expect)(stmt.body.statements[0].text).to.equal(`'comment 1`);
|
|
673
|
+
(0, chai_config_spec_1.expect)(stmt.body.statements[1].text).to.equal(`'comment 2`);
|
|
674
|
+
(0, chai_config_spec_1.expect)(stmt.body.statements[3].text).to.equal(`'comment 3`);
|
|
675
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
|
|
799
676
|
});
|
|
800
677
|
it('for', () => {
|
|
801
678
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -808,12 +685,12 @@ describe('parser', () => {
|
|
|
808
685
|
end function
|
|
809
686
|
`);
|
|
810
687
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
811
|
-
(0,
|
|
688
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
812
689
|
let stmt = statements[0].func.body.statements[0];
|
|
813
|
-
(0,
|
|
814
|
-
(0,
|
|
815
|
-
(0,
|
|
816
|
-
(0,
|
|
690
|
+
(0, chai_config_spec_1.expect)(stmt.body.statements[0].text).to.equal(`'comment 1`);
|
|
691
|
+
(0, chai_config_spec_1.expect)(stmt.body.statements[1].text).to.equal(`'comment 2`);
|
|
692
|
+
(0, chai_config_spec_1.expect)(stmt.body.statements[3].text).to.equal(`'comment 3`);
|
|
693
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
|
|
817
694
|
});
|
|
818
695
|
it('for each', () => {
|
|
819
696
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -826,12 +703,12 @@ describe('parser', () => {
|
|
|
826
703
|
end function
|
|
827
704
|
`);
|
|
828
705
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
829
|
-
(0,
|
|
706
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
830
707
|
let stmt = statements[0].func.body.statements[0];
|
|
831
|
-
(0,
|
|
832
|
-
(0,
|
|
833
|
-
(0,
|
|
834
|
-
(0,
|
|
708
|
+
(0, chai_config_spec_1.expect)(stmt.body.statements[0].text).to.equal(`'comment 1`);
|
|
709
|
+
(0, chai_config_spec_1.expect)(stmt.body.statements[1].text).to.equal(`'comment 2`);
|
|
710
|
+
(0, chai_config_spec_1.expect)(stmt.body.statements[3].text).to.equal(`'comment 3`);
|
|
711
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
|
|
835
712
|
});
|
|
836
713
|
});
|
|
837
714
|
});
|
|
@@ -843,7 +720,7 @@ describe('parser', () => {
|
|
|
843
720
|
then = true
|
|
844
721
|
end sub
|
|
845
722
|
`);
|
|
846
|
-
(0,
|
|
723
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1);
|
|
847
724
|
});
|
|
848
725
|
it('is allowed as an AA property name', () => {
|
|
849
726
|
var _a;
|
|
@@ -856,7 +733,7 @@ describe('parser', () => {
|
|
|
856
733
|
print person.then
|
|
857
734
|
end sub
|
|
858
735
|
`);
|
|
859
|
-
(0,
|
|
736
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
860
737
|
});
|
|
861
738
|
it('allows `mod` as an AA literal property', () => {
|
|
862
739
|
const parser = parse(`
|
|
@@ -888,7 +765,7 @@ describe('parser', () => {
|
|
|
888
765
|
}), {
|
|
889
766
|
walkMode: visitors_1.WalkMode.visitAllRecursive
|
|
890
767
|
});
|
|
891
|
-
(0,
|
|
768
|
+
(0, chai_config_spec_1.expect)(elements.map(x => x.tokens.key.kind)).to.eql([TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.Identifier]);
|
|
892
769
|
});
|
|
893
770
|
});
|
|
894
771
|
it('"end" is not allowed as a local identifier', () => {
|
|
@@ -897,7 +774,7 @@ describe('parser', () => {
|
|
|
897
774
|
end = true
|
|
898
775
|
end sub
|
|
899
776
|
`);
|
|
900
|
-
(0,
|
|
777
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.length.greaterThan(0);
|
|
901
778
|
});
|
|
902
779
|
it('none of them can be used as local variables', () => {
|
|
903
780
|
let reservedWords = new Set(TokenKind_1.ReservedWords);
|
|
@@ -910,7 +787,7 @@ describe('parser', () => {
|
|
|
910
787
|
end sub
|
|
911
788
|
`);
|
|
912
789
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
913
|
-
(0,
|
|
790
|
+
(0, chai_config_spec_1.expect)(diagnostics, `assigning to reserved word "${reservedWord}" should have been an error`).to.be.length.greaterThan(0);
|
|
914
791
|
}
|
|
915
792
|
});
|
|
916
793
|
});
|
|
@@ -920,24 +797,24 @@ describe('parser', () => {
|
|
|
920
797
|
let { statements, diagnostics } = parse(`
|
|
921
798
|
import "somePath"
|
|
922
799
|
`, Parser_1.ParseMode.BrighterScript);
|
|
923
|
-
(0,
|
|
924
|
-
(0,
|
|
800
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
801
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
925
802
|
});
|
|
926
803
|
it('catches import statements used in brightscript files', () => {
|
|
927
804
|
var _a;
|
|
928
805
|
let { statements, diagnostics } = parse(`
|
|
929
806
|
import "somePath"
|
|
930
807
|
`, Parser_1.ParseMode.BrightScript);
|
|
931
|
-
(0,
|
|
932
|
-
(0,
|
|
808
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.eql(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('import statements').message);
|
|
809
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
933
810
|
});
|
|
934
|
-
it('
|
|
811
|
+
it('catchs missing file path', () => {
|
|
935
812
|
var _a;
|
|
936
813
|
let { statements, diagnostics } = parse(`
|
|
937
814
|
import
|
|
938
815
|
`, Parser_1.ParseMode.BrighterScript);
|
|
939
|
-
(0,
|
|
940
|
-
(0,
|
|
816
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import').message);
|
|
817
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
941
818
|
});
|
|
942
819
|
});
|
|
943
820
|
describe('Annotations', () => {
|
|
@@ -948,7 +825,7 @@ describe('parser', () => {
|
|
|
948
825
|
sub main()
|
|
949
826
|
end sub
|
|
950
827
|
`, Parser_1.ParseMode.BrighterScript);
|
|
951
|
-
(0,
|
|
828
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('@').message);
|
|
952
829
|
});
|
|
953
830
|
it('properly handles empty annotation above class method', () => {
|
|
954
831
|
var _a;
|
|
@@ -960,7 +837,7 @@ describe('parser', () => {
|
|
|
960
837
|
end sub
|
|
961
838
|
end class
|
|
962
839
|
`, Parser_1.ParseMode.BrighterScript);
|
|
963
|
-
(0,
|
|
840
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier().message);
|
|
964
841
|
});
|
|
965
842
|
it('parses with error if annotation is not followed by a statement', () => {
|
|
966
843
|
var _a, _b, _c, _d;
|
|
@@ -974,11 +851,11 @@ describe('parser', () => {
|
|
|
974
851
|
end class
|
|
975
852
|
@meta1
|
|
976
853
|
`, Parser_1.ParseMode.BrighterScript);
|
|
977
|
-
(0,
|
|
978
|
-
(0,
|
|
979
|
-
(0,
|
|
980
|
-
(0,
|
|
981
|
-
(0,
|
|
854
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(4);
|
|
855
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
856
|
+
(0, chai_config_spec_1.expect)((_b = diagnostics[1]) === null || _b === void 0 ? void 0 : _b.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
857
|
+
(0, chai_config_spec_1.expect)((_c = diagnostics[2]) === null || _c === void 0 ? void 0 : _c.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
858
|
+
(0, chai_config_spec_1.expect)((_d = diagnostics[3]) === null || _d === void 0 ? void 0 : _d.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
982
859
|
});
|
|
983
860
|
it('attaches an annotation to next statement', () => {
|
|
984
861
|
var _a;
|
|
@@ -990,18 +867,18 @@ describe('parser', () => {
|
|
|
990
867
|
@meta2 sub init()
|
|
991
868
|
end sub
|
|
992
869
|
`, Parser_1.ParseMode.BrighterScript);
|
|
993
|
-
(0,
|
|
994
|
-
(0,
|
|
870
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
871
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
995
872
|
let fn = statements[0];
|
|
996
|
-
(0,
|
|
997
|
-
(0,
|
|
998
|
-
(0,
|
|
999
|
-
(0,
|
|
1000
|
-
(0,
|
|
873
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
874
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
875
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
|
|
876
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].name).to.equal('meta1');
|
|
877
|
+
(0, chai_config_spec_1.expect)(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1001
878
|
fn = statements[1];
|
|
1002
|
-
(0,
|
|
1003
|
-
(0,
|
|
1004
|
-
(0,
|
|
879
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
880
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
881
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta2');
|
|
1005
882
|
});
|
|
1006
883
|
it('attaches annotations inside a function body', () => {
|
|
1007
884
|
var _a, _b;
|
|
@@ -1011,13 +888,13 @@ describe('parser', () => {
|
|
|
1011
888
|
print "hello"
|
|
1012
889
|
end function
|
|
1013
890
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1014
|
-
(0,
|
|
891
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1015
892
|
let fn = statements[0];
|
|
1016
893
|
let fnStatements = fn.func.body.statements;
|
|
1017
894
|
let stat = fnStatements[0];
|
|
1018
|
-
(0,
|
|
1019
|
-
(0,
|
|
1020
|
-
(0,
|
|
895
|
+
(0, chai_config_spec_1.expect)(stat).to.exist;
|
|
896
|
+
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
897
|
+
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1021
898
|
});
|
|
1022
899
|
it('attaches multiple annotations to next statement', () => {
|
|
1023
900
|
var _a;
|
|
@@ -1027,14 +904,14 @@ describe('parser', () => {
|
|
|
1027
904
|
function main()
|
|
1028
905
|
end function
|
|
1029
906
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1030
|
-
(0,
|
|
1031
|
-
(0,
|
|
907
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
908
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1032
909
|
let fn = statements[0];
|
|
1033
|
-
(0,
|
|
1034
|
-
(0,
|
|
1035
|
-
(0,
|
|
1036
|
-
(0,
|
|
1037
|
-
(0,
|
|
910
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
911
|
+
(0, chai_config_spec_1.expect)(fn.annotations.length).to.equal(3);
|
|
912
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
913
|
+
(0, chai_config_spec_1.expect)(fn.annotations[1]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
914
|
+
(0, chai_config_spec_1.expect)(fn.annotations[2]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1038
915
|
});
|
|
1039
916
|
it('allows annotations with parameters', () => {
|
|
1040
917
|
var _a;
|
|
@@ -1043,12 +920,12 @@ describe('parser', () => {
|
|
|
1043
920
|
function main()
|
|
1044
921
|
end function
|
|
1045
922
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1046
|
-
(0,
|
|
923
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1047
924
|
let fn = statements[0];
|
|
1048
|
-
(0,
|
|
1049
|
-
(0,
|
|
1050
|
-
(0,
|
|
1051
|
-
(0,
|
|
925
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
926
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
927
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
|
|
928
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].call).to.be.instanceof(Expression_1.CallExpression);
|
|
1052
929
|
});
|
|
1053
930
|
it('attaches annotations to a class', () => {
|
|
1054
931
|
var _a, _b;
|
|
@@ -1060,10 +937,10 @@ describe('parser', () => {
|
|
|
1060
937
|
end function
|
|
1061
938
|
end class
|
|
1062
939
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1063
|
-
(0,
|
|
940
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1064
941
|
let cs = statements[0];
|
|
1065
|
-
(0,
|
|
1066
|
-
(0,
|
|
942
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
943
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1067
944
|
});
|
|
1068
945
|
it('attaches annotations to multiple clases', () => {
|
|
1069
946
|
var _a, _b, _c;
|
|
@@ -1081,15 +958,15 @@ describe('parser', () => {
|
|
|
1081
958
|
end function
|
|
1082
959
|
end class
|
|
1083
960
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1084
|
-
(0,
|
|
961
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1085
962
|
let cs = statements[0];
|
|
1086
|
-
(0,
|
|
1087
|
-
(0,
|
|
1088
|
-
(0,
|
|
963
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
964
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
965
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
|
|
1089
966
|
let cs2 = statements[1];
|
|
1090
|
-
(0,
|
|
1091
|
-
(0,
|
|
1092
|
-
(0,
|
|
967
|
+
(0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
|
|
968
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
969
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
|
|
1093
970
|
});
|
|
1094
971
|
it('attaches annotations to a namespaced class', () => {
|
|
1095
972
|
var _a, _b;
|
|
@@ -1103,11 +980,11 @@ describe('parser', () => {
|
|
|
1103
980
|
end class
|
|
1104
981
|
end namespace
|
|
1105
982
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1106
|
-
(0,
|
|
983
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1107
984
|
let ns = statements[0];
|
|
1108
985
|
let cs = ns.body.statements[0];
|
|
1109
|
-
(0,
|
|
1110
|
-
(0,
|
|
986
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
987
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1111
988
|
});
|
|
1112
989
|
it('attaches annotations to a namespaced class - multiple', () => {
|
|
1113
990
|
var _a, _b, _c;
|
|
@@ -1127,16 +1004,16 @@ describe('parser', () => {
|
|
|
1127
1004
|
end class
|
|
1128
1005
|
end namespace
|
|
1129
1006
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1130
|
-
(0,
|
|
1007
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1131
1008
|
let ns = statements[0];
|
|
1132
1009
|
let cs = ns.body.statements[0];
|
|
1133
|
-
(0,
|
|
1134
|
-
(0,
|
|
1135
|
-
(0,
|
|
1010
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1011
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1012
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
|
|
1136
1013
|
let cs2 = ns.body.statements[1];
|
|
1137
|
-
(0,
|
|
1138
|
-
(0,
|
|
1139
|
-
(0,
|
|
1014
|
+
(0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
|
|
1015
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1016
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
|
|
1140
1017
|
});
|
|
1141
1018
|
it('attaches annotations to a class constructor', () => {
|
|
1142
1019
|
var _a, _b;
|
|
@@ -1151,11 +1028,11 @@ describe('parser', () => {
|
|
|
1151
1028
|
end function
|
|
1152
1029
|
end class
|
|
1153
1030
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1154
|
-
(0,
|
|
1031
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1155
1032
|
let cs = statements[0];
|
|
1156
1033
|
let stat = cs.body[0];
|
|
1157
|
-
(0,
|
|
1158
|
-
(0,
|
|
1034
|
+
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1035
|
+
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1159
1036
|
});
|
|
1160
1037
|
it('attaches annotations to a class methods', () => {
|
|
1161
1038
|
var _a, _b;
|
|
@@ -1170,11 +1047,11 @@ describe('parser', () => {
|
|
|
1170
1047
|
end function
|
|
1171
1048
|
end class
|
|
1172
1049
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1173
|
-
(0,
|
|
1050
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1174
1051
|
let cs = statements[0];
|
|
1175
1052
|
let stat = cs.body[1];
|
|
1176
|
-
(0,
|
|
1177
|
-
(0,
|
|
1053
|
+
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1054
|
+
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1178
1055
|
});
|
|
1179
1056
|
it('attaches annotations to a class methods, fields and constructor', () => {
|
|
1180
1057
|
var _a, _b, _c, _d, _e;
|
|
@@ -1198,19 +1075,19 @@ describe('parser', () => {
|
|
|
1198
1075
|
public foo="bar"
|
|
1199
1076
|
end class
|
|
1200
1077
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1201
|
-
(0,
|
|
1078
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1202
1079
|
let cs = statements[0];
|
|
1203
|
-
(0,
|
|
1204
|
-
(0,
|
|
1080
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(2);
|
|
1081
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1205
1082
|
let stat1 = cs.body[0];
|
|
1206
1083
|
let stat2 = cs.body[1];
|
|
1207
1084
|
let f1 = cs.body[2];
|
|
1208
|
-
(0,
|
|
1209
|
-
(0,
|
|
1210
|
-
(0,
|
|
1211
|
-
(0,
|
|
1212
|
-
(0,
|
|
1213
|
-
(0,
|
|
1085
|
+
(0, chai_config_spec_1.expect)((_c = stat1.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
|
|
1086
|
+
(0, chai_config_spec_1.expect)(stat1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1087
|
+
(0, chai_config_spec_1.expect)((_d = stat2.annotations) === null || _d === void 0 ? void 0 : _d.length).to.equal(2);
|
|
1088
|
+
(0, chai_config_spec_1.expect)(stat2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1089
|
+
(0, chai_config_spec_1.expect)((_e = f1.annotations) === null || _e === void 0 ? void 0 : _e.length).to.equal(2);
|
|
1090
|
+
(0, chai_config_spec_1.expect)(f1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1214
1091
|
});
|
|
1215
1092
|
it('ignores annotations on commented out lines', () => {
|
|
1216
1093
|
var _a;
|
|
@@ -1221,9 +1098,9 @@ describe('parser', () => {
|
|
|
1221
1098
|
print "hello"
|
|
1222
1099
|
end function
|
|
1223
1100
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1224
|
-
(0,
|
|
1101
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1225
1102
|
let cs = statements[0];
|
|
1226
|
-
(0,
|
|
1103
|
+
(0, chai_config_spec_1.expect)(cs.annotations).to.be.undefined;
|
|
1227
1104
|
});
|
|
1228
1105
|
it('can convert argument of an annotation to JS types', () => {
|
|
1229
1106
|
var _a;
|
|
@@ -1241,22 +1118,22 @@ describe('parser', () => {
|
|
|
1241
1118
|
sub init()
|
|
1242
1119
|
end sub
|
|
1243
1120
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1244
|
-
(0,
|
|
1245
|
-
(0,
|
|
1121
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1122
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1246
1123
|
let fn = statements[0];
|
|
1247
|
-
(0,
|
|
1248
|
-
(0,
|
|
1249
|
-
(0,
|
|
1124
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1125
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([]);
|
|
1126
|
+
(0, chai_config_spec_1.expect)(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1250
1127
|
fn = statements[1];
|
|
1251
|
-
(0,
|
|
1252
|
-
(0,
|
|
1253
|
-
(0,
|
|
1128
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1129
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1130
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([
|
|
1254
1131
|
'arg', 2, true,
|
|
1255
1132
|
{ prop: 'value' }, [1, 2],
|
|
1256
1133
|
null
|
|
1257
1134
|
]);
|
|
1258
1135
|
let allArgs = fn.annotations[0].getArguments(false);
|
|
1259
|
-
(0,
|
|
1136
|
+
(0, chai_config_spec_1.expect)(allArgs.pop()).to.be.instanceOf(Expression_1.FunctionExpression);
|
|
1260
1137
|
});
|
|
1261
1138
|
it('can handle negative numbers', () => {
|
|
1262
1139
|
var _a;
|
|
@@ -1268,459 +1145,594 @@ describe('parser', () => {
|
|
|
1268
1145
|
sub init()
|
|
1269
1146
|
end sub
|
|
1270
1147
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1271
|
-
(0,
|
|
1272
|
-
(0,
|
|
1148
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1149
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1273
1150
|
let fn = statements[0];
|
|
1274
|
-
(0,
|
|
1275
|
-
(0,
|
|
1151
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1152
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([-100]);
|
|
1276
1153
|
});
|
|
1277
1154
|
});
|
|
1278
|
-
describe('
|
|
1279
|
-
it('
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
end sub
|
|
1155
|
+
describe('type casts', () => {
|
|
1156
|
+
it('is not allowed in brightscript mode', () => {
|
|
1157
|
+
var _a;
|
|
1158
|
+
let parser = parse(`
|
|
1159
|
+
sub main(node as dynamic)
|
|
1160
|
+
print lcase((node as string))
|
|
1285
1161
|
end sub
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
const type = (0, Parser_1.getBscTypeFromExpression)(func.body.statements[0].value, func);
|
|
1289
|
-
(0, chai_1.expect)(type.returnType).to.be.instanceof(VoidType_1.VoidType);
|
|
1162
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1163
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('type cast').message);
|
|
1290
1164
|
});
|
|
1291
|
-
it('
|
|
1292
|
-
|
|
1165
|
+
it('allows type casts after function calls', () => {
|
|
1166
|
+
var _a;
|
|
1167
|
+
let { statements, diagnostics } = parse(`
|
|
1293
1168
|
sub main()
|
|
1294
|
-
|
|
1295
|
-
return "hello"
|
|
1296
|
-
end sub
|
|
1169
|
+
value = getValue() as integer
|
|
1297
1170
|
end sub
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1171
|
+
|
|
1172
|
+
function getValue()
|
|
1173
|
+
return 123
|
|
1174
|
+
end function
|
|
1175
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1176
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1177
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1178
|
+
let fn = statements[0];
|
|
1179
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1180
|
+
let assignment = fn.func.body.statements[0];
|
|
1181
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
|
|
1182
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeCastExpression)(assignment.value)).to.be.true;
|
|
1183
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value.obj)).to.be.true;
|
|
1184
|
+
(0, testHelpers_spec_1.expectTypeToBe)(assignment.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime }), IntegerType_1.IntegerType);
|
|
1185
|
+
});
|
|
1186
|
+
it('allows type casts in the middle of expressions', () => {
|
|
1187
|
+
var _a;
|
|
1188
|
+
let { statements, diagnostics } = parse(`
|
|
1305
1189
|
sub main()
|
|
1306
|
-
|
|
1307
|
-
return new Person()
|
|
1308
|
-
end sub
|
|
1190
|
+
value = (getValue() as integer).toStr()
|
|
1309
1191
|
end sub
|
|
1310
1192
|
|
|
1311
|
-
|
|
1312
|
-
|
|
1193
|
+
function getValue()
|
|
1194
|
+
return 123
|
|
1195
|
+
end function
|
|
1313
1196
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1314
|
-
(0,
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1197
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1198
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1199
|
+
let fn = statements[0];
|
|
1200
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1201
|
+
let assignment = fn.func.body.statements[0];
|
|
1202
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
|
|
1203
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value)).to.be.true;
|
|
1204
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)(assignment.value.callee)).to.be.true;
|
|
1205
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(assignment.value.callee.obj)).to.be.true;
|
|
1206
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeCastExpression)(assignment.value.callee.obj.expression)).to.be.true;
|
|
1207
|
+
//grouping expression is an integer
|
|
1208
|
+
(0, testHelpers_spec_1.expectTypeToBe)(assignment.value.callee.obj.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime }), IntegerType_1.IntegerType);
|
|
1209
|
+
});
|
|
1210
|
+
it('allows type casts in a function call', () => {
|
|
1211
|
+
var _a;
|
|
1212
|
+
let { statements, diagnostics } = parse(`
|
|
1322
1213
|
sub main()
|
|
1323
|
-
|
|
1324
|
-
return [1,2,3]
|
|
1325
|
-
end sub
|
|
1214
|
+
print cos(getAngle() as float)
|
|
1326
1215
|
end sub
|
|
1216
|
+
|
|
1217
|
+
function getAngle()
|
|
1218
|
+
return 123
|
|
1219
|
+
end function
|
|
1327
1220
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1328
|
-
(0,
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
(0,
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1221
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1222
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1223
|
+
let fn = statements[0];
|
|
1224
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1225
|
+
let print = fn.func.body.statements[0];
|
|
1226
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
|
|
1227
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(print.expressions[0])).to.be.true;
|
|
1228
|
+
let fnCall = print.expressions[0];
|
|
1229
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeCastExpression)(fnCall.args[0])).to.be.true;
|
|
1230
|
+
let arg = fnCall.args[0];
|
|
1231
|
+
//argument type is float
|
|
1232
|
+
(0, testHelpers_spec_1.expectTypeToBe)(arg.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime }), FloatType_1.FloatType);
|
|
1233
|
+
});
|
|
1234
|
+
it('allows multiple type casts', () => {
|
|
1235
|
+
var _a;
|
|
1236
|
+
let { statements, diagnostics } = parse(`
|
|
1338
1237
|
sub main()
|
|
1339
|
-
|
|
1340
|
-
someString = "hello world"
|
|
1341
|
-
someObj = {foo: "bar"}
|
|
1342
|
-
someCustom = new CustomKlass()
|
|
1238
|
+
print getData() as dynamic as float as string
|
|
1343
1239
|
end sub
|
|
1344
|
-
|
|
1345
|
-
class CustomKlass
|
|
1346
|
-
end class
|
|
1347
1240
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1348
|
-
(0,
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
(0,
|
|
1352
|
-
|
|
1353
|
-
(0,
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1241
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1242
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1243
|
+
let fn = statements[0];
|
|
1244
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1245
|
+
let print = fn.func.body.statements[0];
|
|
1246
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
|
|
1247
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeCastExpression)(print.expressions[0])).to.be.true;
|
|
1248
|
+
//argument type is float
|
|
1249
|
+
(0, testHelpers_spec_1.expectTypeToBe)(print.expressions[0].getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime }), StringType_1.StringType);
|
|
1250
|
+
});
|
|
1251
|
+
it('flags invalid type cast syntax - multiple as', () => {
|
|
1252
|
+
var _a;
|
|
1253
|
+
let { diagnostics } = parse(`
|
|
1254
|
+
sub foo(key)
|
|
1255
|
+
getData(key as as string)
|
|
1359
1256
|
end sub
|
|
1360
1257
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1361
|
-
(0,
|
|
1362
|
-
const someFuncSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1363
|
-
(0, chai_1.expect)(someFuncSymbolTable.getSymbolType('param1')).to.be.instanceof(StringType_1.StringType);
|
|
1364
|
-
(0, chai_1.expect)(someFuncSymbolTable.getSymbolType('param2')).to.be.instanceof(IntegerType_1.IntegerType);
|
|
1365
|
-
(0, chai_1.expect)(someFuncSymbolTable.getSymbolType('temp')).to.be.instanceof(IntegerType_1.IntegerType);
|
|
1258
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1366
1259
|
});
|
|
1367
|
-
it('
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1260
|
+
it('flags invalid type cast syntax - no type after as', () => {
|
|
1261
|
+
var _a;
|
|
1262
|
+
let { diagnostics } = parse(`
|
|
1263
|
+
sub foo(key)
|
|
1264
|
+
getData(key as)
|
|
1371
1265
|
end sub
|
|
1372
|
-
|
|
1373
|
-
function foo() as string
|
|
1374
|
-
return "foo"
|
|
1375
|
-
end function
|
|
1376
1266
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1377
|
-
(0,
|
|
1378
|
-
const someFuncSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1379
|
-
(0, chai_1.expect)((0, reflection_1.isLazyType)(someFuncSymbolTable.getSymbol('temp')[0].type)).to.be.true;
|
|
1380
|
-
(0, chai_1.expect)(someFuncSymbolTable.getSymbolType('temp').toTypeString()).to.eq('string');
|
|
1267
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1381
1268
|
});
|
|
1382
|
-
it('
|
|
1383
|
-
|
|
1384
|
-
sub
|
|
1385
|
-
|
|
1386
|
-
addOne = sub()
|
|
1387
|
-
oldVal = count
|
|
1388
|
-
end sub
|
|
1269
|
+
it('allows declaring types on assignment in Brighterscript mode', () => {
|
|
1270
|
+
let { diagnostics } = parse(`
|
|
1271
|
+
sub foo()
|
|
1272
|
+
x as string = formatJson("some string")
|
|
1389
1273
|
end sub
|
|
1390
1274
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1391
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(
|
|
1392
|
-
const addOneSymbolTable = parser.references.functionExpressions[0].childFunctionExpressions[0].symbolTable;
|
|
1393
|
-
(0, chai_1.expect)((0, reflection_1.isUninitializedType)(addOneSymbolTable.getSymbolType('oldVal'))).to.be.true;
|
|
1275
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1394
1276
|
});
|
|
1395
|
-
it('
|
|
1396
|
-
|
|
1397
|
-
|
|
1277
|
+
it('does not allow declaring types on assignment in brightscript mode', () => {
|
|
1278
|
+
var _a, _b;
|
|
1279
|
+
let { diagnostics } = parse(`
|
|
1280
|
+
sub foo()
|
|
1281
|
+
x as string = formatJson("some string")
|
|
1398
1282
|
end sub
|
|
1399
|
-
`, Parser_1.ParseMode.
|
|
1400
|
-
(0,
|
|
1401
|
-
(0,
|
|
1402
|
-
['p1', new DynamicType_1.DynamicType(), util_1.util.createRange(1, 26, 1, 28)],
|
|
1403
|
-
['p2', new StringType_1.StringType(), util_1.util.createRange(1, 30, 1, 32)],
|
|
1404
|
-
['p3', new IntegerType_1.IntegerType(), util_1.util.createRange(1, 44, 1, 46)]
|
|
1405
|
-
]);
|
|
1283
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1284
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1285
|
+
(0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.message).to.include('typed assignment');
|
|
1406
1286
|
});
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
const symbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1414
|
-
const numArraySymbolType = symbolTable.getSymbolType('numbers');
|
|
1415
|
-
const wordArraySymbolType = symbolTable.getSymbolType('words');
|
|
1416
|
-
(0, chai_1.expect)((0, reflection_1.isArrayType)(numArraySymbolType)).to.be.true;
|
|
1417
|
-
(0, chai_1.expect)((0, reflection_1.isIntegerType)(numArraySymbolType.getDefaultType())).to.be.true;
|
|
1418
|
-
(0, chai_1.expect)((0, reflection_1.isArrayType)(wordArraySymbolType)).to.be.true;
|
|
1419
|
-
(0, chai_1.expect)((0, reflection_1.isStringType)(wordArraySymbolType.getDefaultType())).to.be.true;
|
|
1420
|
-
const funcReturnType = parser.references.functionExpressions[0].getReturnType();
|
|
1421
|
-
(0, chai_1.expect)((0, reflection_1.isArrayType)(funcReturnType)).to.be.true;
|
|
1422
|
-
(0, chai_1.expect)((0, reflection_1.isFloatType)(funcReturnType.getDefaultType())).to.be.true;
|
|
1423
|
-
});
|
|
1424
|
-
it('finds multidimensional arrays', () => {
|
|
1425
|
-
const parser = parse(`
|
|
1426
|
-
sub alert(data as integer[][])
|
|
1287
|
+
});
|
|
1288
|
+
describe('union types', () => {
|
|
1289
|
+
it('is not allowed in brightscript mode', () => {
|
|
1290
|
+
let parser = parse(`
|
|
1291
|
+
sub main(param as string or integer)
|
|
1292
|
+
print param
|
|
1427
1293
|
end sub
|
|
1428
|
-
`, Parser_1.ParseMode.
|
|
1429
|
-
(0, testHelpers_spec_1.
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
});
|
|
1436
|
-
it('finds arrays of custom types', () => {
|
|
1437
|
-
const parser = parse(`
|
|
1438
|
-
sub alert(data as SomeKlass[])
|
|
1294
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1295
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression()]);
|
|
1296
|
+
});
|
|
1297
|
+
it('allows union types in parameters', () => {
|
|
1298
|
+
let { diagnostics } = parse(`
|
|
1299
|
+
sub main(param as string or integer)
|
|
1300
|
+
print param
|
|
1439
1301
|
end sub
|
|
1440
1302
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1441
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
describe('loops', () => {
|
|
1448
|
-
it('stores the loop variable in a for loop', () => {
|
|
1449
|
-
const parser = parse(`
|
|
1450
|
-
sub main()
|
|
1451
|
-
for i = 0 to 10 step 10
|
|
1452
|
-
print i
|
|
1453
|
-
end for
|
|
1454
|
-
end sub
|
|
1455
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1456
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
|
|
1457
|
-
const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1458
|
-
(0, chai_1.expect)((0, reflection_1.isIntegerType)(currentSymbolTable.getSymbolType('i'))).to.be.true;
|
|
1459
|
-
});
|
|
1460
|
-
it('stores the loop variable in a for each loop', () => {
|
|
1461
|
-
const parser = parse(`
|
|
1462
|
-
sub doLoop(someData)
|
|
1463
|
-
for each datum in someData
|
|
1464
|
-
print datum
|
|
1465
|
-
end for
|
|
1303
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1304
|
+
});
|
|
1305
|
+
it('allows union types in type casts', () => {
|
|
1306
|
+
let { diagnostics } = parse(`
|
|
1307
|
+
sub main(val)
|
|
1308
|
+
printThing(val as string or integer)
|
|
1466
1309
|
end sub
|
|
1467
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1468
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
|
|
1469
|
-
const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1470
|
-
(0, chai_1.expect)((0, reflection_1.isDynamicType)(currentSymbolTable.getSymbolType('datum'))).to.be.true;
|
|
1471
|
-
});
|
|
1472
|
-
it('determines the type of the variable in a for each if the target is an array literal', () => {
|
|
1473
|
-
const parser = parse(`
|
|
1474
|
-
sub doLoop()
|
|
1475
|
-
someData = [1,2,3]
|
|
1476
|
-
for each datum in someData
|
|
1477
|
-
print datum
|
|
1478
|
-
end for
|
|
1479
|
-
end sub
|
|
1480
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1481
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
|
|
1482
|
-
const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1483
|
-
(0, chai_1.expect)((0, reflection_1.isIntegerType)(currentSymbolTable.getSymbolType('datum'))).to.be.true;
|
|
1484
|
-
});
|
|
1485
|
-
it('determines the type of the variable in a for each if the target is an array', () => {
|
|
1486
|
-
const parser = parse(`
|
|
1487
|
-
sub doLoop(someData as integer[])
|
|
1488
|
-
for each datum in someData
|
|
1489
|
-
print datum
|
|
1490
|
-
end for
|
|
1491
|
-
end sub
|
|
1492
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1493
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
|
|
1494
|
-
const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1495
|
-
(0, chai_1.expect)((0, reflection_1.isIntegerType)(currentSymbolTable.getSymbolType('datum'))).to.be.true;
|
|
1496
|
-
});
|
|
1497
|
-
it('determines the type of the variable in a for each if the target is an array of some custom type', () => {
|
|
1498
|
-
const parser = parse(`
|
|
1499
|
-
sub doLoop(someData as MyKlass[])
|
|
1500
|
-
for each datum in someData
|
|
1501
|
-
print datum.name
|
|
1502
|
-
end for
|
|
1503
|
-
end sub
|
|
1504
1310
|
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1511
|
-
(0, chai_1.expect)((0, reflection_1.isLazyType)(currentSymbolTable.getSymbol('datum')[0].type)).to.be.true;
|
|
1512
|
-
});
|
|
1513
|
-
it('determines the type of the variable in a for each if the target is a multidimensional array', () => {
|
|
1514
|
-
const parser = parse(`
|
|
1515
|
-
sub doLoop(data as float[][])
|
|
1516
|
-
for each row in data
|
|
1517
|
-
for each item in row
|
|
1518
|
-
print item
|
|
1519
|
-
end for
|
|
1520
|
-
end for
|
|
1521
|
-
end sub
|
|
1522
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1523
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
|
|
1524
|
-
const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1525
|
-
(0, chai_1.expect)((0, reflection_1.isArrayType)(currentSymbolTable.getSymbol('row')[0].type)).to.be.true;
|
|
1526
|
-
(0, chai_1.expect)((0, reflection_1.isFloatType)(currentSymbolTable.getSymbol('item')[0].type)).to.be.true;
|
|
1527
|
-
});
|
|
1311
|
+
sub printThing(thing as string or integer)
|
|
1312
|
+
print thing
|
|
1313
|
+
end sub
|
|
1314
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1315
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1528
1316
|
});
|
|
1529
1317
|
});
|
|
1530
|
-
describe('
|
|
1531
|
-
it('
|
|
1532
|
-
|
|
1533
|
-
sub
|
|
1534
|
-
print
|
|
1535
|
-
end sub
|
|
1536
|
-
`);
|
|
1537
|
-
const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 42));
|
|
1538
|
-
const tokenChain = parser.getTokenChain(childFieldToken).chain;
|
|
1539
|
-
const tokenChainTokens = tokenChain.map(tcm => tcm.token);
|
|
1540
|
-
(0, chai_1.expect)(tokenChain.length).to.equal(3);
|
|
1541
|
-
(0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'childField']);
|
|
1542
|
-
(0, chai_1.expect)(tokenChain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct]);
|
|
1543
|
-
});
|
|
1544
|
-
it('can find a chain of tokens with function call with no args in the middle', () => {
|
|
1545
|
-
const parser = parse(`
|
|
1546
|
-
sub someFunc(var)
|
|
1547
|
-
print var.field.funcCall().childField
|
|
1548
|
-
end sub
|
|
1549
|
-
`);
|
|
1550
|
-
const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 49));
|
|
1551
|
-
const tokenChain = parser.getTokenChain(childFieldToken).chain;
|
|
1552
|
-
const tokenChainTokens = tokenChain.map(tcm => tcm.token);
|
|
1553
|
-
(0, chai_1.expect)(tokenChain.length).to.equal(4);
|
|
1554
|
-
(0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'funcCall', 'childField']);
|
|
1555
|
-
(0, chai_1.expect)(tokenChain[2].usage).to.eql(Parser_1.TokenUsage.Call);
|
|
1556
|
-
});
|
|
1557
|
-
it('can find a chain of tokens with function call with multiple args in the middle', () => {
|
|
1558
|
-
const parser = parse(`
|
|
1559
|
-
sub someFunc(var)
|
|
1560
|
-
print var.field.funcCall(1, "string", {key: value}).childField
|
|
1561
|
-
end sub
|
|
1562
|
-
`);
|
|
1563
|
-
const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 75));
|
|
1564
|
-
const tokenChain = parser.getTokenChain(childFieldToken).chain;
|
|
1565
|
-
const tokenChainTokens = tokenChain.map(tcm => tcm.token);
|
|
1566
|
-
(0, chai_1.expect)(tokenChain.length).to.equal(4);
|
|
1567
|
-
(0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'funcCall', 'childField']);
|
|
1568
|
-
(0, chai_1.expect)(tokenChain[2].usage).to.eql(Parser_1.TokenUsage.Call);
|
|
1569
|
-
});
|
|
1570
|
-
it('can find a chain of tokens with function call with function call inside', () => {
|
|
1571
|
-
const parser = parse(`
|
|
1572
|
-
sub someFunc(var)
|
|
1573
|
-
print var.field.funcCall(a(), b(), otherFunc2(c(), {d: func3(e)})).childField
|
|
1574
|
-
end sub
|
|
1575
|
-
`);
|
|
1576
|
-
const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 90));
|
|
1577
|
-
const tokenChain = parser.getTokenChain(childFieldToken).chain;
|
|
1578
|
-
const tokenChainTokens = tokenChain.map(tcm => tcm.token);
|
|
1579
|
-
(0, chai_1.expect)(tokenChain.length).to.equal(4);
|
|
1580
|
-
(0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'funcCall', 'childField']);
|
|
1581
|
-
(0, chai_1.expect)(tokenChain[2].usage).to.eql(Parser_1.TokenUsage.Call);
|
|
1582
|
-
});
|
|
1583
|
-
it('can find a chain of tokens with array references inside', () => {
|
|
1584
|
-
const parser = parse(`
|
|
1585
|
-
sub someFunc(var)
|
|
1586
|
-
print var.field.myArray[0].childField
|
|
1587
|
-
end sub
|
|
1588
|
-
`);
|
|
1589
|
-
const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 50));
|
|
1590
|
-
const tokenChain = parser.getTokenChain(childFieldToken).chain;
|
|
1591
|
-
const tokenChainTokens = tokenChain.map(tcm => tcm.token);
|
|
1592
|
-
(0, chai_1.expect)(tokenChain.length).to.equal(4);
|
|
1593
|
-
(0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'myArray', 'childField']);
|
|
1594
|
-
(0, chai_1.expect)(tokenChain[2].usage).to.eql(Parser_1.TokenUsage.ArrayReference);
|
|
1595
|
-
});
|
|
1596
|
-
it('includes unknown when an expression in brackets is part of the chain', () => {
|
|
1597
|
-
const parser = parse(`
|
|
1598
|
-
sub someFunc()
|
|
1599
|
-
print (1 + 1).toStr()
|
|
1318
|
+
describe('typed arrays', () => {
|
|
1319
|
+
it('is not allowed in brightscript mode', () => {
|
|
1320
|
+
let parser = parse(`
|
|
1321
|
+
sub main(things as string[])
|
|
1322
|
+
print things
|
|
1600
1323
|
end sub
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
const tokenChainResponse = parser.getTokenChain(toStrToken);
|
|
1604
|
-
(0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.true;
|
|
1324
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1325
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typed arrays')]);
|
|
1605
1326
|
});
|
|
1606
|
-
it('
|
|
1607
|
-
|
|
1608
|
-
sub
|
|
1609
|
-
print
|
|
1327
|
+
it('is allowed in brighterscript mode', () => {
|
|
1328
|
+
let { statements, diagnostics } = parse(`
|
|
1329
|
+
sub main(things as string[])
|
|
1330
|
+
print things
|
|
1610
1331
|
end sub
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
const
|
|
1614
|
-
(0,
|
|
1332
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1333
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1334
|
+
const paramType = statements[0].func.parameters[0].getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1335
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1336
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, StringType_1.StringType);
|
|
1615
1337
|
});
|
|
1616
|
-
it('
|
|
1617
|
-
|
|
1618
|
-
sub
|
|
1619
|
-
print
|
|
1338
|
+
it('allows multi dimensional arrays', () => {
|
|
1339
|
+
let { statements, diagnostics } = parse(`
|
|
1340
|
+
sub main(things as string[][])
|
|
1341
|
+
print things
|
|
1620
1342
|
end sub
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
const
|
|
1624
|
-
(0,
|
|
1343
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1344
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1345
|
+
const paramType = statements[0].func.parameters[0].getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1346
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1347
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, types_1.ArrayType);
|
|
1348
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType.defaultType, StringType_1.StringType);
|
|
1625
1349
|
});
|
|
1626
|
-
it('
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1350
|
+
it('allows arrays as return types', () => {
|
|
1351
|
+
let { statements, diagnostics } = parse(`
|
|
1352
|
+
function getFourPrimes() as integer[]
|
|
1353
|
+
return [2, 3, 5, 7]
|
|
1354
|
+
end function
|
|
1355
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1356
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1357
|
+
const paramType = statements[0].func.returnTypeExpression.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1358
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1359
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, IntegerType_1.IntegerType);
|
|
1360
|
+
});
|
|
1361
|
+
it('allows arrays in union types', () => {
|
|
1362
|
+
let { statements, diagnostics } = parse(`
|
|
1363
|
+
sub foo(x as integer or integer[] or string or string[])
|
|
1364
|
+
print x
|
|
1633
1365
|
end sub
|
|
1366
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1367
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1368
|
+
const paramType = statements[0].func.parameters[0].getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1369
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.UnionType);
|
|
1370
|
+
(0, chai_config_spec_1.expect)(paramType.toString().includes('Array<string>')).to.be.true;
|
|
1371
|
+
(0, chai_config_spec_1.expect)(paramType.toString().includes('Array<integer>')).to.be.true;
|
|
1372
|
+
});
|
|
1373
|
+
});
|
|
1374
|
+
describe('interfaces', () => {
|
|
1375
|
+
it('allows fields and methods', () => {
|
|
1376
|
+
let { statements, diagnostics } = parse(`
|
|
1377
|
+
interface SomeIFace
|
|
1378
|
+
name as string
|
|
1379
|
+
height as integer
|
|
1380
|
+
function getValue(thing as float) as object
|
|
1381
|
+
function getMe() as SomeIFace
|
|
1382
|
+
sub noop()
|
|
1383
|
+
end interface
|
|
1384
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1385
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1386
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1387
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1388
|
+
});
|
|
1389
|
+
it('allows untyped fields', () => {
|
|
1390
|
+
let { statements, diagnostics } = parse(`
|
|
1391
|
+
interface HasUntyped
|
|
1392
|
+
name
|
|
1393
|
+
end interface
|
|
1394
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1395
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1396
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1397
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1398
|
+
});
|
|
1399
|
+
it('allows optional fields', () => {
|
|
1400
|
+
let { statements, diagnostics } = parse(`
|
|
1401
|
+
interface HasOptional
|
|
1402
|
+
optional name as string
|
|
1403
|
+
optional height
|
|
1404
|
+
end interface
|
|
1405
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1406
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1407
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1408
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1409
|
+
const iface = statements[0];
|
|
1410
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1411
|
+
const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1412
|
+
// eslint-disable-next-line no-bitwise
|
|
1413
|
+
ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
|
|
1414
|
+
});
|
|
1415
|
+
it('allows fields named optional', () => {
|
|
1416
|
+
let { statements, diagnostics } = parse(`
|
|
1417
|
+
interface IsJustOptional
|
|
1418
|
+
optional
|
|
1419
|
+
someThingElse
|
|
1420
|
+
end interface
|
|
1421
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1422
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1423
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1424
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1425
|
+
const iface = statements[0];
|
|
1426
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
|
|
1427
|
+
const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1428
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
1429
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(2);
|
|
1430
|
+
// eslint-disable-next-line no-bitwise
|
|
1431
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(0));
|
|
1432
|
+
});
|
|
1433
|
+
it('allows fields named optional that are also optional', () => {
|
|
1434
|
+
let { statements, diagnostics } = parse(`
|
|
1435
|
+
interface IsJustOptional
|
|
1436
|
+
optional optional
|
|
1437
|
+
end interface
|
|
1438
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1439
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1440
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1441
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1442
|
+
const iface = statements[0];
|
|
1443
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1444
|
+
const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1445
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
1446
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1447
|
+
// eslint-disable-next-line no-bitwise
|
|
1448
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
|
|
1449
|
+
});
|
|
1450
|
+
it('allows optional methods', () => {
|
|
1451
|
+
let { statements, diagnostics } = parse(`
|
|
1452
|
+
interface HasOptional
|
|
1453
|
+
optional function getValue() as boolean
|
|
1454
|
+
optional sub noop()
|
|
1455
|
+
optional function process()
|
|
1456
|
+
end interface
|
|
1457
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1458
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1459
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1460
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1461
|
+
const iface = statements[0];
|
|
1462
|
+
iface.methods.forEach(m => (0, chai_config_spec_1.expect)(m.isOptional).to.equal(true));
|
|
1463
|
+
const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1464
|
+
// eslint-disable-next-line no-bitwise
|
|
1465
|
+
ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
|
|
1466
|
+
});
|
|
1467
|
+
it('allows fields named `as` that are also optional', () => {
|
|
1468
|
+
let { statements, diagnostics } = parse(`
|
|
1469
|
+
interface IsJustOptional
|
|
1470
|
+
optional as
|
|
1471
|
+
end interface
|
|
1472
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1473
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1474
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1475
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1476
|
+
const iface = statements[0];
|
|
1477
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1478
|
+
const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1479
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
1480
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1481
|
+
// eslint-disable-next-line no-bitwise
|
|
1482
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
|
|
1483
|
+
});
|
|
1484
|
+
it('allows fields named `as` that are also typed', () => {
|
|
1485
|
+
let { statements, diagnostics } = parse(`
|
|
1486
|
+
interface IsJustOptional
|
|
1487
|
+
optional as as string
|
|
1488
|
+
end interface
|
|
1489
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1490
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1491
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1492
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1493
|
+
const iface = statements[0];
|
|
1494
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1495
|
+
const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1496
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
1497
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1498
|
+
// eslint-disable-next-line no-bitwise
|
|
1499
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
|
|
1500
|
+
});
|
|
1501
|
+
it('allows fields named `optional` that are also typed', () => {
|
|
1502
|
+
let { statements, diagnostics } = parse(`
|
|
1503
|
+
interface IsJustOptional
|
|
1504
|
+
optional as string
|
|
1505
|
+
end interface
|
|
1506
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1507
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1508
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1509
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1510
|
+
const iface = statements[0];
|
|
1511
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
|
|
1512
|
+
const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1513
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
|
|
1514
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1515
|
+
// eslint-disable-next-line no-bitwise
|
|
1516
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(0));
|
|
1517
|
+
});
|
|
1518
|
+
});
|
|
1519
|
+
describe('leadingTrivia', () => {
|
|
1520
|
+
it('gets leading trivia from functions', () => {
|
|
1521
|
+
let { statements } = parse(`
|
|
1522
|
+
' Nice function, bro
|
|
1523
|
+
function foo()
|
|
1524
|
+
return 1
|
|
1525
|
+
end function
|
|
1634
1526
|
`);
|
|
1635
|
-
const
|
|
1636
|
-
const
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
});
|
|
1647
|
-
it('allows token kinds from AllowedLocalIdentifiers as start of a chain', () => {
|
|
1648
|
-
const parser = parse(`
|
|
1649
|
-
sub testLocalIdentifiers(override, string, float)
|
|
1650
|
-
override.someProp.someFunc()
|
|
1651
|
-
string.someProp.someFunc()
|
|
1652
|
-
float.someProp.someFunc()
|
|
1527
|
+
const funcStatements = statements.filter(reflection_1.isFunctionStatement);
|
|
1528
|
+
const fooTrivia = funcStatements[0].getLeadingTrivia();
|
|
1529
|
+
(0, chai_config_spec_1.expect)(fooTrivia.length).to.be.greaterThan(0);
|
|
1530
|
+
(0, chai_config_spec_1.expect)(fooTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1531
|
+
});
|
|
1532
|
+
it('gets multiple lines of leading trivia', () => {
|
|
1533
|
+
let { statements } = parse(`
|
|
1534
|
+
' Say hello to someone
|
|
1535
|
+
'
|
|
1536
|
+
' @param {string} name the person you want to say hello to.
|
|
1537
|
+
sub sayHello(name as string = "world")
|
|
1653
1538
|
end sub
|
|
1654
1539
|
`);
|
|
1655
|
-
const
|
|
1656
|
-
const
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1540
|
+
const funcStatements = statements.filter(reflection_1.isFunctionStatement);
|
|
1541
|
+
const helloTrivia = funcStatements[0].getLeadingTrivia();
|
|
1542
|
+
(0, chai_config_spec_1.expect)(helloTrivia.length).to.be.greaterThan(0);
|
|
1543
|
+
(0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(3);
|
|
1544
|
+
});
|
|
1545
|
+
it('gets leading trivia from classes', () => {
|
|
1546
|
+
let { statements } = parse(`
|
|
1547
|
+
' hello
|
|
1548
|
+
' classes
|
|
1549
|
+
class Hello
|
|
1550
|
+
end class
|
|
1551
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1552
|
+
const classStatements = statements.filter(reflection_1.isClassStatement);
|
|
1553
|
+
const trivia = classStatements[0].getLeadingTrivia();
|
|
1554
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1555
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1556
|
+
});
|
|
1557
|
+
it('gets leading trivia from functions with annotations', () => {
|
|
1558
|
+
let { statements } = parse(`
|
|
1559
|
+
' hello comment 1
|
|
1560
|
+
' hello comment 2
|
|
1561
|
+
@annotation
|
|
1562
|
+
sub sayHello(name as string = "world")
|
|
1674
1563
|
end sub
|
|
1564
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1565
|
+
const funcStatements = statements.filter(reflection_1.isFunctionStatement);
|
|
1566
|
+
const helloTrivia = funcStatements[0].getLeadingTrivia();
|
|
1567
|
+
(0, chai_config_spec_1.expect)(helloTrivia.length).to.be.greaterThan(0);
|
|
1568
|
+
(0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1569
|
+
});
|
|
1570
|
+
it('gets leading trivia from class methods', () => {
|
|
1571
|
+
let { statements } = parse(`
|
|
1572
|
+
' hello
|
|
1573
|
+
' classes
|
|
1574
|
+
class Hello
|
|
1575
|
+
|
|
1576
|
+
' Gets the value of PI
|
|
1577
|
+
' Not a dessert
|
|
1578
|
+
function getPi() as float
|
|
1579
|
+
return 3.14
|
|
1580
|
+
end function
|
|
1581
|
+
|
|
1582
|
+
' Gets a dessert
|
|
1583
|
+
function getPie() as string
|
|
1584
|
+
return "Apple Pie"
|
|
1585
|
+
end function
|
|
1586
|
+
end class
|
|
1587
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1588
|
+
const classStatement = statements.filter(reflection_1.isClassStatement)[0];
|
|
1589
|
+
const methodStatements = classStatement.methods;
|
|
1590
|
+
// function getPi()
|
|
1591
|
+
let trivia = methodStatements[0].getLeadingTrivia();
|
|
1592
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1593
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1594
|
+
// function getPie()
|
|
1595
|
+
trivia = methodStatements[1].getLeadingTrivia();
|
|
1596
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1597
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1598
|
+
});
|
|
1599
|
+
it('gets leading trivia from class fields', () => {
|
|
1600
|
+
let { statements } = parse(`
|
|
1601
|
+
' hello
|
|
1602
|
+
' classes
|
|
1603
|
+
class Thing
|
|
1604
|
+
' like the sky
|
|
1605
|
+
' or a blueberry, evn though that's purple
|
|
1606
|
+
color = "blue"
|
|
1607
|
+
|
|
1608
|
+
' My name
|
|
1609
|
+
public name as string
|
|
1610
|
+
|
|
1611
|
+
' Only I know how old I am
|
|
1612
|
+
private age = 42
|
|
1613
|
+
end class
|
|
1614
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1615
|
+
const classStatement = statements.filter(reflection_1.isClassStatement)[0];
|
|
1616
|
+
const fieldStatements = classStatement.fields;
|
|
1617
|
+
// color = "blue"
|
|
1618
|
+
let trivia = fieldStatements[0].getLeadingTrivia();
|
|
1619
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1620
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1621
|
+
// public name as string
|
|
1622
|
+
trivia = fieldStatements[1].getLeadingTrivia();
|
|
1623
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1624
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1625
|
+
// private age = 42
|
|
1626
|
+
trivia = fieldStatements[2].getLeadingTrivia();
|
|
1627
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1628
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1629
|
+
});
|
|
1630
|
+
it('gets leading trivia from interfaces', () => {
|
|
1631
|
+
let { statements } = parse(`
|
|
1632
|
+
' Description of interface
|
|
1633
|
+
interface myIface
|
|
1634
|
+
' comment
|
|
1635
|
+
someField as integer
|
|
1636
|
+
|
|
1637
|
+
'comment
|
|
1638
|
+
function someFunc() as string
|
|
1639
|
+
end interface
|
|
1640
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1641
|
+
const ifaceStatement = statements.filter(reflection_1.isInterfaceStatement)[0];
|
|
1642
|
+
const fieldStatements = ifaceStatement.fields;
|
|
1643
|
+
const methodStatements = ifaceStatement.methods;
|
|
1644
|
+
// interface myIface
|
|
1645
|
+
let trivia = ifaceStatement.getLeadingTrivia();
|
|
1646
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1647
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1648
|
+
// someField as integer
|
|
1649
|
+
trivia = fieldStatements[0].getLeadingTrivia();
|
|
1650
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1651
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1652
|
+
// function someFunc() as string
|
|
1653
|
+
trivia = methodStatements[0].getLeadingTrivia();
|
|
1654
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1655
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1656
|
+
});
|
|
1657
|
+
it('gets leading trivia from namespaces', () => {
|
|
1658
|
+
let { statements } = parse(`
|
|
1659
|
+
' Description of interface
|
|
1660
|
+
namespace Nested.Name.Space
|
|
1661
|
+
|
|
1662
|
+
end namespace
|
|
1663
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1664
|
+
const nameSpaceStatement = statements.filter(reflection_1.isNamespaceStatement)[0];
|
|
1665
|
+
// namespace Nested.Name.Space
|
|
1666
|
+
let trivia = nameSpaceStatement.getLeadingTrivia();
|
|
1667
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1668
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1669
|
+
});
|
|
1670
|
+
});
|
|
1671
|
+
describe('unary/binary ordering', () => {
|
|
1672
|
+
it('creates the correct operator order for `not x = x` code', () => {
|
|
1673
|
+
let { diagnostics, statements } = parse(`
|
|
1674
|
+
function isStrNotEmpty(myStr as string) as boolean
|
|
1675
|
+
return not myStr = ""
|
|
1676
|
+
end function
|
|
1675
1677
|
`);
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
const
|
|
1679
|
-
|
|
1680
|
-
(0,
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
(0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'float', 'someFunc']);
|
|
1688
|
-
});
|
|
1689
|
-
it('finds tokens in the middle of a chain', () => {
|
|
1690
|
-
const parser = parse(`
|
|
1691
|
-
sub testMiddleOfChain()
|
|
1692
|
-
print m.nodes[8].label.text
|
|
1693
|
-
print alpha.bravo(charlie.delta)
|
|
1694
|
-
print m.otherFunc().name
|
|
1695
|
-
end sub
|
|
1678
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1679
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1680
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1681
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1682
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
|
|
1683
|
+
});
|
|
1684
|
+
it('creates the correct operator order for `not x + x` code', () => {
|
|
1685
|
+
let { diagnostics, statements } = parse(`
|
|
1686
|
+
function tryStuff() as integer
|
|
1687
|
+
return not 1 + 3 ' same as "not (3)" ... eg. the "flipped bits" of 3 (0000 0011) -> 1111 1100, or -4
|
|
1688
|
+
end function
|
|
1696
1689
|
`);
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
const
|
|
1700
|
-
|
|
1701
|
-
(0,
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
(0,
|
|
1710
|
-
(0,
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
const
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1690
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1691
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1692
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1693
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1694
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
|
|
1695
|
+
});
|
|
1696
|
+
it('creates the correct operator order for `x = not x` code', () => {
|
|
1697
|
+
let { diagnostics, statements } = parse(`
|
|
1698
|
+
function tryStuff() as boolean
|
|
1699
|
+
return 4 = not -5 ' same as "4 = 4"
|
|
1700
|
+
end function
|
|
1701
|
+
`);
|
|
1702
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1703
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1704
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1705
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn)).to.be.true;
|
|
1706
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(insideReturn.left)).to.be.true;
|
|
1707
|
+
const right = insideReturn.right;
|
|
1708
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right)).to.be.true;
|
|
1709
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right.right)).to.be.true; // not ( - ( 5))
|
|
1710
|
+
});
|
|
1711
|
+
it('allows multiple nots', () => {
|
|
1712
|
+
let { diagnostics, statements } = parse(`
|
|
1713
|
+
function tryStuff() as integer
|
|
1714
|
+
return not not not 4
|
|
1715
|
+
end function
|
|
1716
|
+
`);
|
|
1717
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1718
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1719
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1720
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1721
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
|
|
1722
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
|
|
1723
|
+
});
|
|
1724
|
+
it('allows multiple -', () => {
|
|
1725
|
+
let { diagnostics, statements } = parse(`
|
|
1726
|
+
function tryStuff() as integer
|
|
1727
|
+
return - - - 4
|
|
1728
|
+
end function
|
|
1718
1729
|
`);
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
(0,
|
|
1723
|
-
(0,
|
|
1730
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1731
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1732
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1733
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1734
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
|
|
1735
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
|
|
1724
1736
|
});
|
|
1725
1737
|
});
|
|
1726
1738
|
});
|
|
@@ -1730,6 +1742,7 @@ function parse(text, mode) {
|
|
|
1730
1742
|
mode: mode
|
|
1731
1743
|
});
|
|
1732
1744
|
}
|
|
1745
|
+
exports.parse = parse;
|
|
1733
1746
|
function rangeToArray(range) {
|
|
1734
1747
|
return [
|
|
1735
1748
|
range.start.line,
|
|
@@ -1741,14 +1754,14 @@ function rangeToArray(range) {
|
|
|
1741
1754
|
exports.rangeToArray = rangeToArray;
|
|
1742
1755
|
function expectCommentWithText(stat, text) {
|
|
1743
1756
|
if ((0, reflection_1.isCommentStatement)(stat)) {
|
|
1744
|
-
(0,
|
|
1757
|
+
(0, chai_config_spec_1.expect)(stat.text).to.equal(text);
|
|
1745
1758
|
}
|
|
1746
1759
|
else {
|
|
1747
1760
|
failStatementType(stat, 'Comment');
|
|
1748
1761
|
}
|
|
1749
1762
|
}
|
|
1750
1763
|
function failStatementType(stat, type) {
|
|
1751
|
-
|
|
1764
|
+
chai_config_spec_1.assert.fail(`Statement ${stat.constructor.name} line ${stat.range.start.line} is not a ${type}`);
|
|
1752
1765
|
}
|
|
1753
1766
|
exports.failStatementType = failStatementType;
|
|
1754
1767
|
//# sourceMappingURL=Parser.spec.js.map
|