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