brighterscript 1.0.0-alpha.23 → 1.0.0-alpha.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +585 -218
- package/README.md +45 -139
- package/bsconfig.schema.json +41 -0
- package/dist/ActionPipeline.d.ts +10 -0
- package/dist/ActionPipeline.js +40 -0
- package/dist/ActionPipeline.js.map +1 -0
- package/dist/AstValidationSegmenter.d.ts +25 -0
- package/dist/AstValidationSegmenter.js +152 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +39 -4
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.js +3 -3
- package/dist/Cache.js.map +1 -1
- package/dist/CacheVerifier.d.ts +7 -0
- package/dist/CacheVerifier.js +20 -0
- package/dist/CacheVerifier.js.map +1 -0
- package/dist/CodeActionUtil.d.ts +3 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +3 -2
- package/dist/CommentFlagProcessor.js +5 -4
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +3 -2
- package/dist/DependencyGraph.js +11 -10
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.js +9 -5
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +1 -0
- package/dist/DiagnosticFilterer.js +5 -3
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +79 -15
- package/dist/DiagnosticMessages.js +134 -21
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
- package/dist/DiagnosticSeverityAdjuster.js +41 -0
- package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
- package/dist/FunctionScope.d.ts +28 -0
- package/dist/FunctionScope.js +52 -0
- package/dist/FunctionScope.js.map +1 -0
- package/dist/KeyedThrottler.d.ts +3 -3
- package/dist/KeyedThrottler.js +3 -3
- package/dist/KeyedThrottler.js.map +1 -1
- package/dist/LanguageServer.d.ts +23 -11
- package/dist/LanguageServer.js +222 -87
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +3 -2
- package/dist/Logger.js +11 -3
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +21 -3
- package/dist/PluginInterface.js +74 -6
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +162 -81
- package/dist/Program.js +903 -732
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +22 -12
- package/dist/ProgramBuilder.js +132 -104
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +95 -134
- package/dist/Scope.js +477 -551
- package/dist/Scope.js.map +1 -1
- package/dist/Stopwatch.js +1 -1
- package/dist/Stopwatch.js.map +1 -1
- package/dist/SymbolTable.d.ts +95 -29
- package/dist/SymbolTable.js +256 -102
- package/dist/SymbolTable.js.map +1 -1
- package/dist/Throttler.d.ts +12 -0
- package/dist/Throttler.js +39 -0
- package/dist/Throttler.js.map +1 -1
- package/dist/Watcher.d.ts +0 -3
- package/dist/Watcher.js +0 -3
- package/dist/Watcher.js.map +1 -1
- package/dist/XmlScope.d.ts +4 -6
- package/dist/XmlScope.js +74 -68
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +48 -0
- package/dist/astUtils/CachedLookups.js +323 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +9 -5
- package/dist/astUtils/{AstEditor.js → Editor.js} +10 -4
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +68 -64
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +10 -10
- package/dist/astUtils/creators.js +26 -16
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +5 -5
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +132 -100
- package/dist/astUtils/reflection.js +225 -166
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +208 -126
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +12 -12
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +54 -35
- package/dist/astUtils/visitors.js +29 -3
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +178 -33
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -9
- package/dist/astUtils/xml.js +9 -9
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +12 -2
- package/dist/bscPlugin/BscPlugin.js +41 -3
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
- package/dist/bscPlugin/CallExpressionInfo.js +131 -0
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
- package/dist/bscPlugin/FileWriter.d.ts +6 -0
- package/dist/bscPlugin/FileWriter.js +24 -0
- package/dist/bscPlugin/FileWriter.js.map +1 -0
- package/dist/bscPlugin/SignatureHelpUtil.d.ts +10 -0
- package/dist/bscPlugin/SignatureHelpUtil.js +135 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +21 -12
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +86 -12
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +57 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js +544 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1909 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +17 -0
- package/dist/bscPlugin/hover/HoverProcessor.js +188 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +513 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +3 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +102 -29
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +167 -6
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +1 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
- package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
- package/dist/bscPlugin/serialize/BslibManager.js +40 -0
- package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
- package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
- package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
- package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +16 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +123 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +12 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +22 -1
- package/dist/bscPlugin/validation/BrsFileValidator.js +316 -29
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +264 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/ProgramValidator.d.ts +10 -0
- package/dist/bscPlugin/validation/ProgramValidator.js +32 -0
- package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +56 -8
- package/dist/bscPlugin/validation/ScopeValidator.js +514 -116
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2454 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js +44 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
- package/dist/cli.js +107 -8
- package/dist/cli.js.map +1 -1
- package/dist/deferred.d.ts +3 -3
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +8 -2
- package/dist/diagnosticUtils.js +47 -17
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +8 -10
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +26 -0
- package/dist/files/AssetFile.js +26 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +529 -486
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +124 -112
- package/dist/files/BrsFile.js +819 -1131
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1869 -1277
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +104 -0
- package/dist/files/BscFile.js +16 -0
- package/dist/files/BscFile.js.map +1 -0
- package/dist/files/Factory.d.ts +25 -0
- package/dist/files/Factory.js +22 -0
- package/dist/files/Factory.js.map +1 -0
- package/dist/files/LazyFileData.d.ts +20 -0
- package/dist/files/LazyFileData.js +54 -0
- package/dist/files/LazyFileData.js.map +1 -0
- package/dist/files/LazyFileData.spec.d.ts +1 -0
- package/dist/files/LazyFileData.spec.js +27 -0
- package/dist/files/LazyFileData.spec.js.map +1 -0
- package/dist/files/XmlFile.d.ts +70 -32
- package/dist/files/XmlFile.js +106 -117
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +325 -262
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +49 -41
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.js +104 -40
- package/dist/files/tests/optionalChaning.spec.js.map +1 -1
- package/dist/globalCallables.js +16 -18
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +440 -150
- package/dist/interfaces.js +27 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Character.spec.js +5 -5
- package/dist/lexer/Character.spec.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +12 -5
- package/dist/lexer/Lexer.js +28 -13
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +187 -134
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +9 -1
- package/dist/lexer/Token.js +9 -1
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +9 -0
- package/dist/lexer/TokenKind.js +30 -5
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +162 -0
- package/dist/parser/AstNode.js +225 -0
- package/dist/parser/AstNode.js.map +1 -0
- package/dist/parser/AstNode.spec.d.ts +1 -0
- package/dist/parser/AstNode.spec.js +165 -0
- package/dist/parser/AstNode.spec.js.map +1 -0
- package/dist/parser/BrsTranspileState.d.ts +4 -7
- package/dist/parser/BrsTranspileState.js +4 -12
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +126 -167
- package/dist/parser/Expression.js +524 -394
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +152 -146
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +45 -196
- package/dist/parser/Parser.js +470 -926
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +1034 -805
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +9 -8
- package/dist/parser/SGParser.js +10 -8
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +27 -38
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +98 -35
- package/dist/parser/SGTypes.js +169 -99
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +208 -122
- package/dist/parser/Statement.js +599 -364
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +45 -21
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +1 -1
- package/dist/parser/TranspileState.js +7 -12
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.js +3 -2
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +33 -23
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +25 -20
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +96 -94
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +22 -16
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +8 -8
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +58 -21
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +61 -20
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +8 -8
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +129 -21
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +5 -5
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +36 -36
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +67 -22
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +9 -9
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +123 -81
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +12 -12
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +12 -12
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/Relational.spec.js +13 -13
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +221 -81
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +287 -105
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js +127 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +15 -15
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/ConstStatement.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js +262 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/Continue.spec.d.ts +1 -0
- package/dist/parser/tests/statement/Continue.spec.js +119 -0
- package/dist/parser/tests/statement/Continue.spec.js.map +1 -0
- package/dist/parser/tests/statement/Declaration.spec.js +19 -19
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +22 -22
- package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.js +111 -300
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
- package/dist/parser/tests/statement/For.spec.js +9 -10
- package/dist/parser/tests/statement/For.spec.js.map +1 -1
- package/dist/parser/tests/statement/ForEach.spec.js +8 -9
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/statement/Function.spec.js +44 -35
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +5 -5
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +20 -20
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +30 -196
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +11 -11
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +16 -78
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +107 -90
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +14 -12
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +48 -35
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +6 -6
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +6 -6
- package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +18 -16
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +1 -1
- package/dist/preprocessor/Manifest.js +3 -3
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/preprocessor/Manifest.spec.js +8 -8
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/preprocessor/Preprocessor.d.ts +5 -6
- package/dist/preprocessor/Preprocessor.js +15 -11
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/preprocessor/Preprocessor.spec.js +25 -25
- package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.d.ts +1 -1
- package/dist/preprocessor/PreprocessorParser.js +7 -1
- package/dist/preprocessor/PreprocessorParser.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +13 -13
- package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
- package/dist/roku-types/data.json +6544 -10519
- package/dist/roku-types/index.d.ts +662 -1934
- package/dist/types/ArrayType.d.ts +10 -9
- package/dist/types/ArrayType.js +65 -60
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +36 -68
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +11 -0
- package/dist/types/AssociativeArrayType.js +52 -0
- package/dist/types/AssociativeArrayType.js.map +1 -0
- package/dist/types/BaseFunctionType.d.ts +9 -0
- package/dist/types/BaseFunctionType.js +25 -0
- package/dist/types/BaseFunctionType.js.map +1 -0
- package/dist/types/BooleanType.d.ts +8 -5
- package/dist/types/BooleanType.js +14 -7
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +10 -6
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +32 -21
- package/dist/types/BscType.js +118 -21
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BscTypeKind.d.ts +25 -0
- package/dist/types/BscTypeKind.js +30 -0
- package/dist/types/BscTypeKind.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
- package/dist/types/BuiltInInterfaceAdder.js +164 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +116 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
- package/dist/types/ClassType.d.ts +17 -0
- package/dist/types/ClassType.js +58 -0
- package/dist/types/ClassType.js.map +1 -0
- package/dist/types/ClassType.spec.d.ts +1 -0
- package/dist/types/ClassType.spec.js +77 -0
- package/dist/types/ClassType.spec.js.map +1 -0
- package/dist/types/ComponentType.d.ts +26 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +8 -5
- package/dist/types/DoubleType.js +18 -16
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +12 -6
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +10 -5
- package/dist/types/DynamicType.js +16 -4
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/DynamicType.spec.js +16 -5
- package/dist/types/DynamicType.spec.js.map +1 -1
- package/dist/types/EnumType.d.ts +30 -12
- package/dist/types/EnumType.js +43 -17
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/EnumType.spec.d.ts +1 -0
- package/dist/types/EnumType.spec.js +33 -0
- package/dist/types/EnumType.spec.js.map +1 -0
- package/dist/types/FloatType.d.ts +8 -5
- package/dist/types/FloatType.js +18 -16
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -6
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +13 -8
- package/dist/types/FunctionType.js +30 -14
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +28 -0
- package/dist/types/InheritableType.js +152 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +8 -5
- package/dist/types/IntegerType.js +18 -16
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +8 -6
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +12 -13
- package/dist/types/InterfaceType.js +20 -48
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +90 -56
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/InvalidType.d.ts +7 -5
- package/dist/types/InvalidType.js +13 -7
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +8 -6
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +8 -5
- package/dist/types/LongIntegerType.js +17 -15
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +10 -6
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/NamespaceType.d.ts +12 -0
- package/dist/types/NamespaceType.js +28 -0
- package/dist/types/NamespaceType.js.map +1 -0
- package/dist/types/ObjectType.d.ts +9 -8
- package/dist/types/ObjectType.js +21 -11
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ObjectType.spec.js +3 -3
- package/dist/types/ObjectType.spec.js.map +1 -1
- package/dist/types/ReferenceType.d.ts +63 -0
- package/dist/types/ReferenceType.js +423 -0
- package/dist/types/ReferenceType.js.map +1 -0
- package/dist/types/ReferenceType.spec.d.ts +1 -0
- package/dist/types/ReferenceType.spec.js +137 -0
- package/dist/types/ReferenceType.spec.js.map +1 -0
- package/dist/types/StringType.d.ts +11 -5
- package/dist/types/StringType.js +18 -7
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +3 -5
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +22 -17
- package/dist/types/TypedFunctionType.js +78 -60
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/TypedFunctionType.spec.js +105 -20
- package/dist/types/TypedFunctionType.spec.js.map +1 -1
- package/dist/types/UninitializedType.d.ts +8 -6
- package/dist/types/UninitializedType.js +13 -7
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +20 -0
- package/dist/types/UnionType.js +123 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +130 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +8 -5
- package/dist/types/VoidType.js +14 -7
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/VoidType.spec.js +3 -3
- package/dist/types/VoidType.spec.js.map +1 -1
- package/dist/types/helper.spec.d.ts +1 -0
- package/dist/types/helper.spec.js +145 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +19 -37
- package/dist/types/helpers.js +159 -99
- package/dist/types/helpers.js.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.js +39 -0
- package/dist/types/index.js.map +1 -0
- package/dist/util.d.ts +167 -131
- package/dist/util.js +890 -350
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +7 -25
- package/dist/validators/ClassValidator.js +103 -194
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +165 -149
- package/dist/astUtils/AstEditor.js.map +0 -1
- package/dist/astUtils/AstEditor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +0 -8
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +0 -40
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -32
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
- package/dist/parser/SGTypes.spec.js +0 -351
- package/dist/parser/SGTypes.spec.js.map +0 -1
- package/dist/types/CustomType.d.ts +0 -12
- package/dist/types/CustomType.js +0 -44
- package/dist/types/CustomType.js.map +0 -1
- package/dist/types/LazyType.d.ts +0 -16
- package/dist/types/LazyType.js +0 -44
- package/dist/types/LazyType.js.map +0 -1
- /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
- /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{parser/SGTypes.spec.d.ts → bscPlugin/hover/HoverProcessor.spec.d.ts} +0 -0
|
@@ -1,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,207 +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
|
|
15
|
-
const source_map_1 = require("source-map");
|
|
16
|
-
const BrsFile_1 = require("../files/BrsFile");
|
|
17
|
-
const Program_1 = require("../Program");
|
|
14
|
+
const visitors_1 = require("../astUtils/visitors");
|
|
18
15
|
const SymbolTable_1 = require("../SymbolTable");
|
|
19
|
-
const TypedFunctionType_1 = require("../types/TypedFunctionType");
|
|
20
|
-
const LazyType_1 = require("../types/LazyType");
|
|
21
16
|
const IntegerType_1 = require("../types/IntegerType");
|
|
17
|
+
const FloatType_1 = require("../types/FloatType");
|
|
22
18
|
const StringType_1 = require("../types/StringType");
|
|
23
|
-
const
|
|
24
|
-
const CustomType_1 = require("../types/CustomType");
|
|
25
|
-
const VoidType_1 = require("../types/VoidType");
|
|
26
|
-
const DynamicType_1 = require("../types/DynamicType");
|
|
27
|
-
const util_1 = require("../util");
|
|
28
|
-
const ArrayType_1 = require("../types/ArrayType");
|
|
19
|
+
const types_1 = require("../types");
|
|
29
20
|
describe('parser', () => {
|
|
30
21
|
it('emits empty object when empty token list is provided', () => {
|
|
31
|
-
(0,
|
|
22
|
+
(0, chai_config_spec_1.expect)(Parser_1.Parser.parse([])).to.deep.include({
|
|
32
23
|
statements: [],
|
|
33
24
|
diagnostics: []
|
|
34
25
|
});
|
|
35
26
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
isAlive = false
|
|
42
|
-
end for
|
|
43
|
-
for i = 0 to 10 step 1
|
|
44
|
-
j = i
|
|
45
|
-
end for
|
|
46
|
-
humansAreAlive = false
|
|
47
|
-
end sub
|
|
48
|
-
`);
|
|
49
|
-
(0, chai_1.expect)(parser.references.functionExpressions[0].symbolTable.getOwnSymbols().map(x => x.name).sort()).to.eql([
|
|
50
|
-
'herd',
|
|
51
|
-
'humansAreAlive',
|
|
52
|
-
'i',
|
|
53
|
-
'isAlive',
|
|
54
|
-
'j',
|
|
55
|
-
'zombie'
|
|
56
|
-
]);
|
|
57
|
-
parser.invalidateReferences();
|
|
58
|
-
(0, chai_1.expect)(parser.references.functionExpressions[0].symbolTable.getOwnSymbols().map(x => x.name).sort()).to.eql([
|
|
59
|
-
'herd',
|
|
60
|
-
'humansAreAlive',
|
|
61
|
-
'i',
|
|
62
|
-
'isAlive',
|
|
63
|
-
'j',
|
|
64
|
-
'zombie'
|
|
65
|
-
]);
|
|
66
|
-
});
|
|
67
|
-
it('assigns localVars to correct function expression bucket', () => {
|
|
68
|
-
const parser = Parser_1.Parser.parse(`
|
|
69
|
-
sub main()
|
|
70
|
-
outerName = "bob"
|
|
71
|
-
speak = sub()
|
|
72
|
-
innerName = "innerBob"
|
|
27
|
+
/*
|
|
28
|
+
describe.skip('findReferences', () => {
|
|
29
|
+
it('gets called if references are missing', () => {
|
|
30
|
+
const parser = Parser.parse(`
|
|
31
|
+
sub main()
|
|
73
32
|
end sub
|
|
74
|
-
age = 12
|
|
75
|
-
end sub
|
|
76
|
-
`);
|
|
77
|
-
parser.invalidateReferences();
|
|
78
|
-
(0, chai_1.expect)(parser.references.functionExpressions.map(x => {
|
|
79
|
-
return x.symbolTable.getOwnSymbols().map(x => x.name);
|
|
80
|
-
})).to.eql([
|
|
81
|
-
[
|
|
82
|
-
'outerName',
|
|
83
|
-
'speak',
|
|
84
|
-
'age'
|
|
85
|
-
],
|
|
86
|
-
[
|
|
87
|
-
'innerName'
|
|
88
|
-
]
|
|
89
|
-
]);
|
|
90
|
-
});
|
|
91
|
-
it('gets called if references are missing', () => {
|
|
92
|
-
const parser = Parser_1.Parser.parse(`
|
|
93
|
-
sub main()
|
|
94
|
-
end sub
|
|
95
33
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
113
|
-
function expressionsToStrings(expressions) {
|
|
114
|
-
return [...expressions.values()].map(x => {
|
|
115
|
-
const file = new BrsFile_1.BrsFile('', '', new Program_1.Program({}));
|
|
116
|
-
const state = new BrsTranspileState_1.BrsTranspileState(file);
|
|
117
|
-
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
|
+
]);
|
|
118
50
|
});
|
|
119
|
-
}
|
|
120
|
-
it('works for references.expressions', () => {
|
|
121
|
-
const parser = Parser_1.Parser.parse(`
|
|
122
|
-
a += 1 + 2
|
|
123
|
-
b += getValue1() + getValue2()
|
|
124
|
-
increment++
|
|
125
|
-
decrement--
|
|
126
|
-
some.node@.doCallfunc()
|
|
127
|
-
bravo(3 + 4).jump(callMe())
|
|
128
|
-
obj = {
|
|
129
|
-
val1: someValue
|
|
130
|
-
}
|
|
131
|
-
arr = [
|
|
132
|
-
one
|
|
133
|
-
]
|
|
134
|
-
thing = alpha.bravo
|
|
135
|
-
alpha.charlie()
|
|
136
|
-
delta(alpha.delta)
|
|
137
|
-
call1().a.b.call2()
|
|
138
|
-
class Person
|
|
139
|
-
name as string = "bob"
|
|
140
|
-
end class
|
|
141
|
-
function thing(p1 = name.space.getSomething())
|
|
142
51
|
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
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
|
+
}); */
|
|
215
188
|
describe('callfunc operator', () => {
|
|
216
189
|
it('is not allowed in brightscript mode', () => {
|
|
217
190
|
var _a;
|
|
@@ -220,7 +193,7 @@ describe('parser', () => {
|
|
|
220
193
|
node@.doSomething(1, 2)
|
|
221
194
|
end sub
|
|
222
195
|
`, Parser_1.ParseMode.BrightScript);
|
|
223
|
-
(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);
|
|
224
197
|
});
|
|
225
198
|
it('does not cause parse errors', () => {
|
|
226
199
|
var _a, _b, _c, _d, _e;
|
|
@@ -229,15 +202,15 @@ describe('parser', () => {
|
|
|
229
202
|
node@.doSomething(1, 2)
|
|
230
203
|
end sub
|
|
231
204
|
`, Parser_1.ParseMode.BrighterScript);
|
|
232
|
-
(0,
|
|
233
|
-
(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);
|
|
234
207
|
});
|
|
235
208
|
});
|
|
236
209
|
describe('optional chaining operator', () => {
|
|
237
210
|
function getExpression(text, options) {
|
|
238
211
|
const parser = parse(text, options === null || options === void 0 ? void 0 : options.parseMode);
|
|
239
212
|
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
240
|
-
const expressions =
|
|
213
|
+
const expressions = parser.ast.findChildren(reflection_1.isExpression);
|
|
241
214
|
if (options === null || options === void 0 ? void 0 : options.matcher) {
|
|
242
215
|
return expressions.find(options.matcher);
|
|
243
216
|
}
|
|
@@ -247,50 +220,50 @@ describe('parser', () => {
|
|
|
247
220
|
}
|
|
248
221
|
it('works for ?.', () => {
|
|
249
222
|
const expression = getExpression(`value = person?.name`);
|
|
250
|
-
(0,
|
|
251
|
-
(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);
|
|
252
225
|
});
|
|
253
226
|
it('works for ?[', () => {
|
|
254
227
|
const expression = getExpression(`value = person?["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
255
|
-
(0,
|
|
256
|
-
(0,
|
|
257
|
-
(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;
|
|
258
231
|
});
|
|
259
232
|
it('works for ?.[', () => {
|
|
260
233
|
var _a;
|
|
261
234
|
const expression = getExpression(`value = person?.["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
262
|
-
(0,
|
|
263
|
-
(0,
|
|
264
|
-
(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);
|
|
265
238
|
});
|
|
266
239
|
it('works for ?@', () => {
|
|
267
240
|
const expression = getExpression(`value = someXml?@someAttr`);
|
|
268
|
-
(0,
|
|
269
|
-
(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);
|
|
270
243
|
});
|
|
271
244
|
it('works for ?(', () => {
|
|
272
245
|
const expression = getExpression(`value = person.getName?()`);
|
|
273
|
-
(0,
|
|
274
|
-
(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);
|
|
275
248
|
});
|
|
276
249
|
it('works for print statements using question mark', () => {
|
|
277
250
|
const { statements } = parse(`
|
|
278
251
|
?[1]
|
|
279
252
|
?(1+1)
|
|
280
253
|
`);
|
|
281
|
-
(0,
|
|
282
|
-
(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);
|
|
283
256
|
});
|
|
284
257
|
//TODO enable this once we properly parse IIFEs
|
|
285
258
|
it.skip('works for ?( in anonymous function', () => {
|
|
286
259
|
const expression = getExpression(`thing = (function() : end function)?()`);
|
|
287
|
-
(0,
|
|
288
|
-
(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);
|
|
289
262
|
});
|
|
290
263
|
it('works for ?( in new call', () => {
|
|
291
264
|
const expression = getExpression(`thing = new Person?()`, { parseMode: Parser_1.ParseMode.BrighterScript });
|
|
292
|
-
(0,
|
|
293
|
-
(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);
|
|
294
267
|
});
|
|
295
268
|
it('distinguishes between optional chaining and ternary expression', () => {
|
|
296
269
|
const parser = parse(`
|
|
@@ -300,8 +273,9 @@ describe('parser', () => {
|
|
|
300
273
|
key = isTrue ? ["name"] : ["age"]
|
|
301
274
|
end sub
|
|
302
275
|
`, Parser_1.ParseMode.BrighterScript);
|
|
303
|
-
|
|
304
|
-
(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);
|
|
305
279
|
});
|
|
306
280
|
it('distinguishes between optional chaining and ternary expression', () => {
|
|
307
281
|
const parser = parse(`
|
|
@@ -312,13 +286,14 @@ describe('parser', () => {
|
|
|
312
286
|
key = isTrue ? ["name"] : getDefault()
|
|
313
287
|
end sub
|
|
314
288
|
`, Parser_1.ParseMode.BrighterScript);
|
|
315
|
-
|
|
316
|
-
(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);
|
|
317
292
|
});
|
|
318
293
|
});
|
|
319
294
|
describe('diagnostic locations', () => {
|
|
320
295
|
it('tracks basic diagnostic locations', () => {
|
|
321
|
-
(0,
|
|
296
|
+
(0, chai_config_spec_1.expect)(parse(`
|
|
322
297
|
sub main()
|
|
323
298
|
call()a
|
|
324
299
|
end sub
|
|
@@ -334,8 +309,8 @@ describe('parser', () => {
|
|
|
334
309
|
return "6c5cdf1"
|
|
335
310
|
end functionasdf
|
|
336
311
|
`).diagnostics;
|
|
337
|
-
(0,
|
|
338
|
-
(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));
|
|
339
314
|
});
|
|
340
315
|
});
|
|
341
316
|
describe('parse', () => {
|
|
@@ -372,20 +347,37 @@ describe('parser', () => {
|
|
|
372
347
|
});
|
|
373
348
|
it('supports using "interface" as parameter name', () => {
|
|
374
349
|
var _a;
|
|
375
|
-
(0,
|
|
350
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
376
351
|
sub main(interface as object)
|
|
377
352
|
end sub
|
|
378
353
|
`, Parser_1.ParseMode.BrighterScript).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
379
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
|
+
});
|
|
380
364
|
describe('namespace', () => {
|
|
381
|
-
it('
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
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
|
|
386
371
|
end namespace
|
|
387
|
-
end
|
|
388
|
-
`, 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
|
+
]);
|
|
389
381
|
});
|
|
390
382
|
it('parses empty namespace', () => {
|
|
391
383
|
var _a;
|
|
@@ -393,8 +385,8 @@ describe('parser', () => {
|
|
|
393
385
|
namespace Name.Space
|
|
394
386
|
end namespace
|
|
395
387
|
`, Parser_1.ParseMode.BrighterScript);
|
|
396
|
-
(0,
|
|
397
|
-
(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);
|
|
398
390
|
});
|
|
399
391
|
it('includes body', () => {
|
|
400
392
|
var _a;
|
|
@@ -404,9 +396,9 @@ describe('parser', () => {
|
|
|
404
396
|
end sub
|
|
405
397
|
end namespace
|
|
406
398
|
`, Parser_1.ParseMode.BrighterScript);
|
|
407
|
-
(0,
|
|
408
|
-
(0,
|
|
409
|
-
(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);
|
|
410
402
|
});
|
|
411
403
|
it('supports comments and newlines', () => {
|
|
412
404
|
var _a;
|
|
@@ -422,7 +414,7 @@ describe('parser', () => {
|
|
|
422
414
|
'comment
|
|
423
415
|
end namespace 'comment
|
|
424
416
|
`, Parser_1.ParseMode.BrighterScript);
|
|
425
|
-
(0,
|
|
417
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
426
418
|
});
|
|
427
419
|
it('catches missing name', () => {
|
|
428
420
|
var _a;
|
|
@@ -430,7 +422,7 @@ describe('parser', () => {
|
|
|
430
422
|
namespace
|
|
431
423
|
end namespace
|
|
432
424
|
`, Parser_1.ParseMode.BrighterScript);
|
|
433
|
-
(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);
|
|
434
426
|
});
|
|
435
427
|
it('recovers after missing `end namespace`', () => {
|
|
436
428
|
var _a, _b, _c;
|
|
@@ -439,9 +431,9 @@ describe('parser', () => {
|
|
|
439
431
|
sub main()
|
|
440
432
|
end sub
|
|
441
433
|
`, Parser_1.ParseMode.BrighterScript);
|
|
442
|
-
(0,
|
|
443
|
-
(0,
|
|
444
|
-
(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);
|
|
445
437
|
});
|
|
446
438
|
it('adds diagnostic when encountering namespace in brightscript mode', () => {
|
|
447
439
|
var _a;
|
|
@@ -449,47 +441,12 @@ describe('parser', () => {
|
|
|
449
441
|
namespace Name.Space
|
|
450
442
|
end namespace
|
|
451
443
|
`);
|
|
452
|
-
(0,
|
|
453
|
-
});
|
|
454
|
-
it('declares a symbol table for the namespace', () => {
|
|
455
|
-
let parser = parse(`
|
|
456
|
-
namespace Name.Space
|
|
457
|
-
function funcInt() as integer
|
|
458
|
-
return 3
|
|
459
|
-
end function
|
|
460
|
-
|
|
461
|
-
function funcStr() as string
|
|
462
|
-
return "hello"
|
|
463
|
-
end function
|
|
464
|
-
end namespace
|
|
465
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
466
|
-
(0, chai_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
467
|
-
const namespaceStmt = parser.ast.statements[0];
|
|
468
|
-
(0, chai_1.expect)(namespaceStmt.symbolTable).to.be.instanceof(SymbolTable_1.SymbolTable);
|
|
469
|
-
(0, chai_1.expect)(namespaceStmt.symbolTable.getSymbolType('funcInt').toString()).to.equal('function funcInt() as integer');
|
|
470
|
-
(0, chai_1.expect)(namespaceStmt.symbolTable.getSymbolType('funcStr')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
|
|
471
|
-
const strFunctionType = namespaceStmt.symbolTable.getSymbolType('funcStr');
|
|
472
|
-
(0, chai_1.expect)(strFunctionType.returnType.toString()).to.equal('string');
|
|
473
|
-
});
|
|
474
|
-
it('adds a fully qualified name of a function in a namespace to the parsers symbol table', () => {
|
|
475
|
-
let parser = parse(`
|
|
476
|
-
namespace Name.Space
|
|
477
|
-
function funcInt() as integer
|
|
478
|
-
return 3
|
|
479
|
-
end function
|
|
480
|
-
|
|
481
|
-
function funcStr() as string
|
|
482
|
-
return "hello"
|
|
483
|
-
end function
|
|
484
|
-
end namespace
|
|
485
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
486
|
-
(0, chai_1.expect)(parser.symbolTable.getSymbolType('Name.Space.funcInt')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
|
|
487
|
-
(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);
|
|
488
445
|
});
|
|
489
446
|
});
|
|
490
447
|
it('supports << operator', () => {
|
|
491
448
|
var _a;
|
|
492
|
-
(0,
|
|
449
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
493
450
|
sub main()
|
|
494
451
|
print ((r << 24) + (g << 16) + (b << 8) + a)
|
|
495
452
|
end sub
|
|
@@ -497,7 +454,7 @@ describe('parser', () => {
|
|
|
497
454
|
});
|
|
498
455
|
it('supports >> operator', () => {
|
|
499
456
|
var _a;
|
|
500
|
-
(0,
|
|
457
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
501
458
|
sub main()
|
|
502
459
|
print ((r >> 24) + (g >> 16) + (b >> 8) + a)
|
|
503
460
|
end sub
|
|
@@ -505,7 +462,7 @@ describe('parser', () => {
|
|
|
505
462
|
});
|
|
506
463
|
it('allows global function names with same as token to be called', () => {
|
|
507
464
|
var _a;
|
|
508
|
-
(0,
|
|
465
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
509
466
|
sub main()
|
|
510
467
|
print string(123)
|
|
511
468
|
end sub
|
|
@@ -519,18 +476,18 @@ describe('parser', () => {
|
|
|
519
476
|
age = personXml.firstChild@age
|
|
520
477
|
end sub
|
|
521
478
|
`);
|
|
522
|
-
(0,
|
|
479
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
523
480
|
let statements = parser.statements[0].func.body.statements;
|
|
524
481
|
let first = statements[0].value;
|
|
525
|
-
(0,
|
|
526
|
-
(0,
|
|
527
|
-
(0,
|
|
528
|
-
(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');
|
|
529
486
|
let second = statements[1].value;
|
|
530
|
-
(0,
|
|
531
|
-
(0,
|
|
532
|
-
(0,
|
|
533
|
-
(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');
|
|
534
491
|
});
|
|
535
492
|
it('does not allow chaining of @ symbols', () => {
|
|
536
493
|
let parser = parse(`
|
|
@@ -539,58 +496,58 @@ describe('parser', () => {
|
|
|
539
496
|
name = personXml@name@age@shoeSize
|
|
540
497
|
end sub
|
|
541
498
|
`);
|
|
542
|
-
(0,
|
|
499
|
+
(0, chai_config_spec_1.expect)(parser.diagnostics).not.to.be.empty;
|
|
543
500
|
});
|
|
544
501
|
it('unknown function type does not invalidate rest of function', () => {
|
|
545
502
|
let { statements, diagnostics } = parse(`
|
|
546
503
|
function log() as UNKNOWN_TYPE
|
|
547
504
|
end function
|
|
548
505
|
`, Parser_1.ParseMode.BrightScript);
|
|
549
|
-
(0,
|
|
550
|
-
(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;
|
|
551
508
|
});
|
|
552
509
|
it('unknown function type is not a problem in Brighterscript mode', () => {
|
|
553
510
|
let { statements, diagnostics } = parse(`
|
|
554
511
|
function log() as UNKNOWN_TYPE
|
|
555
512
|
end function
|
|
556
513
|
`, Parser_1.ParseMode.BrighterScript);
|
|
557
|
-
(0,
|
|
558
|
-
(0,
|
|
514
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
515
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
559
516
|
});
|
|
560
517
|
it('allows namespaced function type in Brighterscript mode', () => {
|
|
561
518
|
let { statements, diagnostics } = parse(`
|
|
562
519
|
function log() as SOME_NAMESPACE.UNKNOWN_TYPE
|
|
563
520
|
end function
|
|
564
521
|
`, Parser_1.ParseMode.BrighterScript);
|
|
565
|
-
(0,
|
|
566
|
-
(0,
|
|
522
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
523
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
567
524
|
});
|
|
568
525
|
it('allows custom parameter types in BrighterscriptMode', () => {
|
|
569
526
|
let { statements, diagnostics } = parse(`
|
|
570
527
|
sub foo(value as UNKNOWN_TYPE)
|
|
571
528
|
end sub
|
|
572
529
|
`, Parser_1.ParseMode.BrighterScript);
|
|
573
|
-
(0,
|
|
574
|
-
(0,
|
|
530
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
531
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
575
532
|
});
|
|
576
|
-
it('does not
|
|
533
|
+
it('does not cause any diagnostics when custom parameter types are used in Brightscript Mode', () => {
|
|
577
534
|
let { diagnostics } = parse(`
|
|
578
535
|
sub foo(value as UNKNOWN_TYPE)
|
|
579
536
|
end sub
|
|
580
537
|
`, Parser_1.ParseMode.BrightScript);
|
|
581
|
-
(0,
|
|
538
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
582
539
|
});
|
|
583
540
|
it('allows custom namespaced parameter types in BrighterscriptMode', () => {
|
|
584
541
|
let { statements, diagnostics } = parse(`
|
|
585
542
|
sub foo(value as SOME_NAMESPACE.UNKNOWN_TYPE)
|
|
586
543
|
end sub
|
|
587
544
|
`, Parser_1.ParseMode.BrighterScript);
|
|
588
|
-
(0,
|
|
589
|
-
(0,
|
|
545
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
546
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
590
547
|
});
|
|
591
548
|
it('works with conditionals', () => {
|
|
592
549
|
var _a;
|
|
593
|
-
(0,
|
|
550
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
594
551
|
function printNumber()
|
|
595
552
|
if true then
|
|
596
553
|
print 1
|
|
@@ -602,7 +559,7 @@ describe('parser', () => {
|
|
|
602
559
|
});
|
|
603
560
|
it('supports single-line if statements', () => {
|
|
604
561
|
var _a;
|
|
605
|
-
(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;
|
|
606
563
|
});
|
|
607
564
|
it('works with excess newlines', () => {
|
|
608
565
|
var _a;
|
|
@@ -615,7 +572,7 @@ describe('parser', () => {
|
|
|
615
572
|
' print 1\n\n' +
|
|
616
573
|
' end if\n\n' +
|
|
617
574
|
'end function\n\n');
|
|
618
|
-
(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;
|
|
619
576
|
});
|
|
620
577
|
it('does not invalidate entire file when line ends with a period', () => {
|
|
621
578
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -625,15 +582,101 @@ describe('parser', () => {
|
|
|
625
582
|
|
|
626
583
|
`);
|
|
627
584
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
628
|
-
(0,
|
|
585
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1, 'Error count should be 0');
|
|
629
586
|
});
|
|
630
|
-
it
|
|
587
|
+
it('allows printing object with trailing period', () => {
|
|
631
588
|
let { tokens } = Lexer_1.Lexer.scan(`print a.`);
|
|
632
|
-
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);
|
|
633
598
|
let printStatement = statements[0];
|
|
634
|
-
(0,
|
|
635
|
-
(0,
|
|
636
|
-
(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
|
+
});
|
|
637
680
|
});
|
|
638
681
|
describe('comments', () => {
|
|
639
682
|
it('combines multi-line comments', () => {
|
|
@@ -643,8 +686,8 @@ describe('parser', () => {
|
|
|
643
686
|
'line 3
|
|
644
687
|
`);
|
|
645
688
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
646
|
-
(0,
|
|
647
|
-
(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`);
|
|
648
691
|
});
|
|
649
692
|
it('does not combile comments separated by newlines', () => {
|
|
650
693
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -655,11 +698,11 @@ describe('parser', () => {
|
|
|
655
698
|
'line 3
|
|
656
699
|
`);
|
|
657
700
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
658
|
-
(0,
|
|
659
|
-
(0,
|
|
660
|
-
(0,
|
|
661
|
-
(0,
|
|
662
|
-
(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`);
|
|
663
706
|
});
|
|
664
707
|
it('works after print statement', () => {
|
|
665
708
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -668,8 +711,8 @@ describe('parser', () => {
|
|
|
668
711
|
end sub
|
|
669
712
|
`);
|
|
670
713
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
671
|
-
(0,
|
|
672
|
-
(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`);
|
|
673
716
|
});
|
|
674
717
|
it('declaration-level', () => {
|
|
675
718
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -679,9 +722,9 @@ describe('parser', () => {
|
|
|
679
722
|
'comment 2
|
|
680
723
|
`);
|
|
681
724
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
682
|
-
(0,
|
|
683
|
-
(0,
|
|
684
|
-
(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`);
|
|
685
728
|
});
|
|
686
729
|
it('works in aa literal as its own statement', () => {
|
|
687
730
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -691,7 +734,7 @@ describe('parser', () => {
|
|
|
691
734
|
}
|
|
692
735
|
`);
|
|
693
736
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
694
|
-
(0,
|
|
737
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
695
738
|
});
|
|
696
739
|
it('parses after function call', () => {
|
|
697
740
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -701,8 +744,8 @@ describe('parser', () => {
|
|
|
701
744
|
end sub
|
|
702
745
|
`);
|
|
703
746
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
704
|
-
(0,
|
|
705
|
-
(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`);
|
|
706
749
|
});
|
|
707
750
|
it('function', () => {
|
|
708
751
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -713,11 +756,11 @@ describe('parser', () => {
|
|
|
713
756
|
end function 'comment 4
|
|
714
757
|
`);
|
|
715
758
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
716
|
-
(0,
|
|
717
|
-
(0,
|
|
718
|
-
(0,
|
|
719
|
-
(0,
|
|
720
|
-
(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`);
|
|
721
764
|
});
|
|
722
765
|
it('if statement`', () => {
|
|
723
766
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -738,7 +781,7 @@ describe('parser', () => {
|
|
|
738
781
|
end function
|
|
739
782
|
`);
|
|
740
783
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
741
|
-
(0,
|
|
784
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
742
785
|
let fnSmt = statements[0];
|
|
743
786
|
if ((0, reflection_1.isFunctionStatement)(fnSmt)) {
|
|
744
787
|
let ifStmt = fnSmt.func.body.statements[0];
|
|
@@ -785,12 +828,12 @@ describe('parser', () => {
|
|
|
785
828
|
end function
|
|
786
829
|
`);
|
|
787
830
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
788
|
-
(0,
|
|
831
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
789
832
|
let stmt = statements[0].func.body.statements[0];
|
|
790
|
-
(0,
|
|
791
|
-
(0,
|
|
792
|
-
(0,
|
|
793
|
-
(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`);
|
|
794
837
|
});
|
|
795
838
|
it('for', () => {
|
|
796
839
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -803,12 +846,12 @@ describe('parser', () => {
|
|
|
803
846
|
end function
|
|
804
847
|
`);
|
|
805
848
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
806
|
-
(0,
|
|
849
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
807
850
|
let stmt = statements[0].func.body.statements[0];
|
|
808
|
-
(0,
|
|
809
|
-
(0,
|
|
810
|
-
(0,
|
|
811
|
-
(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`);
|
|
812
855
|
});
|
|
813
856
|
it('for each', () => {
|
|
814
857
|
let { tokens } = Lexer_1.Lexer.scan(`
|
|
@@ -821,12 +864,12 @@ describe('parser', () => {
|
|
|
821
864
|
end function
|
|
822
865
|
`);
|
|
823
866
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
824
|
-
(0,
|
|
867
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
825
868
|
let stmt = statements[0].func.body.statements[0];
|
|
826
|
-
(0,
|
|
827
|
-
(0,
|
|
828
|
-
(0,
|
|
829
|
-
(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`);
|
|
830
873
|
});
|
|
831
874
|
});
|
|
832
875
|
});
|
|
@@ -838,7 +881,7 @@ describe('parser', () => {
|
|
|
838
881
|
then = true
|
|
839
882
|
end sub
|
|
840
883
|
`);
|
|
841
|
-
(0,
|
|
884
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1);
|
|
842
885
|
});
|
|
843
886
|
it('is allowed as an AA property name', () => {
|
|
844
887
|
var _a;
|
|
@@ -851,7 +894,39 @@ describe('parser', () => {
|
|
|
851
894
|
print person.then
|
|
852
895
|
end sub
|
|
853
896
|
`);
|
|
854
|
-
(0,
|
|
897
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
898
|
+
});
|
|
899
|
+
it('allows `mod` as an AA literal property', () => {
|
|
900
|
+
const parser = parse(`
|
|
901
|
+
sub main()
|
|
902
|
+
person = {
|
|
903
|
+
mod: true
|
|
904
|
+
}
|
|
905
|
+
person.mod = false
|
|
906
|
+
print person.mod
|
|
907
|
+
end sub
|
|
908
|
+
`);
|
|
909
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
910
|
+
});
|
|
911
|
+
it('converts aa literal property TokenKind to Identifier', () => {
|
|
912
|
+
const parser = parse(`
|
|
913
|
+
sub main()
|
|
914
|
+
person = {
|
|
915
|
+
mod: true
|
|
916
|
+
and: true
|
|
917
|
+
}
|
|
918
|
+
end sub
|
|
919
|
+
`);
|
|
920
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
921
|
+
const elements = [];
|
|
922
|
+
parser.ast.walk((0, visitors_1.createVisitor)({
|
|
923
|
+
AAMemberExpression: (node) => {
|
|
924
|
+
elements.push(node);
|
|
925
|
+
}
|
|
926
|
+
}), {
|
|
927
|
+
walkMode: visitors_1.WalkMode.visitAllRecursive
|
|
928
|
+
});
|
|
929
|
+
(0, chai_config_spec_1.expect)(elements.map(x => x.keyToken.kind)).to.eql([TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.Identifier]);
|
|
855
930
|
});
|
|
856
931
|
});
|
|
857
932
|
it('"end" is not allowed as a local identifier', () => {
|
|
@@ -860,7 +935,7 @@ describe('parser', () => {
|
|
|
860
935
|
end = true
|
|
861
936
|
end sub
|
|
862
937
|
`);
|
|
863
|
-
(0,
|
|
938
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.length.greaterThan(0);
|
|
864
939
|
});
|
|
865
940
|
it('none of them can be used as local variables', () => {
|
|
866
941
|
let reservedWords = new Set(TokenKind_1.ReservedWords);
|
|
@@ -873,7 +948,7 @@ describe('parser', () => {
|
|
|
873
948
|
end sub
|
|
874
949
|
`);
|
|
875
950
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
876
|
-
(0,
|
|
951
|
+
(0, chai_config_spec_1.expect)(diagnostics, `assigning to reserved word "${reservedWord}" should have been an error`).to.be.length.greaterThan(0);
|
|
877
952
|
}
|
|
878
953
|
});
|
|
879
954
|
});
|
|
@@ -883,24 +958,24 @@ describe('parser', () => {
|
|
|
883
958
|
let { statements, diagnostics } = parse(`
|
|
884
959
|
import "somePath"
|
|
885
960
|
`, Parser_1.ParseMode.BrighterScript);
|
|
886
|
-
(0,
|
|
887
|
-
(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);
|
|
888
963
|
});
|
|
889
964
|
it('catches import statements used in brightscript files', () => {
|
|
890
965
|
var _a;
|
|
891
966
|
let { statements, diagnostics } = parse(`
|
|
892
967
|
import "somePath"
|
|
893
968
|
`, Parser_1.ParseMode.BrightScript);
|
|
894
|
-
(0,
|
|
895
|
-
(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);
|
|
896
971
|
});
|
|
897
|
-
it('
|
|
972
|
+
it('catchs missing file path', () => {
|
|
898
973
|
var _a;
|
|
899
974
|
let { statements, diagnostics } = parse(`
|
|
900
975
|
import
|
|
901
976
|
`, Parser_1.ParseMode.BrighterScript);
|
|
902
|
-
(0,
|
|
903
|
-
(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);
|
|
904
979
|
});
|
|
905
980
|
});
|
|
906
981
|
describe('Annotations', () => {
|
|
@@ -911,7 +986,7 @@ describe('parser', () => {
|
|
|
911
986
|
sub main()
|
|
912
987
|
end sub
|
|
913
988
|
`, Parser_1.ParseMode.BrighterScript);
|
|
914
|
-
(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);
|
|
915
990
|
});
|
|
916
991
|
it('properly handles empty annotation above class method', () => {
|
|
917
992
|
var _a;
|
|
@@ -923,7 +998,7 @@ describe('parser', () => {
|
|
|
923
998
|
end sub
|
|
924
999
|
end class
|
|
925
1000
|
`, Parser_1.ParseMode.BrighterScript);
|
|
926
|
-
(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);
|
|
927
1002
|
});
|
|
928
1003
|
it('parses with error if annotation is not followed by a statement', () => {
|
|
929
1004
|
var _a, _b, _c, _d;
|
|
@@ -937,11 +1012,11 @@ describe('parser', () => {
|
|
|
937
1012
|
end class
|
|
938
1013
|
@meta1
|
|
939
1014
|
`, Parser_1.ParseMode.BrighterScript);
|
|
940
|
-
(0,
|
|
941
|
-
(0,
|
|
942
|
-
(0,
|
|
943
|
-
(0,
|
|
944
|
-
(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);
|
|
945
1020
|
});
|
|
946
1021
|
it('attaches an annotation to next statement', () => {
|
|
947
1022
|
var _a;
|
|
@@ -953,18 +1028,18 @@ describe('parser', () => {
|
|
|
953
1028
|
@meta2 sub init()
|
|
954
1029
|
end sub
|
|
955
1030
|
`, Parser_1.ParseMode.BrighterScript);
|
|
956
|
-
(0,
|
|
957
|
-
(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);
|
|
958
1033
|
let fn = statements[0];
|
|
959
|
-
(0,
|
|
960
|
-
(0,
|
|
961
|
-
(0,
|
|
962
|
-
(0,
|
|
963
|
-
(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);
|
|
964
1039
|
fn = statements[1];
|
|
965
|
-
(0,
|
|
966
|
-
(0,
|
|
967
|
-
(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');
|
|
968
1043
|
});
|
|
969
1044
|
it('attaches annotations inside a function body', () => {
|
|
970
1045
|
var _a, _b;
|
|
@@ -974,13 +1049,13 @@ describe('parser', () => {
|
|
|
974
1049
|
print "hello"
|
|
975
1050
|
end function
|
|
976
1051
|
`, Parser_1.ParseMode.BrighterScript);
|
|
977
|
-
(0,
|
|
1052
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
978
1053
|
let fn = statements[0];
|
|
979
1054
|
let fnStatements = fn.func.body.statements;
|
|
980
1055
|
let stat = fnStatements[0];
|
|
981
|
-
(0,
|
|
982
|
-
(0,
|
|
983
|
-
(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);
|
|
984
1059
|
});
|
|
985
1060
|
it('attaches multiple annotations to next statement', () => {
|
|
986
1061
|
var _a;
|
|
@@ -990,14 +1065,14 @@ describe('parser', () => {
|
|
|
990
1065
|
function main()
|
|
991
1066
|
end function
|
|
992
1067
|
`, Parser_1.ParseMode.BrighterScript);
|
|
993
|
-
(0,
|
|
994
|
-
(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);
|
|
995
1070
|
let fn = statements[0];
|
|
996
|
-
(0,
|
|
997
|
-
(0,
|
|
998
|
-
(0,
|
|
999
|
-
(0,
|
|
1000
|
-
(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);
|
|
1001
1076
|
});
|
|
1002
1077
|
it('allows annotations with parameters', () => {
|
|
1003
1078
|
var _a;
|
|
@@ -1006,12 +1081,12 @@ describe('parser', () => {
|
|
|
1006
1081
|
function main()
|
|
1007
1082
|
end function
|
|
1008
1083
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1009
|
-
(0,
|
|
1084
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1010
1085
|
let fn = statements[0];
|
|
1011
|
-
(0,
|
|
1012
|
-
(0,
|
|
1013
|
-
(0,
|
|
1014
|
-
(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);
|
|
1015
1090
|
});
|
|
1016
1091
|
it('attaches annotations to a class', () => {
|
|
1017
1092
|
var _a, _b;
|
|
@@ -1023,10 +1098,10 @@ describe('parser', () => {
|
|
|
1023
1098
|
end function
|
|
1024
1099
|
end class
|
|
1025
1100
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1026
|
-
(0,
|
|
1101
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1027
1102
|
let cs = statements[0];
|
|
1028
|
-
(0,
|
|
1029
|
-
(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);
|
|
1030
1105
|
});
|
|
1031
1106
|
it('attaches annotations to multiple clases', () => {
|
|
1032
1107
|
var _a, _b, _c;
|
|
@@ -1044,15 +1119,15 @@ describe('parser', () => {
|
|
|
1044
1119
|
end function
|
|
1045
1120
|
end class
|
|
1046
1121
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1047
|
-
(0,
|
|
1122
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1048
1123
|
let cs = statements[0];
|
|
1049
|
-
(0,
|
|
1050
|
-
(0,
|
|
1051
|
-
(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');
|
|
1052
1127
|
let cs2 = statements[1];
|
|
1053
|
-
(0,
|
|
1054
|
-
(0,
|
|
1055
|
-
(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');
|
|
1056
1131
|
});
|
|
1057
1132
|
it('attaches annotations to a namespaced class', () => {
|
|
1058
1133
|
var _a, _b;
|
|
@@ -1066,11 +1141,11 @@ describe('parser', () => {
|
|
|
1066
1141
|
end class
|
|
1067
1142
|
end namespace
|
|
1068
1143
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1069
|
-
(0,
|
|
1144
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1070
1145
|
let ns = statements[0];
|
|
1071
1146
|
let cs = ns.body.statements[0];
|
|
1072
|
-
(0,
|
|
1073
|
-
(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);
|
|
1074
1149
|
});
|
|
1075
1150
|
it('attaches annotations to a namespaced class - multiple', () => {
|
|
1076
1151
|
var _a, _b, _c;
|
|
@@ -1090,16 +1165,16 @@ describe('parser', () => {
|
|
|
1090
1165
|
end class
|
|
1091
1166
|
end namespace
|
|
1092
1167
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1093
|
-
(0,
|
|
1168
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1094
1169
|
let ns = statements[0];
|
|
1095
1170
|
let cs = ns.body.statements[0];
|
|
1096
|
-
(0,
|
|
1097
|
-
(0,
|
|
1098
|
-
(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');
|
|
1099
1174
|
let cs2 = ns.body.statements[1];
|
|
1100
|
-
(0,
|
|
1101
|
-
(0,
|
|
1102
|
-
(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');
|
|
1103
1178
|
});
|
|
1104
1179
|
it('attaches annotations to a class constructor', () => {
|
|
1105
1180
|
var _a, _b;
|
|
@@ -1114,11 +1189,11 @@ describe('parser', () => {
|
|
|
1114
1189
|
end function
|
|
1115
1190
|
end class
|
|
1116
1191
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1117
|
-
(0,
|
|
1192
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1118
1193
|
let cs = statements[0];
|
|
1119
1194
|
let stat = cs.body[0];
|
|
1120
|
-
(0,
|
|
1121
|
-
(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);
|
|
1122
1197
|
});
|
|
1123
1198
|
it('attaches annotations to a class methods', () => {
|
|
1124
1199
|
var _a, _b;
|
|
@@ -1133,11 +1208,11 @@ describe('parser', () => {
|
|
|
1133
1208
|
end function
|
|
1134
1209
|
end class
|
|
1135
1210
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1136
|
-
(0,
|
|
1211
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1137
1212
|
let cs = statements[0];
|
|
1138
1213
|
let stat = cs.body[1];
|
|
1139
|
-
(0,
|
|
1140
|
-
(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);
|
|
1141
1216
|
});
|
|
1142
1217
|
it('attaches annotations to a class methods, fields and constructor', () => {
|
|
1143
1218
|
var _a, _b, _c, _d, _e;
|
|
@@ -1161,19 +1236,19 @@ describe('parser', () => {
|
|
|
1161
1236
|
public foo="bar"
|
|
1162
1237
|
end class
|
|
1163
1238
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1164
|
-
(0,
|
|
1239
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1165
1240
|
let cs = statements[0];
|
|
1166
|
-
(0,
|
|
1167
|
-
(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);
|
|
1168
1243
|
let stat1 = cs.body[0];
|
|
1169
1244
|
let stat2 = cs.body[1];
|
|
1170
1245
|
let f1 = cs.body[2];
|
|
1171
|
-
(0,
|
|
1172
|
-
(0,
|
|
1173
|
-
(0,
|
|
1174
|
-
(0,
|
|
1175
|
-
(0,
|
|
1176
|
-
(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);
|
|
1177
1252
|
});
|
|
1178
1253
|
it('ignores annotations on commented out lines', () => {
|
|
1179
1254
|
var _a;
|
|
@@ -1184,9 +1259,9 @@ describe('parser', () => {
|
|
|
1184
1259
|
print "hello"
|
|
1185
1260
|
end function
|
|
1186
1261
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1187
|
-
(0,
|
|
1262
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1188
1263
|
let cs = statements[0];
|
|
1189
|
-
(0,
|
|
1264
|
+
(0, chai_config_spec_1.expect)(cs.annotations).to.be.undefined;
|
|
1190
1265
|
});
|
|
1191
1266
|
it('can convert argument of an annotation to JS types', () => {
|
|
1192
1267
|
var _a;
|
|
@@ -1204,22 +1279,22 @@ describe('parser', () => {
|
|
|
1204
1279
|
sub init()
|
|
1205
1280
|
end sub
|
|
1206
1281
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1207
|
-
(0,
|
|
1208
|
-
(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);
|
|
1209
1284
|
let fn = statements[0];
|
|
1210
|
-
(0,
|
|
1211
|
-
(0,
|
|
1212
|
-
(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);
|
|
1213
1288
|
fn = statements[1];
|
|
1214
|
-
(0,
|
|
1215
|
-
(0,
|
|
1216
|
-
(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([
|
|
1217
1292
|
'arg', 2, true,
|
|
1218
1293
|
{ prop: 'value' }, [1, 2],
|
|
1219
1294
|
null
|
|
1220
1295
|
]);
|
|
1221
1296
|
let allArgs = fn.annotations[0].getArguments(false);
|
|
1222
|
-
(0,
|
|
1297
|
+
(0, chai_config_spec_1.expect)(allArgs.pop()).to.be.instanceOf(Expression_1.FunctionExpression);
|
|
1223
1298
|
});
|
|
1224
1299
|
it('can handle negative numbers', () => {
|
|
1225
1300
|
var _a;
|
|
@@ -1231,424 +1306,577 @@ describe('parser', () => {
|
|
|
1231
1306
|
sub init()
|
|
1232
1307
|
end sub
|
|
1233
1308
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1234
|
-
(0,
|
|
1235
|
-
(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);
|
|
1236
1311
|
let fn = statements[0];
|
|
1237
|
-
(0,
|
|
1238
|
-
(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]);
|
|
1239
1314
|
});
|
|
1240
1315
|
});
|
|
1241
|
-
describe('
|
|
1242
|
-
it('
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
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))
|
|
1248
1322
|
end sub
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
const type = (0, Parser_1.getBscTypeFromExpression)(func.body.statements[0].value, func);
|
|
1252
|
-
(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);
|
|
1253
1325
|
});
|
|
1254
|
-
it('
|
|
1255
|
-
|
|
1326
|
+
it('allows type casts after function calls', () => {
|
|
1327
|
+
var _a;
|
|
1328
|
+
let { statements, diagnostics } = parse(`
|
|
1256
1329
|
sub main()
|
|
1257
|
-
|
|
1258
|
-
return "hello"
|
|
1259
|
-
end sub
|
|
1330
|
+
value = getValue() as integer
|
|
1260
1331
|
end sub
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
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(`
|
|
1268
1350
|
sub main()
|
|
1269
|
-
|
|
1270
|
-
return new Person()
|
|
1271
|
-
end sub
|
|
1351
|
+
value = (getValue() as integer).toStr()
|
|
1272
1352
|
end sub
|
|
1273
1353
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1354
|
+
function getValue()
|
|
1355
|
+
return 123
|
|
1356
|
+
end function
|
|
1276
1357
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1277
|
-
(0,
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
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(`
|
|
1285
1374
|
sub main()
|
|
1286
|
-
|
|
1287
|
-
return [1,2,3]
|
|
1288
|
-
end sub
|
|
1375
|
+
print cos(getAngle() as float)
|
|
1289
1376
|
end sub
|
|
1377
|
+
|
|
1378
|
+
function getAngle()
|
|
1379
|
+
return 123
|
|
1380
|
+
end function
|
|
1290
1381
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1291
|
-
(0,
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
(0,
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
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(`
|
|
1301
1398
|
sub main()
|
|
1302
|
-
|
|
1303
|
-
someString = "hello world"
|
|
1304
|
-
someObj = {foo: "bar"}
|
|
1305
|
-
someCustom = new CustomKlass()
|
|
1399
|
+
print getData() as dynamic as float as string
|
|
1306
1400
|
end sub
|
|
1307
|
-
|
|
1308
|
-
class CustomKlass
|
|
1309
|
-
end class
|
|
1310
1401
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1311
|
-
(0,
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
(0,
|
|
1315
|
-
|
|
1316
|
-
(0,
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
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)
|
|
1322
1417
|
end sub
|
|
1323
1418
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1324
|
-
(0,
|
|
1325
|
-
const someFuncSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1326
|
-
(0, chai_1.expect)(someFuncSymbolTable.getSymbolType('param1')).to.be.instanceof(StringType_1.StringType);
|
|
1327
|
-
(0, chai_1.expect)(someFuncSymbolTable.getSymbolType('param2')).to.be.instanceof(IntegerType_1.IntegerType);
|
|
1328
|
-
(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;
|
|
1329
1420
|
});
|
|
1330
|
-
it('
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
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)
|
|
1334
1426
|
end sub
|
|
1335
|
-
|
|
1336
|
-
function foo() as string
|
|
1337
|
-
return "foo"
|
|
1338
|
-
end function
|
|
1339
1427
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1340
|
-
(0,
|
|
1341
|
-
const someFuncSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1342
|
-
(0, chai_1.expect)((0, reflection_1.isLazyType)(someFuncSymbolTable.getSymbol('temp')[0].type)).to.be.true;
|
|
1343
|
-
(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;
|
|
1344
1429
|
});
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
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
|
|
1352
1436
|
end sub
|
|
1353
|
-
`, Parser_1.ParseMode.
|
|
1354
|
-
(0, testHelpers_spec_1.
|
|
1355
|
-
const addOneSymbolTable = parser.references.functionExpressions[0].childFunctionExpressions[0].symbolTable;
|
|
1356
|
-
(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()]);
|
|
1357
1439
|
});
|
|
1358
|
-
it('
|
|
1359
|
-
|
|
1360
|
-
sub
|
|
1440
|
+
it('allows union types in parameters', () => {
|
|
1441
|
+
let { diagnostics } = parse(`
|
|
1442
|
+
sub main(param as string or integer)
|
|
1443
|
+
print param
|
|
1361
1444
|
end sub
|
|
1362
1445
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1363
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(
|
|
1364
|
-
(0, testHelpers_spec_1.expectSymbolTableEquals)(parser.references.functionExpressions[0].symbolTable, [
|
|
1365
|
-
['p1', new DynamicType_1.DynamicType(), util_1.util.createRange(1, 26, 1, 28)],
|
|
1366
|
-
['p2', new StringType_1.StringType(), util_1.util.createRange(1, 30, 1, 32)],
|
|
1367
|
-
['p3', new IntegerType_1.IntegerType(), util_1.util.createRange(1, 44, 1, 46)]
|
|
1368
|
-
]);
|
|
1446
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1369
1447
|
});
|
|
1370
|
-
it('
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
const wordArraySymbolType = symbolTable.getSymbolType('words');
|
|
1379
|
-
(0, chai_1.expect)((0, reflection_1.isArrayType)(numArraySymbolType)).to.be.true;
|
|
1380
|
-
(0, chai_1.expect)((0, reflection_1.isIntegerType)(numArraySymbolType.getDefaultType())).to.be.true;
|
|
1381
|
-
(0, chai_1.expect)((0, reflection_1.isArrayType)(wordArraySymbolType)).to.be.true;
|
|
1382
|
-
(0, chai_1.expect)((0, reflection_1.isStringType)(wordArraySymbolType.getDefaultType())).to.be.true;
|
|
1383
|
-
const funcReturnType = parser.references.functionExpressions[0].getReturnType();
|
|
1384
|
-
(0, chai_1.expect)((0, reflection_1.isArrayType)(funcReturnType)).to.be.true;
|
|
1385
|
-
(0, chai_1.expect)((0, reflection_1.isFloatType)(funcReturnType.getDefaultType())).to.be.true;
|
|
1386
|
-
});
|
|
1387
|
-
it('finds multidimensional arrays', () => {
|
|
1388
|
-
const parser = parse(`
|
|
1389
|
-
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)
|
|
1452
|
+
end sub
|
|
1453
|
+
|
|
1454
|
+
sub printThing(thing as string or integer)
|
|
1455
|
+
print thing
|
|
1390
1456
|
end sub
|
|
1391
1457
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1392
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1458
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1459
|
+
});
|
|
1460
|
+
});
|
|
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
|
|
1466
|
+
end sub
|
|
1467
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1468
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typed arrays')]);
|
|
1469
|
+
});
|
|
1470
|
+
it('is allowed in brighterscript mode', () => {
|
|
1471
|
+
let { statements, diagnostics } = parse(`
|
|
1472
|
+
sub main(things as string[])
|
|
1473
|
+
print things
|
|
1402
1474
|
end sub
|
|
1403
1475
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1404
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(
|
|
1405
|
-
const
|
|
1406
|
-
|
|
1407
|
-
(0,
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
sub main()
|
|
1414
|
-
for i = 0 to 10 step 10
|
|
1415
|
-
print i
|
|
1416
|
-
end for
|
|
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);
|
|
1480
|
+
});
|
|
1481
|
+
it('allows multi dimensional arrays', () => {
|
|
1482
|
+
let { statements, diagnostics } = parse(`
|
|
1483
|
+
sub main(things as string[][])
|
|
1484
|
+
print things
|
|
1417
1485
|
end sub
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
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);
|
|
1492
|
+
});
|
|
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
|
|
1429
1508
|
end sub
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
const parser = parse(`
|
|
1437
|
-
sub doLoop()
|
|
1438
|
-
someData = [1,2,3]
|
|
1439
|
-
for each datum in someData
|
|
1440
|
-
print datum
|
|
1441
|
-
end for
|
|
1442
|
-
end sub
|
|
1443
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1444
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
|
|
1445
|
-
const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1446
|
-
(0, chai_1.expect)((0, reflection_1.isIntegerType)(currentSymbolTable.getSymbolType('datum'))).to.be.true;
|
|
1447
|
-
});
|
|
1448
|
-
it('determines the type of the variable in a for each if the target is an array', () => {
|
|
1449
|
-
const parser = parse(`
|
|
1450
|
-
sub doLoop(someData as integer[])
|
|
1451
|
-
for each datum in someData
|
|
1452
|
-
print datum
|
|
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('datum'))).to.be.true;
|
|
1459
|
-
});
|
|
1460
|
-
it('determines the type of the variable in a for each if the target is an array of some custom type', () => {
|
|
1461
|
-
const parser = parse(`
|
|
1462
|
-
sub doLoop(someData as MyKlass[])
|
|
1463
|
-
for each datum in someData
|
|
1464
|
-
print datum.name
|
|
1465
|
-
end for
|
|
1466
|
-
end sub
|
|
1467
|
-
|
|
1468
|
-
class MyKlass
|
|
1469
|
-
name as string
|
|
1470
|
-
end class
|
|
1471
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1472
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
|
|
1473
|
-
const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1474
|
-
(0, chai_1.expect)((0, reflection_1.isLazyType)(currentSymbolTable.getSymbol('datum')[0].type)).to.be.true;
|
|
1475
|
-
});
|
|
1476
|
-
it('determines the type of the variable in a for each if the target is a multidimensional array', () => {
|
|
1477
|
-
const parser = parse(`
|
|
1478
|
-
sub doLoop(data as float[][])
|
|
1479
|
-
for each row in data
|
|
1480
|
-
for each item in row
|
|
1481
|
-
print item
|
|
1482
|
-
end for
|
|
1483
|
-
end for
|
|
1484
|
-
end sub
|
|
1485
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1486
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
|
|
1487
|
-
const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1488
|
-
(0, chai_1.expect)((0, reflection_1.isArrayType)(currentSymbolTable.getSymbol('row')[0].type)).to.be.true;
|
|
1489
|
-
(0, chai_1.expect)((0, reflection_1.isFloatType)(currentSymbolTable.getSymbol('item')[0].type)).to.be.true;
|
|
1490
|
-
});
|
|
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;
|
|
1491
1515
|
});
|
|
1492
1516
|
});
|
|
1493
|
-
describe('
|
|
1494
|
-
it('
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
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
|
|
1499
1527
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
sub someFunc()
|
|
1510
|
-
print var.field.funcCall().childField
|
|
1511
|
-
end sub
|
|
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
|
|
1512
1537
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
print var.field.funcCall(1, "string", {key: value}).childField
|
|
1524
|
-
end sub
|
|
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
|
|
1525
1548
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
(0,
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
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
|
|
1538
1564
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
(0,
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
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
|
|
1551
1581
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
(0,
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
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
|
|
1564
1600
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
(0,
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
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
|
|
1574
1615
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
(0,
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
const
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
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
|
|
1584
1649
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
(0,
|
|
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));
|
|
1588
1660
|
});
|
|
1589
1661
|
});
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
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
|
|
1669
|
+
`);
|
|
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")
|
|
1681
|
+
end sub
|
|
1682
|
+
`);
|
|
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
|
|
1598
1694
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
(
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
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")
|
|
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
|
+
});
|
|
1631
1813
|
});
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
(
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
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
|
|
1820
|
+
`);
|
|
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
|
|
1832
|
+
`);
|
|
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
|
|
1872
|
+
`);
|
|
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;
|
|
1879
|
+
});
|
|
1652
1880
|
});
|
|
1653
1881
|
});
|
|
1654
1882
|
function parse(text, mode) {
|
|
@@ -1657,6 +1885,7 @@ function parse(text, mode) {
|
|
|
1657
1885
|
mode: mode
|
|
1658
1886
|
});
|
|
1659
1887
|
}
|
|
1888
|
+
exports.parse = parse;
|
|
1660
1889
|
function rangeToArray(range) {
|
|
1661
1890
|
return [
|
|
1662
1891
|
range.start.line,
|
|
@@ -1668,14 +1897,14 @@ function rangeToArray(range) {
|
|
|
1668
1897
|
exports.rangeToArray = rangeToArray;
|
|
1669
1898
|
function expectCommentWithText(stat, text) {
|
|
1670
1899
|
if ((0, reflection_1.isCommentStatement)(stat)) {
|
|
1671
|
-
(0,
|
|
1900
|
+
(0, chai_config_spec_1.expect)(stat.text).to.equal(text);
|
|
1672
1901
|
}
|
|
1673
1902
|
else {
|
|
1674
1903
|
failStatementType(stat, 'Comment');
|
|
1675
1904
|
}
|
|
1676
1905
|
}
|
|
1677
1906
|
function failStatementType(stat, type) {
|
|
1678
|
-
|
|
1907
|
+
chai_config_spec_1.assert.fail(`Statement ${stat.constructor.name} line ${stat.range.start.line} is not a ${type}`);
|
|
1679
1908
|
}
|
|
1680
1909
|
exports.failStatementType = failStatementType;
|
|
1681
1910
|
//# sourceMappingURL=Parser.spec.js.map
|