brighterscript 1.0.0-alpha.3 → 1.0.0-alpha.31
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 +1249 -285
- package/README.md +61 -131
- package/bsconfig.schema.json +68 -2
- 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 +42 -0
- package/dist/AstValidationSegmenter.js +232 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +51 -6
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.d.ts +5 -6
- package/dist/Cache.js +12 -11
- 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 +11 -2
- package/dist/CodeActionUtil.js +17 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +7 -6
- package/dist/CommentFlagProcessor.js +10 -7
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/CrossScopeValidator.d.ts +67 -0
- package/dist/CrossScopeValidator.js +625 -0
- package/dist/CrossScopeValidator.js.map +1 -0
- package/dist/DependencyGraph.d.ts +8 -3
- package/dist/DependencyGraph.js +49 -16
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.d.ts +5 -3
- package/dist/DiagnosticCollection.js +18 -16
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +8 -4
- package/dist/DiagnosticFilterer.js +77 -44
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticManager.d.ts +56 -0
- package/dist/DiagnosticManager.js +218 -0
- package/dist/DiagnosticManager.js.map +1 -0
- package/dist/DiagnosticMessages.d.ts +187 -20
- package/dist/DiagnosticMessages.js +247 -29
- 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 +72 -47
- package/dist/LanguageServer.js +544 -312
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +9 -10
- package/dist/Logger.js +36 -30
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +29 -7
- package/dist/PluginInterface.js +90 -7
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +199 -100
- package/dist/Program.js +1056 -700
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +29 -18
- package/dist/ProgramBuilder.js +170 -132
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +144 -109
- package/dist/Scope.js +533 -552
- package/dist/Scope.js.map +1 -1
- package/dist/SemanticTokenUtils.d.ts +14 -0
- package/dist/SemanticTokenUtils.js +85 -0
- package/dist/SemanticTokenUtils.js.map +1 -0
- package/dist/Stopwatch.d.ts +4 -0
- package/dist/Stopwatch.js +8 -1
- package/dist/Stopwatch.js.map +1 -1
- package/dist/SymbolTable.d.ts +91 -24
- package/dist/SymbolTable.js +290 -64
- package/dist/SymbolTable.js.map +1 -1
- package/dist/SymbolTypeFlag.d.ts +9 -0
- package/dist/SymbolTypeFlag.js +14 -0
- package/dist/SymbolTypeFlag.js.map +1 -0
- 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 +5 -15
- package/dist/XmlScope.js +35 -87
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +50 -0
- package/dist/astUtils/CachedLookups.js +331 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/Editor.d.ts +69 -0
- package/dist/astUtils/Editor.js +245 -0
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/Editor.spec.js +258 -0
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +33 -10
- package/dist/astUtils/creators.js +224 -30
- 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 +146 -82
- package/dist/astUtils/reflection.js +308 -132
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +267 -162
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +14 -14
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +115 -53
- package/dist/astUtils/visitors.js +70 -13
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +465 -51
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -8
- package/dist/astUtils/xml.js +10 -5
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +22 -1
- package/dist/bscPlugin/BscPlugin.js +88 -0
- 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 +137 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +26 -17
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +94 -20
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +60 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js +601 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +2139 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js +210 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js +88 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
- package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +18 -0
- package/dist/bscPlugin/hover/HoverProcessor.js +218 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +737 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
- package/dist/bscPlugin/references/ReferencesProvider.js +56 -0
- package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +14 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +144 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +504 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
- 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/symbols/DocumentSymbolProcessor.d.ts +7 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js +22 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js.map +1 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +291 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.d.ts +7 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js +26 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js.map +1 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +245 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/symbols/symbolUtils.d.ts +5 -0
- package/dist/bscPlugin/symbols/symbolUtils.js +140 -0
- package/dist/bscPlugin/symbols/symbolUtils.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +21 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +199 -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/BrsFileAfterValidator.d.ts +7 -0
- package/dist/bscPlugin/validation/BrsFileAfterValidator.js +18 -0
- package/dist/bscPlugin/validation/BrsFileAfterValidator.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +34 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +462 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +758 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/ProgramValidator.d.ts +11 -0
- package/dist/bscPlugin/validation/ProgramValidator.js +33 -0
- package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +123 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +1026 -0
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2897 -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 +117 -11
- 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 +10 -3
- package/dist/diagnosticUtils.js +58 -21
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +8 -12
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +24 -0
- package/dist/files/AssetFile.js +25 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +858 -153
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +147 -82
- package/dist/files/BrsFile.js +853 -911
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +3056 -836
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +101 -0
- package/dist/files/BscFile.js +15 -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 +73 -41
- package/dist/files/XmlFile.js +126 -138
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +450 -318
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +62 -52
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.d.ts +1 -0
- package/dist/files/tests/optionalChaning.spec.js +152 -0
- package/dist/files/tests/optionalChaning.spec.js.map +1 -0
- package/dist/globalCallables.d.ts +3 -1
- package/dist/globalCallables.js +416 -162
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +25 -3
- package/dist/index.js +42 -5
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +717 -119
- package/dist/interfaces.js +21 -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 +40 -9
- package/dist/lexer/Lexer.js +191 -49
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +775 -563
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +11 -3
- package/dist/lexer/Token.js +10 -2
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +27 -1
- package/dist/lexer/TokenKind.js +112 -5
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/logging.d.ts +9 -0
- package/dist/logging.js +16 -0
- package/dist/logging.js.map +1 -0
- package/dist/parser/AstNode.d.ts +181 -0
- package/dist/parser/AstNode.js +246 -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 +12 -2
- package/dist/parser/BrsTranspileState.js +6 -0
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +454 -210
- package/dist/parser/Expression.js +953 -498
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +200 -95
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +106 -120
- package/dist/parser/Parser.js +1432 -931
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +1383 -456
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +44 -6
- package/dist/parser/SGParser.js +212 -185
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +30 -28
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +293 -50
- package/dist/parser/SGTypes.js +540 -187
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +759 -247
- package/dist/parser/Statement.js +1785 -607
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +45 -34
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +18 -8
- package/dist/parser/TranspileState.js +76 -12
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.d.ts +10 -9
- package/dist/parser/tests/Parser.spec.js +18 -14
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +79 -69
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +53 -47
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +217 -196
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +48 -42
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +31 -31
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +157 -120
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +202 -139
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +25 -25
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +150 -41
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +18 -18
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +257 -257
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +160 -90
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +38 -38
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +196 -98
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +42 -42
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +42 -42
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +171 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/Relational.spec.js +44 -44
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +31 -31
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +230 -90
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +377 -148
- 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 +126 -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 +37 -37
- 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 +45 -45
- 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.d.ts +1 -0
- package/dist/parser/tests/statement/Enum.spec.js +745 -0
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
- package/dist/parser/tests/statement/For.spec.d.ts +1 -0
- package/dist/parser/tests/statement/For.spec.js +45 -0
- package/dist/parser/tests/statement/For.spec.js.map +1 -0
- package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ForEach.spec.js +36 -0
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
- package/dist/parser/tests/statement/Function.spec.js +208 -198
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +16 -15
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +51 -51
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +110 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/LibraryStatement.spec.js +18 -18
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +123 -163
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +125 -108
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +51 -49
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +110 -97
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +13 -12
- 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 +26 -15
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +6 -6
- package/dist/preprocessor/Manifest.js +17 -38
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/preprocessor/Manifest.spec.d.ts +1 -0
- package/dist/preprocessor/Manifest.spec.js +78 -103
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/roku-types/data.json +19369 -0
- package/dist/roku-types/index.d.ts +5497 -0
- package/dist/roku-types/index.js +11 -0
- package/dist/roku-types/index.js.map +1 -0
- package/dist/types/ArrayType.d.ts +9 -5
- package/dist/types/ArrayType.js +68 -24
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +39 -11
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +14 -0
- package/dist/types/AssociativeArrayType.js +60 -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 +10 -5
- package/dist/types/BooleanType.js +21 -9
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +10 -4
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +29 -3
- package/dist/types/BscType.js +121 -0
- 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 +25 -0
- package/dist/types/BuiltInInterfaceAdder.js +201 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +115 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
- package/dist/types/ClassType.d.ts +16 -0
- package/dist/types/ClassType.js +57 -0
- package/dist/types/ClassType.js.map +1 -0
- package/dist/types/ClassType.spec.d.ts +1 -0
- package/dist/types/ClassType.spec.js +76 -0
- package/dist/types/ClassType.spec.js.map +1 -0
- package/dist/types/ComponentType.d.ts +27 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +10 -5
- package/dist/types/DoubleType.js +25 -18
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +12 -4
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +12 -5
- package/dist/types/DynamicType.js +22 -6
- 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 +40 -0
- package/dist/types/EnumType.js +80 -0
- package/dist/types/EnumType.js.map +1 -0
- 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 +10 -5
- package/dist/types/FloatType.js +25 -18
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -4
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +10 -22
- package/dist/types/FunctionType.js +26 -63
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +28 -0
- package/dist/types/InheritableType.js +157 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +10 -5
- package/dist/types/IntegerType.js +25 -18
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +8 -4
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +14 -6
- package/dist/types/InterfaceType.js +26 -15
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.d.ts +1 -0
- package/dist/types/InterfaceType.spec.js +227 -0
- package/dist/types/InterfaceType.spec.js.map +1 -0
- package/dist/types/InvalidType.d.ts +9 -5
- package/dist/types/InvalidType.js +20 -9
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +8 -4
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +10 -5
- package/dist/types/LongIntegerType.js +25 -18
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +10 -4
- 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 +10 -5
- package/dist/types/ObjectType.js +23 -9
- 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 +79 -0
- package/dist/types/ReferenceType.js +522 -0
- package/dist/types/ReferenceType.js.map +1 -0
- package/dist/types/ReferenceType.spec.d.ts +1 -0
- package/dist/types/ReferenceType.spec.js +151 -0
- package/dist/types/ReferenceType.spec.js.map +1 -0
- package/dist/types/StringType.d.ts +13 -5
- package/dist/types/StringType.js +25 -9
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +3 -3
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +33 -0
- package/dist/types/TypedFunctionType.js +106 -0
- package/dist/types/TypedFunctionType.js.map +1 -0
- package/dist/types/TypedFunctionType.spec.d.ts +1 -0
- package/dist/types/TypedFunctionType.spec.js +122 -0
- package/dist/types/TypedFunctionType.spec.js.map +1 -0
- package/dist/types/UninitializedType.d.ts +8 -6
- package/dist/types/UninitializedType.js +15 -9
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +20 -0
- package/dist/types/UnionType.js +127 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +129 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +10 -5
- package/dist/types/VoidType.js +20 -9
- 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 +144 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +26 -0
- package/dist/types/helpers.js +191 -0
- package/dist/types/helpers.js.map +1 -0
- 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 +218 -106
- package/dist/util.js +1310 -320
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +9 -15
- package/dist/validators/ClassValidator.js +81 -134
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +169 -138
- package/dist/astUtils/index.d.ts +0 -7
- package/dist/astUtils/index.js +0 -26
- package/dist/astUtils/index.js.map +0 -1
- package/dist/lexer/index.d.ts +0 -3
- package/dist/lexer/index.js +0 -17
- package/dist/lexer/index.js.map +0 -1
- package/dist/parser/index.d.ts +0 -3
- package/dist/parser/index.js +0 -16
- package/dist/parser/index.js.map +0 -1
- package/dist/preprocessor/Chunk.d.ts +0 -82
- package/dist/preprocessor/Chunk.js +0 -77
- package/dist/preprocessor/Chunk.js.map +0 -1
- package/dist/preprocessor/Preprocessor.d.ts +0 -60
- package/dist/preprocessor/Preprocessor.js +0 -156
- package/dist/preprocessor/Preprocessor.js.map +0 -1
- package/dist/preprocessor/Preprocessor.spec.js +0 -152
- package/dist/preprocessor/Preprocessor.spec.js.map +0 -1
- package/dist/preprocessor/PreprocessorParser.d.ts +0 -61
- package/dist/preprocessor/PreprocessorParser.js +0 -194
- package/dist/preprocessor/PreprocessorParser.js.map +0 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +0 -116
- package/dist/preprocessor/PreprocessorParser.spec.js.map +0 -1
- package/dist/preprocessor/index.d.ts +0 -3
- package/dist/preprocessor/index.js +0 -16
- package/dist/preprocessor/index.js.map +0 -1
- package/dist/types/CustomType.d.ts +0 -10
- package/dist/types/CustomType.js +0 -35
- package/dist/types/CustomType.js.map +0 -1
- package/dist/types/FunctionType.spec.js +0 -29
- package/dist/types/FunctionType.spec.js.map +0 -1
- package/dist/types/LazyType.d.ts +0 -15
- package/dist/types/LazyType.js +0 -32
- package/dist/types/LazyType.js.map +0 -1
- /package/dist/{preprocessor/Preprocessor.spec.d.ts → astUtils/Editor.spec.d.ts} +0 -0
- /package/dist/{preprocessor/PreprocessorParser.spec.d.ts → bscPlugin/completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{types/FunctionType.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.failStatementType = exports.rangeToArray = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
3
|
+
exports.failStatementType = exports.rangeToArray = exports.parse = void 0;
|
|
4
|
+
const chai_config_spec_1 = require("../chai-config.spec");
|
|
5
|
+
const Lexer_1 = require("../lexer/Lexer");
|
|
6
|
+
const TokenKind_1 = require("../lexer/TokenKind");
|
|
6
7
|
const Expression_1 = require("./Expression");
|
|
7
8
|
const Parser_1 = require("./Parser");
|
|
8
9
|
const Statement_1 = require("./Statement");
|
|
@@ -10,97 +11,18 @@ const vscode_languageserver_1 = require("vscode-languageserver");
|
|
|
10
11
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
11
12
|
const reflection_1 = require("../astUtils/reflection");
|
|
12
13
|
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
13
|
-
const
|
|
14
|
-
const FunctionType_1 = require("../types/FunctionType");
|
|
15
|
-
const StringType_1 = require("../types/StringType");
|
|
16
|
-
const CustomType_1 = require("../types/CustomType");
|
|
14
|
+
const visitors_1 = require("../astUtils/visitors");
|
|
17
15
|
const IntegerType_1 = require("../types/IntegerType");
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const DynamicType_1 = require("../types/DynamicType");
|
|
22
|
-
const util_1 = require("../util");
|
|
16
|
+
const FloatType_1 = require("../types/FloatType");
|
|
17
|
+
const StringType_1 = require("../types/StringType");
|
|
18
|
+
const types_1 = require("../types");
|
|
23
19
|
describe('parser', () => {
|
|
24
20
|
it('emits empty object when empty token list is provided', () => {
|
|
25
|
-
|
|
21
|
+
(0, chai_config_spec_1.expect)(Parser_1.Parser.parse([])).to.deep.include({
|
|
26
22
|
statements: [],
|
|
27
23
|
diagnostics: []
|
|
28
24
|
});
|
|
29
25
|
});
|
|
30
|
-
describe('findReferences', () => {
|
|
31
|
-
it('recomputes localVars', () => {
|
|
32
|
-
const parser = Parser_1.Parser.parse(`
|
|
33
|
-
sub main(herd)
|
|
34
|
-
for each zombie in herd
|
|
35
|
-
isAlive = false
|
|
36
|
-
end for
|
|
37
|
-
for i = 0 to 10 step 1
|
|
38
|
-
j = i
|
|
39
|
-
end for
|
|
40
|
-
humansAreAlive = false
|
|
41
|
-
end sub
|
|
42
|
-
`);
|
|
43
|
-
chai_1.expect(parser.references.functionExpressions[0].symbolTable.ownSymbols.map(x => x.name).sort()).to.eql([
|
|
44
|
-
'herd',
|
|
45
|
-
'humansAreAlive',
|
|
46
|
-
'i',
|
|
47
|
-
'isAlive',
|
|
48
|
-
'j',
|
|
49
|
-
'zombie'
|
|
50
|
-
]);
|
|
51
|
-
parser.invalidateReferences();
|
|
52
|
-
chai_1.expect(parser.references.functionExpressions[0].symbolTable.ownSymbols.map(x => x.name).sort()).to.eql([
|
|
53
|
-
'herd',
|
|
54
|
-
'humansAreAlive',
|
|
55
|
-
'i',
|
|
56
|
-
'isAlive',
|
|
57
|
-
'j',
|
|
58
|
-
'zombie'
|
|
59
|
-
]);
|
|
60
|
-
});
|
|
61
|
-
it('assigns localVars to correct function expression bucket', () => {
|
|
62
|
-
const parser = Parser_1.Parser.parse(`
|
|
63
|
-
sub main()
|
|
64
|
-
outerName = "bob"
|
|
65
|
-
speak = sub()
|
|
66
|
-
innerName = "innerBob"
|
|
67
|
-
end sub
|
|
68
|
-
age = 12
|
|
69
|
-
end sub
|
|
70
|
-
`);
|
|
71
|
-
parser.invalidateReferences();
|
|
72
|
-
chai_1.expect(parser.references.functionExpressions[0].symbolTable.ownSymbols.map(x => x.name)).to.eql([
|
|
73
|
-
'outerName',
|
|
74
|
-
'speak',
|
|
75
|
-
'age'
|
|
76
|
-
]);
|
|
77
|
-
chai_1.expect(parser.references.functionExpressions[1].symbolTable.ownSymbols.map(x => x.name)).to.eql([
|
|
78
|
-
'innerName'
|
|
79
|
-
]);
|
|
80
|
-
});
|
|
81
|
-
it('gets called if references are missing', () => {
|
|
82
|
-
const parser = Parser_1.Parser.parse(`
|
|
83
|
-
sub main()
|
|
84
|
-
end sub
|
|
85
|
-
|
|
86
|
-
sub UnusedFunction()
|
|
87
|
-
end sub
|
|
88
|
-
`);
|
|
89
|
-
chai_1.expect(parser.references.functionStatements.map(x => x.name.text)).to.eql([
|
|
90
|
-
'main',
|
|
91
|
-
'UnusedFunction'
|
|
92
|
-
]);
|
|
93
|
-
//simulate a tree-shaking plugin by removing the `UnusedFunction`
|
|
94
|
-
parser.ast.statements.splice(1);
|
|
95
|
-
//tell the parser we modified the AST and need to regenerate references
|
|
96
|
-
parser.invalidateReferences();
|
|
97
|
-
chai_1.expect(parser['_references']).not.to.exist;
|
|
98
|
-
//calling `references` automatically regenerates the references
|
|
99
|
-
chai_1.expect(parser.references.functionStatements.map(x => x.name.text)).to.eql([
|
|
100
|
-
'main'
|
|
101
|
-
]);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
26
|
describe('callfunc operator', () => {
|
|
105
27
|
it('is not allowed in brightscript mode', () => {
|
|
106
28
|
var _a;
|
|
@@ -109,7 +31,7 @@ describe('parser', () => {
|
|
|
109
31
|
node@.doSomething(1, 2)
|
|
110
32
|
end sub
|
|
111
33
|
`, Parser_1.ParseMode.BrightScript);
|
|
112
|
-
|
|
34
|
+
(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);
|
|
113
35
|
});
|
|
114
36
|
it('does not cause parse errors', () => {
|
|
115
37
|
var _a, _b, _c, _d, _e;
|
|
@@ -118,13 +40,98 @@ describe('parser', () => {
|
|
|
118
40
|
node@.doSomething(1, 2)
|
|
119
41
|
end sub
|
|
120
42
|
`, Parser_1.ParseMode.BrighterScript);
|
|
121
|
-
|
|
122
|
-
|
|
43
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
44
|
+
(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);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('optional chaining operator', () => {
|
|
48
|
+
function getExpression(text, options) {
|
|
49
|
+
const parser = parse(text, options === null || options === void 0 ? void 0 : options.parseMode);
|
|
50
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
51
|
+
const expressions = parser.ast.findChildren(reflection_1.isExpression);
|
|
52
|
+
if (options === null || options === void 0 ? void 0 : options.matcher) {
|
|
53
|
+
return expressions.find(options.matcher);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return expressions[0];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
it('works for ?.', () => {
|
|
60
|
+
const expression = getExpression(`value = person?.name`);
|
|
61
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.DottedGetExpression);
|
|
62
|
+
(0, chai_config_spec_1.expect)(expression.tokens.dot.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
|
|
63
|
+
});
|
|
64
|
+
it('works for ?[', () => {
|
|
65
|
+
const expression = getExpression(`value = person?["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
66
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
|
|
67
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftSquare);
|
|
68
|
+
(0, chai_config_spec_1.expect)(expression.tokens.questionDot).not.to.exist;
|
|
69
|
+
});
|
|
70
|
+
it('works for ?.[', () => {
|
|
71
|
+
var _a;
|
|
72
|
+
const expression = getExpression(`value = person?.["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
73
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
|
|
74
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.LeftSquareBracket);
|
|
75
|
+
(0, chai_config_spec_1.expect)((_a = expression.tokens.questionDot) === null || _a === void 0 ? void 0 : _a.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
|
|
76
|
+
});
|
|
77
|
+
it('works for ?@', () => {
|
|
78
|
+
const expression = getExpression(`value = someXml?@someAttr`);
|
|
79
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.XmlAttributeGetExpression);
|
|
80
|
+
(0, chai_config_spec_1.expect)(expression.tokens.at.kind).to.eql(TokenKind_1.TokenKind.QuestionAt);
|
|
81
|
+
});
|
|
82
|
+
it('works for ?(', () => {
|
|
83
|
+
const expression = getExpression(`value = person.getName?()`);
|
|
84
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
|
|
85
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
86
|
+
});
|
|
87
|
+
it('works for print statements using question mark', () => {
|
|
88
|
+
const { statements } = parse(`
|
|
89
|
+
?[1]
|
|
90
|
+
?(1+1)
|
|
91
|
+
`);
|
|
92
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceOf(Statement_1.PrintStatement);
|
|
93
|
+
(0, chai_config_spec_1.expect)(statements[1]).to.be.instanceOf(Statement_1.PrintStatement);
|
|
94
|
+
});
|
|
95
|
+
//TODO enable this once we properly parse IIFEs
|
|
96
|
+
it.skip('works for ?( in anonymous function', () => {
|
|
97
|
+
const expression = getExpression(`thing = (function() : end function)?()`);
|
|
98
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
|
|
99
|
+
(0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
100
|
+
});
|
|
101
|
+
it('works for ?( in new call', () => {
|
|
102
|
+
const expression = getExpression(`thing = new Person?()`, { parseMode: Parser_1.ParseMode.BrighterScript });
|
|
103
|
+
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.NewExpression);
|
|
104
|
+
(0, chai_config_spec_1.expect)(expression.call.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
105
|
+
});
|
|
106
|
+
it('distinguishes between optional chaining and ternary expression', () => {
|
|
107
|
+
const parser = parse(`
|
|
108
|
+
sub main()
|
|
109
|
+
name = person?["name"]
|
|
110
|
+
isTrue = true
|
|
111
|
+
key = isTrue ? ["name"] : ["age"]
|
|
112
|
+
end sub
|
|
113
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
114
|
+
const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
|
|
115
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
|
|
116
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[2].value).is.instanceof(Expression_1.TernaryExpression);
|
|
117
|
+
});
|
|
118
|
+
it('distinguishes between optional chaining and ternary expression', () => {
|
|
119
|
+
const parser = parse(`
|
|
120
|
+
sub main()
|
|
121
|
+
'optional chain. the lack of whitespace between ? and [ matters
|
|
122
|
+
key = isTrue ?["name"] : getDefault()
|
|
123
|
+
'ternary
|
|
124
|
+
key = isTrue ? ["name"] : getDefault()
|
|
125
|
+
end sub
|
|
126
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
127
|
+
const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
|
|
128
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
|
|
129
|
+
(0, chai_config_spec_1.expect)(assignmentStatements[1].value).is.instanceof(Expression_1.TernaryExpression);
|
|
123
130
|
});
|
|
124
131
|
});
|
|
125
132
|
describe('diagnostic locations', () => {
|
|
126
133
|
it('tracks basic diagnostic locations', () => {
|
|
127
|
-
|
|
134
|
+
(0, chai_config_spec_1.expect)(parse(`
|
|
128
135
|
sub main()
|
|
129
136
|
call()a
|
|
130
137
|
end sub
|
|
@@ -140,8 +147,8 @@ describe('parser', () => {
|
|
|
140
147
|
return "6c5cdf1"
|
|
141
148
|
end functionasdf
|
|
142
149
|
`).diagnostics;
|
|
143
|
-
|
|
144
|
-
|
|
150
|
+
(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);
|
|
151
|
+
(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));
|
|
145
152
|
});
|
|
146
153
|
});
|
|
147
154
|
describe('parse', () => {
|
|
@@ -154,7 +161,7 @@ describe('parser', () => {
|
|
|
154
161
|
end function()
|
|
155
162
|
end sub
|
|
156
163
|
`);
|
|
157
|
-
testHelpers_spec_1.expectZeroDiagnostics(parser);
|
|
164
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
158
165
|
});
|
|
159
166
|
it('supports grouped iife in assignment', () => {
|
|
160
167
|
const parser = parse(`
|
|
@@ -165,7 +172,7 @@ describe('parser', () => {
|
|
|
165
172
|
end function)()
|
|
166
173
|
end sub
|
|
167
174
|
`);
|
|
168
|
-
testHelpers_spec_1.expectZeroDiagnostics(parser);
|
|
175
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
169
176
|
});
|
|
170
177
|
it('supports returning iife call', () => {
|
|
171
178
|
const parser = parse(`
|
|
@@ -174,24 +181,41 @@ describe('parser', () => {
|
|
|
174
181
|
end sub)()
|
|
175
182
|
end sub
|
|
176
183
|
`);
|
|
177
|
-
testHelpers_spec_1.expectZeroDiagnostics(parser);
|
|
184
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
178
185
|
});
|
|
179
186
|
it('supports using "interface" as parameter name', () => {
|
|
180
187
|
var _a;
|
|
181
|
-
|
|
188
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
182
189
|
sub main(interface as object)
|
|
183
190
|
end sub
|
|
184
191
|
`, Parser_1.ParseMode.BrighterScript).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
185
192
|
});
|
|
193
|
+
it('does not scrap the entire function when encountering unknown parameter type', () => {
|
|
194
|
+
const parser = parse(`
|
|
195
|
+
sub test(param1 as unknownType)
|
|
196
|
+
end sub
|
|
197
|
+
`);
|
|
198
|
+
// type validation happens at scope validation, not at the parser
|
|
199
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
200
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(parser.ast.statements[0])).to.be.true;
|
|
201
|
+
});
|
|
186
202
|
describe('namespace', () => {
|
|
187
|
-
it('
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
203
|
+
it('allows namespaces declared inside other namespaces', () => {
|
|
204
|
+
const parser = parse(`
|
|
205
|
+
namespace Level1
|
|
206
|
+
namespace Level2.Level3
|
|
207
|
+
sub main()
|
|
208
|
+
end sub
|
|
192
209
|
end namespace
|
|
193
|
-
end
|
|
194
|
-
`, Parser_1.ParseMode.BrighterScript)
|
|
210
|
+
end namespace
|
|
211
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
212
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
213
|
+
// We expect these names to be "as given" in this context, because we aren't evaluating a full program.
|
|
214
|
+
const namespaceStatements = parser.ast.findChildren(reflection_1.isNamespaceStatement);
|
|
215
|
+
(0, chai_config_spec_1.expect)(namespaceStatements.map(statement => statement.getName(Parser_1.ParseMode.BrighterScript))).to.have.deep.members([
|
|
216
|
+
'Level1.Level2.Level3',
|
|
217
|
+
'Level1'
|
|
218
|
+
]);
|
|
195
219
|
});
|
|
196
220
|
it('parses empty namespace', () => {
|
|
197
221
|
var _a;
|
|
@@ -199,8 +223,8 @@ describe('parser', () => {
|
|
|
199
223
|
namespace Name.Space
|
|
200
224
|
end namespace
|
|
201
225
|
`, Parser_1.ParseMode.BrighterScript);
|
|
202
|
-
|
|
203
|
-
|
|
226
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
227
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
204
228
|
});
|
|
205
229
|
it('includes body', () => {
|
|
206
230
|
var _a;
|
|
@@ -210,9 +234,9 @@ describe('parser', () => {
|
|
|
210
234
|
end sub
|
|
211
235
|
end namespace
|
|
212
236
|
`, Parser_1.ParseMode.BrighterScript);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
237
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
238
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
239
|
+
(0, chai_config_spec_1.expect)(statements[0].body.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
216
240
|
});
|
|
217
241
|
it('supports comments and newlines', () => {
|
|
218
242
|
var _a;
|
|
@@ -228,7 +252,7 @@ describe('parser', () => {
|
|
|
228
252
|
'comment
|
|
229
253
|
end namespace 'comment
|
|
230
254
|
`, Parser_1.ParseMode.BrighterScript);
|
|
231
|
-
|
|
255
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
232
256
|
});
|
|
233
257
|
it('catches missing name', () => {
|
|
234
258
|
var _a;
|
|
@@ -236,7 +260,7 @@ describe('parser', () => {
|
|
|
236
260
|
namespace
|
|
237
261
|
end namespace
|
|
238
262
|
`, Parser_1.ParseMode.BrighterScript);
|
|
239
|
-
|
|
263
|
+
(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);
|
|
240
264
|
});
|
|
241
265
|
it('recovers after missing `end namespace`', () => {
|
|
242
266
|
var _a, _b, _c;
|
|
@@ -245,9 +269,9 @@ describe('parser', () => {
|
|
|
245
269
|
sub main()
|
|
246
270
|
end sub
|
|
247
271
|
`, Parser_1.ParseMode.BrighterScript);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
272
|
+
(0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
273
|
+
(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);
|
|
274
|
+
(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);
|
|
251
275
|
});
|
|
252
276
|
it('adds diagnostic when encountering namespace in brightscript mode', () => {
|
|
253
277
|
var _a;
|
|
@@ -255,47 +279,12 @@ describe('parser', () => {
|
|
|
255
279
|
namespace Name.Space
|
|
256
280
|
end namespace
|
|
257
281
|
`);
|
|
258
|
-
|
|
259
|
-
});
|
|
260
|
-
it('declares a symbol table for the namespace', () => {
|
|
261
|
-
let parser = parse(`
|
|
262
|
-
namespace Name.Space
|
|
263
|
-
function funcInt() as integer
|
|
264
|
-
return 3
|
|
265
|
-
end function
|
|
266
|
-
|
|
267
|
-
function funcStr() as string
|
|
268
|
-
return "hello"
|
|
269
|
-
end function
|
|
270
|
-
end namespace
|
|
271
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
272
|
-
chai_1.expect(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
273
|
-
const namespaceStmt = parser.ast.statements[0];
|
|
274
|
-
chai_1.expect(namespaceStmt.symbolTable).to.be.instanceof(SymbolTable_1.SymbolTable);
|
|
275
|
-
chai_1.expect(namespaceStmt.symbolTable.getSymbolType('funcInt').toString()).to.equal('function funcInt() as integer');
|
|
276
|
-
chai_1.expect(namespaceStmt.symbolTable.getSymbolType('funcStr')).to.be.instanceof(FunctionType_1.FunctionType);
|
|
277
|
-
const strFunctionType = namespaceStmt.symbolTable.getSymbolType('funcStr');
|
|
278
|
-
chai_1.expect(strFunctionType.returnType.toString()).to.equal('string');
|
|
279
|
-
});
|
|
280
|
-
it('adds a fully qualified name of a function in a namespace to the parsers symbol table', () => {
|
|
281
|
-
let parser = parse(`
|
|
282
|
-
namespace Name.Space
|
|
283
|
-
function funcInt() as integer
|
|
284
|
-
return 3
|
|
285
|
-
end function
|
|
286
|
-
|
|
287
|
-
function funcStr() as string
|
|
288
|
-
return "hello"
|
|
289
|
-
end function
|
|
290
|
-
end namespace
|
|
291
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
292
|
-
chai_1.expect(parser.symbolTable.getSymbolType('Name.Space.funcInt')).to.be.instanceof(FunctionType_1.FunctionType);
|
|
293
|
-
chai_1.expect(parser.symbolTable.getSymbolType('Name.Space.funcStr')).to.be.instanceof(FunctionType_1.FunctionType);
|
|
282
|
+
(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);
|
|
294
283
|
});
|
|
295
284
|
});
|
|
296
285
|
it('supports << operator', () => {
|
|
297
286
|
var _a;
|
|
298
|
-
|
|
287
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
299
288
|
sub main()
|
|
300
289
|
print ((r << 24) + (g << 16) + (b << 8) + a)
|
|
301
290
|
end sub
|
|
@@ -303,7 +292,7 @@ describe('parser', () => {
|
|
|
303
292
|
});
|
|
304
293
|
it('supports >> operator', () => {
|
|
305
294
|
var _a;
|
|
306
|
-
|
|
295
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
307
296
|
sub main()
|
|
308
297
|
print ((r >> 24) + (g >> 16) + (b >> 8) + a)
|
|
309
298
|
end sub
|
|
@@ -311,7 +300,7 @@ describe('parser', () => {
|
|
|
311
300
|
});
|
|
312
301
|
it('allows global function names with same as token to be called', () => {
|
|
313
302
|
var _a;
|
|
314
|
-
|
|
303
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
315
304
|
sub main()
|
|
316
305
|
print string(123)
|
|
317
306
|
end sub
|
|
@@ -325,18 +314,18 @@ describe('parser', () => {
|
|
|
325
314
|
age = personXml.firstChild@age
|
|
326
315
|
end sub
|
|
327
316
|
`);
|
|
328
|
-
|
|
317
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
329
318
|
let statements = parser.statements[0].func.body.statements;
|
|
330
319
|
let first = statements[0].value;
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
320
|
+
(0, chai_config_spec_1.expect)(first).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
|
|
321
|
+
(0, chai_config_spec_1.expect)(first.tokens.name.text).to.equal('firstName');
|
|
322
|
+
(0, chai_config_spec_1.expect)(first.tokens.at.text).to.equal('@');
|
|
323
|
+
(0, chai_config_spec_1.expect)(first.obj.tokens.name.text).to.equal('personXml');
|
|
335
324
|
let second = statements[1].value;
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
325
|
+
(0, chai_config_spec_1.expect)(second).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
|
|
326
|
+
(0, chai_config_spec_1.expect)(second.tokens.name.text).to.equal('age');
|
|
327
|
+
(0, chai_config_spec_1.expect)(second.tokens.at.text).to.equal('@');
|
|
328
|
+
(0, chai_config_spec_1.expect)(second.obj.tokens.name.text).to.equal('firstChild');
|
|
340
329
|
});
|
|
341
330
|
it('does not allow chaining of @ symbols', () => {
|
|
342
331
|
let parser = parse(`
|
|
@@ -345,58 +334,58 @@ describe('parser', () => {
|
|
|
345
334
|
name = personXml@name@age@shoeSize
|
|
346
335
|
end sub
|
|
347
336
|
`);
|
|
348
|
-
|
|
337
|
+
(0, chai_config_spec_1.expect)(parser.diagnostics).not.to.be.empty;
|
|
349
338
|
});
|
|
350
339
|
it('unknown function type does not invalidate rest of function', () => {
|
|
351
340
|
let { statements, diagnostics } = parse(`
|
|
352
341
|
function log() as UNKNOWN_TYPE
|
|
353
342
|
end function
|
|
354
343
|
`, Parser_1.ParseMode.BrightScript);
|
|
355
|
-
|
|
356
|
-
|
|
344
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics); // type validation happens at scope validation step
|
|
345
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
357
346
|
});
|
|
358
347
|
it('unknown function type is not a problem in Brighterscript mode', () => {
|
|
359
348
|
let { statements, diagnostics } = parse(`
|
|
360
349
|
function log() as UNKNOWN_TYPE
|
|
361
350
|
end function
|
|
362
351
|
`, Parser_1.ParseMode.BrighterScript);
|
|
363
|
-
|
|
364
|
-
|
|
352
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
353
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
365
354
|
});
|
|
366
355
|
it('allows namespaced function type in Brighterscript mode', () => {
|
|
367
356
|
let { statements, diagnostics } = parse(`
|
|
368
357
|
function log() as SOME_NAMESPACE.UNKNOWN_TYPE
|
|
369
358
|
end function
|
|
370
359
|
`, Parser_1.ParseMode.BrighterScript);
|
|
371
|
-
|
|
372
|
-
|
|
360
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
361
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
373
362
|
});
|
|
374
363
|
it('allows custom parameter types in BrighterscriptMode', () => {
|
|
375
364
|
let { statements, diagnostics } = parse(`
|
|
376
365
|
sub foo(value as UNKNOWN_TYPE)
|
|
377
366
|
end sub
|
|
378
367
|
`, Parser_1.ParseMode.BrighterScript);
|
|
379
|
-
|
|
380
|
-
|
|
368
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
369
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
381
370
|
});
|
|
382
|
-
it('does not
|
|
371
|
+
it('does not cause any diagnostics when custom parameter types are used in Brightscript Mode', () => {
|
|
383
372
|
let { diagnostics } = parse(`
|
|
384
373
|
sub foo(value as UNKNOWN_TYPE)
|
|
385
374
|
end sub
|
|
386
375
|
`, Parser_1.ParseMode.BrightScript);
|
|
387
|
-
|
|
376
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
388
377
|
});
|
|
389
378
|
it('allows custom namespaced parameter types in BrighterscriptMode', () => {
|
|
390
379
|
let { statements, diagnostics } = parse(`
|
|
391
380
|
sub foo(value as SOME_NAMESPACE.UNKNOWN_TYPE)
|
|
392
381
|
end sub
|
|
393
382
|
`, Parser_1.ParseMode.BrighterScript);
|
|
394
|
-
|
|
395
|
-
|
|
383
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
384
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.exist;
|
|
396
385
|
});
|
|
397
386
|
it('works with conditionals', () => {
|
|
398
387
|
var _a;
|
|
399
|
-
|
|
388
|
+
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
400
389
|
function printNumber()
|
|
401
390
|
if true then
|
|
402
391
|
print 1
|
|
@@ -408,11 +397,11 @@ describe('parser', () => {
|
|
|
408
397
|
});
|
|
409
398
|
it('supports single-line if statements', () => {
|
|
410
399
|
var _a;
|
|
411
|
-
|
|
400
|
+
(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;
|
|
412
401
|
});
|
|
413
402
|
it('works with excess newlines', () => {
|
|
414
403
|
var _a;
|
|
415
|
-
let { tokens } =
|
|
404
|
+
let { tokens } = Lexer_1.Lexer.scan('function boolToNumber() as string\n\n' +
|
|
416
405
|
' if true then\n\n' +
|
|
417
406
|
' print 1\n\n' +
|
|
418
407
|
' elseif true then\n\n' +
|
|
@@ -421,39 +410,125 @@ describe('parser', () => {
|
|
|
421
410
|
' print 1\n\n' +
|
|
422
411
|
' end if\n\n' +
|
|
423
412
|
'end function\n\n');
|
|
424
|
-
|
|
413
|
+
(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;
|
|
425
414
|
});
|
|
426
415
|
it('does not invalidate entire file when line ends with a period', () => {
|
|
427
|
-
let { tokens } =
|
|
416
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
428
417
|
sub main()
|
|
429
418
|
person.a
|
|
430
419
|
end sub
|
|
431
420
|
|
|
432
421
|
`);
|
|
433
422
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
434
|
-
|
|
423
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1, 'Error count should be 0');
|
|
435
424
|
});
|
|
436
|
-
it
|
|
437
|
-
let { tokens } =
|
|
438
|
-
let {
|
|
425
|
+
it('allows printing object with trailing period', () => {
|
|
426
|
+
let { tokens } = Lexer_1.Lexer.scan(`print a.`);
|
|
427
|
+
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
439
428
|
let printStatement = statements[0];
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
429
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod());
|
|
430
|
+
(0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
|
|
431
|
+
(0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.VariableExpression);
|
|
432
|
+
});
|
|
433
|
+
it('allows printing object with trailing period with multiple dotted gets', () => {
|
|
434
|
+
let { tokens } = Lexer_1.Lexer.scan(`print a.b.`);
|
|
435
|
+
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
436
|
+
let printStatement = statements[0];
|
|
437
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod());
|
|
438
|
+
(0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
|
|
439
|
+
(0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.DottedGetExpression);
|
|
440
|
+
});
|
|
441
|
+
describe('incomplete statements in the ast', () => {
|
|
442
|
+
it('adds variable expressions to the ast', () => {
|
|
443
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
444
|
+
function a()
|
|
445
|
+
NameA.
|
|
446
|
+
end function
|
|
447
|
+
|
|
448
|
+
namespace NameA
|
|
449
|
+
sub noop()
|
|
450
|
+
end sub
|
|
451
|
+
end namespace
|
|
452
|
+
`);
|
|
453
|
+
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
454
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression());
|
|
455
|
+
let stmt = statements[0].func.body.statements[0];
|
|
456
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
457
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)((stmt).expression)).to.be.true;
|
|
458
|
+
(0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('NameA');
|
|
459
|
+
});
|
|
460
|
+
it('adds unended call statements', () => {
|
|
461
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
462
|
+
function a()
|
|
463
|
+
lcase(
|
|
464
|
+
end function
|
|
465
|
+
`);
|
|
466
|
+
let { statements } = Parser_1.Parser.parse(tokens);
|
|
467
|
+
let stmt = statements[0].func.body.statements[0];
|
|
468
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
469
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)((stmt).expression)).to.be.true;
|
|
470
|
+
(0, chai_config_spec_1.expect)(stmt.expression.callee.tokens.name.text).to.equal('lcase');
|
|
471
|
+
});
|
|
472
|
+
it('adds unended indexed get statements', () => {
|
|
473
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
474
|
+
function a()
|
|
475
|
+
nums[
|
|
476
|
+
end function
|
|
477
|
+
|
|
478
|
+
const nums = [1, 2, 3]
|
|
479
|
+
`);
|
|
480
|
+
let { statements } = Parser_1.Parser.parse(tokens);
|
|
481
|
+
let stmt = statements[0].func.body.statements[0];
|
|
482
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
483
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isIndexedGetExpression)((stmt).expression)).to.be.true;
|
|
484
|
+
(0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('nums');
|
|
485
|
+
});
|
|
486
|
+
it('adds dotted gets', () => {
|
|
487
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
488
|
+
function foo(a as KlassA)
|
|
489
|
+
a.b.
|
|
490
|
+
end function
|
|
491
|
+
|
|
492
|
+
class KlassA
|
|
493
|
+
b as KlassB
|
|
494
|
+
end class
|
|
495
|
+
|
|
496
|
+
class KlassB
|
|
497
|
+
sub noop()
|
|
498
|
+
end sub
|
|
499
|
+
end class
|
|
500
|
+
`);
|
|
501
|
+
let { statements } = Parser_1.Parser.parse(tokens);
|
|
502
|
+
let stmt = statements[0].func.body.statements[0];
|
|
503
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
504
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)((stmt).expression)).to.be.true;
|
|
505
|
+
(0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('a');
|
|
506
|
+
(0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('b');
|
|
507
|
+
});
|
|
508
|
+
it('adds function statement with missing type after as', () => {
|
|
509
|
+
var _a;
|
|
510
|
+
let parser = parse(`
|
|
511
|
+
sub foo(thing as )
|
|
512
|
+
print thing
|
|
513
|
+
end sub
|
|
514
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
515
|
+
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
516
|
+
(0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
517
|
+
});
|
|
443
518
|
});
|
|
444
519
|
describe('comments', () => {
|
|
445
|
-
it('
|
|
446
|
-
let { tokens } =
|
|
520
|
+
it('does not include comments', () => {
|
|
521
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
447
522
|
'line 1
|
|
448
523
|
'line 2
|
|
449
524
|
'line 3
|
|
450
525
|
`);
|
|
451
526
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
452
|
-
|
|
453
|
-
|
|
527
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
528
|
+
(0, chai_config_spec_1.expect)(statements.length).to.equal(0);
|
|
454
529
|
});
|
|
455
|
-
it('does
|
|
456
|
-
let { tokens } =
|
|
530
|
+
it('does matter if comments separated by newlines', () => {
|
|
531
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
457
532
|
'line 1
|
|
458
533
|
|
|
459
534
|
'line 2
|
|
@@ -461,57 +536,52 @@ describe('parser', () => {
|
|
|
461
536
|
'line 3
|
|
462
537
|
`);
|
|
463
538
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
chai_1.expect(statements[0].text).to.equal(`'line 1`);
|
|
467
|
-
chai_1.expect(statements[1].text).to.equal(`'line 2`);
|
|
468
|
-
chai_1.expect(statements[2].text).to.equal(`'line 3`);
|
|
539
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
540
|
+
(0, chai_config_spec_1.expect)(statements).to.be.lengthOf(0);
|
|
469
541
|
});
|
|
470
542
|
it('works after print statement', () => {
|
|
471
|
-
let { tokens } =
|
|
543
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
472
544
|
sub main()
|
|
473
545
|
print "hi" 'comment 1
|
|
474
546
|
end sub
|
|
475
547
|
`);
|
|
476
548
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
477
|
-
|
|
478
|
-
|
|
549
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
550
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements.length).to.equal(1);
|
|
479
551
|
});
|
|
480
|
-
it('declaration-level', () => {
|
|
481
|
-
let { tokens } =
|
|
552
|
+
it('declaration-level should be set as leading trivia', () => {
|
|
553
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
482
554
|
'comment 1
|
|
483
555
|
function a()
|
|
484
556
|
end function
|
|
485
557
|
'comment 2
|
|
486
558
|
`);
|
|
487
559
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
chai_1.expect(statements[2].text).to.equal(`'comment 2`);
|
|
560
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
561
|
+
(0, chai_config_spec_1.expect)(statements[0].getLeadingTrivia()[2].text).to.equal(`'comment 1`);
|
|
491
562
|
});
|
|
492
563
|
it('works in aa literal as its own statement', () => {
|
|
493
|
-
let { tokens } =
|
|
564
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
494
565
|
obj = {
|
|
495
566
|
"name": true,
|
|
496
567
|
'comment
|
|
497
568
|
}
|
|
498
569
|
`);
|
|
499
570
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
500
|
-
|
|
571
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
501
572
|
});
|
|
502
573
|
it('parses after function call', () => {
|
|
503
|
-
let { tokens } =
|
|
574
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
504
575
|
sub Main()
|
|
505
576
|
name = "Hello"
|
|
506
577
|
DoSomething(name) 'comment 1
|
|
507
578
|
end sub
|
|
508
579
|
`);
|
|
509
|
-
let { diagnostics
|
|
510
|
-
|
|
511
|
-
chai_1.expect(statements[0].func.body.statements[2].text).to.equal(`'comment 1`);
|
|
580
|
+
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
581
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
512
582
|
});
|
|
513
583
|
it('function', () => {
|
|
514
|
-
let { tokens } =
|
|
584
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
515
585
|
function a() 'comment 1
|
|
516
586
|
'comment 2
|
|
517
587
|
num = 1
|
|
@@ -519,14 +589,11 @@ describe('parser', () => {
|
|
|
519
589
|
end function 'comment 4
|
|
520
590
|
`);
|
|
521
591
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 2`);
|
|
525
|
-
chai_1.expect(statements[0].func.body.statements[3].text).to.equal(`'comment 3`);
|
|
526
|
-
chai_1.expect(statements[1].text).to.equal(`'comment 4`);
|
|
592
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
593
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[0].getLeadingTrivia().filter(x => x.kind === TokenKind_1.TokenKind.Comment).map(x => x.text)).members([`'comment 1`, `'comment 2`]);
|
|
527
594
|
});
|
|
528
595
|
it('if statement`', () => {
|
|
529
|
-
let { tokens } =
|
|
596
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
530
597
|
function a()
|
|
531
598
|
if true then 'comment 1
|
|
532
599
|
'comment 2
|
|
@@ -544,24 +611,18 @@ describe('parser', () => {
|
|
|
544
611
|
end function
|
|
545
612
|
`);
|
|
546
613
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
547
|
-
|
|
614
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
548
615
|
let fnSmt = statements[0];
|
|
549
|
-
if (reflection_1.isFunctionStatement(fnSmt)) {
|
|
616
|
+
if ((0, reflection_1.isFunctionStatement)(fnSmt)) {
|
|
550
617
|
let ifStmt = fnSmt.func.body.statements[0];
|
|
551
|
-
if (reflection_1.isIfStatement(ifStmt)) {
|
|
552
|
-
expectCommentWithText(ifStmt.thenBranch.statements[0], `'comment 1`);
|
|
553
|
-
expectCommentWithText(ifStmt.thenBranch.statements[1], `'comment 2`);
|
|
554
|
-
expectCommentWithText(ifStmt.thenBranch.statements[3], `'comment 3`);
|
|
618
|
+
if ((0, reflection_1.isIfStatement)(ifStmt)) {
|
|
619
|
+
expectCommentWithText(ifStmt.thenBranch.statements[0], `'comment 1\n'comment 2`);
|
|
555
620
|
let elseIfBranch = ifStmt.elseBranch;
|
|
556
|
-
if (reflection_1.isIfStatement(elseIfBranch)) {
|
|
557
|
-
expectCommentWithText(elseIfBranch.thenBranch.statements[0], `'comment 4`);
|
|
558
|
-
expectCommentWithText(elseIfBranch.thenBranch.statements[1], `'comment 5`);
|
|
559
|
-
expectCommentWithText(elseIfBranch.thenBranch.statements[3], `'comment 6`);
|
|
621
|
+
if ((0, reflection_1.isIfStatement)(elseIfBranch)) {
|
|
622
|
+
expectCommentWithText(elseIfBranch.thenBranch.statements[0], `'comment 4\n'comment 5`);
|
|
560
623
|
let elseBranch = elseIfBranch.elseBranch;
|
|
561
|
-
if (reflection_1.isBlock(elseBranch)) {
|
|
562
|
-
expectCommentWithText(elseBranch.statements[0], `'comment 7`);
|
|
563
|
-
expectCommentWithText(elseBranch.statements[1], `'comment 8`);
|
|
564
|
-
expectCommentWithText(elseBranch.statements[3], `'comment 9`);
|
|
624
|
+
if ((0, reflection_1.isBlock)(elseBranch)) {
|
|
625
|
+
expectCommentWithText(elseBranch.statements[0], `'comment 7\n'comment 8`);
|
|
565
626
|
}
|
|
566
627
|
else {
|
|
567
628
|
failStatementType(elseBranch, 'Block');
|
|
@@ -570,7 +631,6 @@ describe('parser', () => {
|
|
|
570
631
|
else {
|
|
571
632
|
failStatementType(elseIfBranch, 'If');
|
|
572
633
|
}
|
|
573
|
-
expectCommentWithText(fnSmt.func.body.statements[1], `'comment 10`);
|
|
574
634
|
}
|
|
575
635
|
else {
|
|
576
636
|
failStatementType(ifStmt, 'If');
|
|
@@ -581,7 +641,7 @@ describe('parser', () => {
|
|
|
581
641
|
}
|
|
582
642
|
});
|
|
583
643
|
it('while', () => {
|
|
584
|
-
let { tokens } =
|
|
644
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
585
645
|
function a()
|
|
586
646
|
while true 'comment 1
|
|
587
647
|
'comment 2
|
|
@@ -591,15 +651,12 @@ describe('parser', () => {
|
|
|
591
651
|
end function
|
|
592
652
|
`);
|
|
593
653
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
594
|
-
|
|
654
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
595
655
|
let stmt = statements[0].func.body.statements[0];
|
|
596
|
-
|
|
597
|
-
chai_1.expect(stmt.body.statements[1].text).to.equal(`'comment 2`);
|
|
598
|
-
chai_1.expect(stmt.body.statements[3].text).to.equal(`'comment 3`);
|
|
599
|
-
chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
|
|
656
|
+
expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
|
|
600
657
|
});
|
|
601
658
|
it('for', () => {
|
|
602
|
-
let { tokens } =
|
|
659
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
603
660
|
function a()
|
|
604
661
|
for i = 0 to 10 step 1 'comment 1
|
|
605
662
|
'comment 2
|
|
@@ -609,15 +666,12 @@ describe('parser', () => {
|
|
|
609
666
|
end function
|
|
610
667
|
`);
|
|
611
668
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
612
|
-
|
|
669
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
613
670
|
let stmt = statements[0].func.body.statements[0];
|
|
614
|
-
|
|
615
|
-
chai_1.expect(stmt.body.statements[1].text).to.equal(`'comment 2`);
|
|
616
|
-
chai_1.expect(stmt.body.statements[3].text).to.equal(`'comment 3`);
|
|
617
|
-
chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
|
|
671
|
+
expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
|
|
618
672
|
});
|
|
619
673
|
it('for each', () => {
|
|
620
|
-
let { tokens } =
|
|
674
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
621
675
|
function a()
|
|
622
676
|
for each val in [1,2,3] 'comment 1
|
|
623
677
|
'comment 2
|
|
@@ -627,12 +681,9 @@ describe('parser', () => {
|
|
|
627
681
|
end function
|
|
628
682
|
`);
|
|
629
683
|
let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
|
|
630
|
-
|
|
684
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
631
685
|
let stmt = statements[0].func.body.statements[0];
|
|
632
|
-
|
|
633
|
-
chai_1.expect(stmt.body.statements[1].text).to.equal(`'comment 2`);
|
|
634
|
-
chai_1.expect(stmt.body.statements[3].text).to.equal(`'comment 3`);
|
|
635
|
-
chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
|
|
686
|
+
expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
|
|
636
687
|
});
|
|
637
688
|
});
|
|
638
689
|
});
|
|
@@ -644,7 +695,7 @@ describe('parser', () => {
|
|
|
644
695
|
then = true
|
|
645
696
|
end sub
|
|
646
697
|
`);
|
|
647
|
-
|
|
698
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1);
|
|
648
699
|
});
|
|
649
700
|
it('is allowed as an AA property name', () => {
|
|
650
701
|
var _a;
|
|
@@ -657,7 +708,39 @@ describe('parser', () => {
|
|
|
657
708
|
print person.then
|
|
658
709
|
end sub
|
|
659
710
|
`);
|
|
660
|
-
|
|
711
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
712
|
+
});
|
|
713
|
+
it('allows `mod` as an AA literal property', () => {
|
|
714
|
+
const parser = parse(`
|
|
715
|
+
sub main()
|
|
716
|
+
person = {
|
|
717
|
+
mod: true
|
|
718
|
+
}
|
|
719
|
+
person.mod = false
|
|
720
|
+
print person.mod
|
|
721
|
+
end sub
|
|
722
|
+
`);
|
|
723
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
724
|
+
});
|
|
725
|
+
it('converts aa literal property TokenKind to Identifier', () => {
|
|
726
|
+
const parser = parse(`
|
|
727
|
+
sub main()
|
|
728
|
+
person = {
|
|
729
|
+
mod: true
|
|
730
|
+
and: true
|
|
731
|
+
}
|
|
732
|
+
end sub
|
|
733
|
+
`);
|
|
734
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
735
|
+
const elements = [];
|
|
736
|
+
parser.ast.walk((0, visitors_1.createVisitor)({
|
|
737
|
+
AAMemberExpression: (node) => {
|
|
738
|
+
elements.push(node);
|
|
739
|
+
}
|
|
740
|
+
}), {
|
|
741
|
+
walkMode: visitors_1.WalkMode.visitAllRecursive
|
|
742
|
+
});
|
|
743
|
+
(0, chai_config_spec_1.expect)(elements.map(x => x.tokens.key.kind)).to.eql([TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.Identifier]);
|
|
661
744
|
});
|
|
662
745
|
});
|
|
663
746
|
it('"end" is not allowed as a local identifier', () => {
|
|
@@ -666,20 +749,20 @@ describe('parser', () => {
|
|
|
666
749
|
end = true
|
|
667
750
|
end sub
|
|
668
751
|
`);
|
|
669
|
-
|
|
752
|
+
(0, chai_config_spec_1.expect)(diagnostics).to.be.length.greaterThan(0);
|
|
670
753
|
});
|
|
671
754
|
it('none of them can be used as local variables', () => {
|
|
672
|
-
let reservedWords = new Set(
|
|
755
|
+
let reservedWords = new Set(TokenKind_1.ReservedWords);
|
|
673
756
|
//remove the rem keyword because it's a comment...won't cause error
|
|
674
757
|
reservedWords.delete('rem');
|
|
675
758
|
for (let reservedWord of reservedWords) {
|
|
676
|
-
let { tokens } =
|
|
759
|
+
let { tokens } = Lexer_1.Lexer.scan(`
|
|
677
760
|
sub main()
|
|
678
761
|
${reservedWord} = true
|
|
679
762
|
end sub
|
|
680
763
|
`);
|
|
681
764
|
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
682
|
-
|
|
765
|
+
(0, chai_config_spec_1.expect)(diagnostics, `assigning to reserved word "${reservedWord}" should have been an error`).to.be.length.greaterThan(0);
|
|
683
766
|
}
|
|
684
767
|
});
|
|
685
768
|
});
|
|
@@ -689,24 +772,24 @@ describe('parser', () => {
|
|
|
689
772
|
let { statements, diagnostics } = parse(`
|
|
690
773
|
import "somePath"
|
|
691
774
|
`, Parser_1.ParseMode.BrighterScript);
|
|
692
|
-
|
|
693
|
-
|
|
775
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
776
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
694
777
|
});
|
|
695
778
|
it('catches import statements used in brightscript files', () => {
|
|
696
779
|
var _a;
|
|
697
780
|
let { statements, diagnostics } = parse(`
|
|
698
781
|
import "somePath"
|
|
699
782
|
`, Parser_1.ParseMode.BrightScript);
|
|
700
|
-
|
|
701
|
-
|
|
783
|
+
(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);
|
|
784
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
702
785
|
});
|
|
703
786
|
it('catchs missing file path', () => {
|
|
704
787
|
var _a;
|
|
705
788
|
let { statements, diagnostics } = parse(`
|
|
706
789
|
import
|
|
707
790
|
`, Parser_1.ParseMode.BrighterScript);
|
|
708
|
-
|
|
709
|
-
|
|
791
|
+
(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);
|
|
792
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
710
793
|
});
|
|
711
794
|
});
|
|
712
795
|
describe('Annotations', () => {
|
|
@@ -717,7 +800,7 @@ describe('parser', () => {
|
|
|
717
800
|
sub main()
|
|
718
801
|
end sub
|
|
719
802
|
`, Parser_1.ParseMode.BrighterScript);
|
|
720
|
-
|
|
803
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('@').message);
|
|
721
804
|
});
|
|
722
805
|
it('properly handles empty annotation above class method', () => {
|
|
723
806
|
var _a;
|
|
@@ -729,7 +812,7 @@ describe('parser', () => {
|
|
|
729
812
|
end sub
|
|
730
813
|
end class
|
|
731
814
|
`, Parser_1.ParseMode.BrighterScript);
|
|
732
|
-
|
|
815
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier().message);
|
|
733
816
|
});
|
|
734
817
|
it('parses with error if annotation is not followed by a statement', () => {
|
|
735
818
|
var _a, _b, _c, _d;
|
|
@@ -743,11 +826,11 @@ describe('parser', () => {
|
|
|
743
826
|
end class
|
|
744
827
|
@meta1
|
|
745
828
|
`, Parser_1.ParseMode.BrighterScript);
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
829
|
+
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(4);
|
|
830
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
831
|
+
(0, chai_config_spec_1.expect)((_b = diagnostics[1]) === null || _b === void 0 ? void 0 : _b.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
832
|
+
(0, chai_config_spec_1.expect)((_c = diagnostics[2]) === null || _c === void 0 ? void 0 : _c.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
833
|
+
(0, chai_config_spec_1.expect)((_d = diagnostics[3]) === null || _d === void 0 ? void 0 : _d.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
751
834
|
});
|
|
752
835
|
it('attaches an annotation to next statement', () => {
|
|
753
836
|
var _a;
|
|
@@ -759,18 +842,18 @@ describe('parser', () => {
|
|
|
759
842
|
@meta2 sub init()
|
|
760
843
|
end sub
|
|
761
844
|
`, Parser_1.ParseMode.BrighterScript);
|
|
762
|
-
|
|
763
|
-
|
|
845
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
846
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
764
847
|
let fn = statements[0];
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
848
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
849
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
850
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
|
|
851
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].name).to.equal('meta1');
|
|
852
|
+
(0, chai_config_spec_1.expect)(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
770
853
|
fn = statements[1];
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
854
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
855
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
856
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta2');
|
|
774
857
|
});
|
|
775
858
|
it('attaches annotations inside a function body', () => {
|
|
776
859
|
var _a, _b;
|
|
@@ -780,13 +863,13 @@ describe('parser', () => {
|
|
|
780
863
|
print "hello"
|
|
781
864
|
end function
|
|
782
865
|
`, Parser_1.ParseMode.BrighterScript);
|
|
783
|
-
|
|
866
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
784
867
|
let fn = statements[0];
|
|
785
868
|
let fnStatements = fn.func.body.statements;
|
|
786
869
|
let stat = fnStatements[0];
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
870
|
+
(0, chai_config_spec_1.expect)(stat).to.exist;
|
|
871
|
+
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
872
|
+
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
790
873
|
});
|
|
791
874
|
it('attaches multiple annotations to next statement', () => {
|
|
792
875
|
var _a;
|
|
@@ -796,14 +879,14 @@ describe('parser', () => {
|
|
|
796
879
|
function main()
|
|
797
880
|
end function
|
|
798
881
|
`, Parser_1.ParseMode.BrighterScript);
|
|
799
|
-
|
|
800
|
-
|
|
882
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
883
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
801
884
|
let fn = statements[0];
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
885
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
886
|
+
(0, chai_config_spec_1.expect)(fn.annotations.length).to.equal(3);
|
|
887
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
888
|
+
(0, chai_config_spec_1.expect)(fn.annotations[1]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
889
|
+
(0, chai_config_spec_1.expect)(fn.annotations[2]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
807
890
|
});
|
|
808
891
|
it('allows annotations with parameters', () => {
|
|
809
892
|
var _a;
|
|
@@ -812,12 +895,12 @@ describe('parser', () => {
|
|
|
812
895
|
function main()
|
|
813
896
|
end function
|
|
814
897
|
`, Parser_1.ParseMode.BrighterScript);
|
|
815
|
-
|
|
898
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
816
899
|
let fn = statements[0];
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
900
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
901
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
902
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
|
|
903
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].call).to.be.instanceof(Expression_1.CallExpression);
|
|
821
904
|
});
|
|
822
905
|
it('attaches annotations to a class', () => {
|
|
823
906
|
var _a, _b;
|
|
@@ -829,10 +912,10 @@ describe('parser', () => {
|
|
|
829
912
|
end function
|
|
830
913
|
end class
|
|
831
914
|
`, Parser_1.ParseMode.BrighterScript);
|
|
832
|
-
|
|
915
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
833
916
|
let cs = statements[0];
|
|
834
|
-
|
|
835
|
-
|
|
917
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
918
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
836
919
|
});
|
|
837
920
|
it('attaches annotations to multiple clases', () => {
|
|
838
921
|
var _a, _b, _c;
|
|
@@ -850,15 +933,15 @@ describe('parser', () => {
|
|
|
850
933
|
end function
|
|
851
934
|
end class
|
|
852
935
|
`, Parser_1.ParseMode.BrighterScript);
|
|
853
|
-
|
|
936
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
854
937
|
let cs = statements[0];
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
938
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
939
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
940
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
|
|
858
941
|
let cs2 = statements[1];
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
942
|
+
(0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
|
|
943
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
944
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
|
|
862
945
|
});
|
|
863
946
|
it('attaches annotations to a namespaced class', () => {
|
|
864
947
|
var _a, _b;
|
|
@@ -872,11 +955,11 @@ describe('parser', () => {
|
|
|
872
955
|
end class
|
|
873
956
|
end namespace
|
|
874
957
|
`, Parser_1.ParseMode.BrighterScript);
|
|
875
|
-
|
|
958
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
876
959
|
let ns = statements[0];
|
|
877
960
|
let cs = ns.body.statements[0];
|
|
878
|
-
|
|
879
|
-
|
|
961
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
962
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
880
963
|
});
|
|
881
964
|
it('attaches annotations to a namespaced class - multiple', () => {
|
|
882
965
|
var _a, _b, _c;
|
|
@@ -896,16 +979,16 @@ describe('parser', () => {
|
|
|
896
979
|
end class
|
|
897
980
|
end namespace
|
|
898
981
|
`, Parser_1.ParseMode.BrighterScript);
|
|
899
|
-
|
|
982
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
900
983
|
let ns = statements[0];
|
|
901
984
|
let cs = ns.body.statements[0];
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
985
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
986
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
987
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
|
|
905
988
|
let cs2 = ns.body.statements[1];
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
989
|
+
(0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
|
|
990
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
991
|
+
(0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
|
|
909
992
|
});
|
|
910
993
|
it('attaches annotations to a class constructor', () => {
|
|
911
994
|
var _a, _b;
|
|
@@ -920,11 +1003,11 @@ describe('parser', () => {
|
|
|
920
1003
|
end function
|
|
921
1004
|
end class
|
|
922
1005
|
`, Parser_1.ParseMode.BrighterScript);
|
|
923
|
-
|
|
1006
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
924
1007
|
let cs = statements[0];
|
|
925
1008
|
let stat = cs.body[0];
|
|
926
|
-
|
|
927
|
-
|
|
1009
|
+
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1010
|
+
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
928
1011
|
});
|
|
929
1012
|
it('attaches annotations to a class methods', () => {
|
|
930
1013
|
var _a, _b;
|
|
@@ -939,11 +1022,11 @@ describe('parser', () => {
|
|
|
939
1022
|
end function
|
|
940
1023
|
end class
|
|
941
1024
|
`, Parser_1.ParseMode.BrighterScript);
|
|
942
|
-
|
|
1025
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
943
1026
|
let cs = statements[0];
|
|
944
1027
|
let stat = cs.body[1];
|
|
945
|
-
|
|
946
|
-
|
|
1028
|
+
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1029
|
+
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
947
1030
|
});
|
|
948
1031
|
it('attaches annotations to a class methods, fields and constructor', () => {
|
|
949
1032
|
var _a, _b, _c, _d, _e;
|
|
@@ -967,19 +1050,19 @@ describe('parser', () => {
|
|
|
967
1050
|
public foo="bar"
|
|
968
1051
|
end class
|
|
969
1052
|
`, Parser_1.ParseMode.BrighterScript);
|
|
970
|
-
|
|
1053
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
971
1054
|
let cs = statements[0];
|
|
972
|
-
|
|
973
|
-
|
|
1055
|
+
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(2);
|
|
1056
|
+
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
974
1057
|
let stat1 = cs.body[0];
|
|
975
1058
|
let stat2 = cs.body[1];
|
|
976
1059
|
let f1 = cs.body[2];
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1060
|
+
(0, chai_config_spec_1.expect)((_c = stat1.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
|
|
1061
|
+
(0, chai_config_spec_1.expect)(stat1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1062
|
+
(0, chai_config_spec_1.expect)((_d = stat2.annotations) === null || _d === void 0 ? void 0 : _d.length).to.equal(2);
|
|
1063
|
+
(0, chai_config_spec_1.expect)(stat2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1064
|
+
(0, chai_config_spec_1.expect)((_e = f1.annotations) === null || _e === void 0 ? void 0 : _e.length).to.equal(2);
|
|
1065
|
+
(0, chai_config_spec_1.expect)(f1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
983
1066
|
});
|
|
984
1067
|
it('ignores annotations on commented out lines', () => {
|
|
985
1068
|
var _a;
|
|
@@ -990,9 +1073,9 @@ describe('parser', () => {
|
|
|
990
1073
|
print "hello"
|
|
991
1074
|
end function
|
|
992
1075
|
`, Parser_1.ParseMode.BrighterScript);
|
|
993
|
-
|
|
1076
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
994
1077
|
let cs = statements[0];
|
|
995
|
-
|
|
1078
|
+
(0, chai_config_spec_1.expect)(cs.annotations).to.be.undefined;
|
|
996
1079
|
});
|
|
997
1080
|
it('can convert argument of an annotation to JS types', () => {
|
|
998
1081
|
var _a;
|
|
@@ -1010,22 +1093,22 @@ describe('parser', () => {
|
|
|
1010
1093
|
sub init()
|
|
1011
1094
|
end sub
|
|
1012
1095
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1013
|
-
|
|
1014
|
-
|
|
1096
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1097
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1015
1098
|
let fn = statements[0];
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1099
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1100
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([]);
|
|
1101
|
+
(0, chai_config_spec_1.expect)(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1019
1102
|
fn = statements[1];
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1103
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1104
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1105
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([
|
|
1023
1106
|
'arg', 2, true,
|
|
1024
1107
|
{ prop: 'value' }, [1, 2],
|
|
1025
1108
|
null
|
|
1026
1109
|
]);
|
|
1027
1110
|
let allArgs = fn.annotations[0].getArguments(false);
|
|
1028
|
-
|
|
1111
|
+
(0, chai_config_spec_1.expect)(allArgs.pop()).to.be.instanceOf(Expression_1.FunctionExpression);
|
|
1029
1112
|
});
|
|
1030
1113
|
it('can handle negative numbers', () => {
|
|
1031
1114
|
var _a;
|
|
@@ -1037,161 +1120,1004 @@ describe('parser', () => {
|
|
|
1037
1120
|
sub init()
|
|
1038
1121
|
end sub
|
|
1039
1122
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1040
|
-
|
|
1041
|
-
|
|
1123
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1124
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1042
1125
|
let fn = statements[0];
|
|
1043
|
-
|
|
1044
|
-
|
|
1126
|
+
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1127
|
+
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([-100]);
|
|
1045
1128
|
});
|
|
1046
1129
|
});
|
|
1047
|
-
describe('
|
|
1048
|
-
it('
|
|
1049
|
-
|
|
1130
|
+
describe('type casts', () => {
|
|
1131
|
+
it('is not allowed in brightscript mode', () => {
|
|
1132
|
+
var _a;
|
|
1133
|
+
let parser = parse(`
|
|
1134
|
+
sub main(node as dynamic)
|
|
1135
|
+
print lcase((node as string))
|
|
1136
|
+
end sub
|
|
1137
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1138
|
+
(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);
|
|
1139
|
+
});
|
|
1140
|
+
it('allows type casts after function calls', () => {
|
|
1141
|
+
var _a;
|
|
1142
|
+
let { statements, diagnostics } = parse(`
|
|
1050
1143
|
sub main()
|
|
1051
|
-
|
|
1052
|
-
print "hello"
|
|
1053
|
-
end sub
|
|
1144
|
+
value = getValue() as integer
|
|
1054
1145
|
end sub
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1146
|
+
|
|
1147
|
+
function getValue()
|
|
1148
|
+
return 123
|
|
1149
|
+
end function
|
|
1150
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1151
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1152
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1153
|
+
let fn = statements[0];
|
|
1154
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1155
|
+
let assignment = fn.func.body.statements[0];
|
|
1156
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
|
|
1157
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(assignment.value)).to.be.true;
|
|
1158
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value.obj)).to.be.true;
|
|
1159
|
+
(0, testHelpers_spec_1.expectTypeToBe)(assignment.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), IntegerType_1.IntegerType);
|
|
1059
1160
|
});
|
|
1060
|
-
it('
|
|
1061
|
-
|
|
1161
|
+
it('allows type casts in the middle of expressions', () => {
|
|
1162
|
+
var _a;
|
|
1163
|
+
let { statements, diagnostics } = parse(`
|
|
1062
1164
|
sub main()
|
|
1063
|
-
|
|
1064
|
-
return "hello"
|
|
1065
|
-
end sub
|
|
1165
|
+
value = (getValue() as integer).toStr()
|
|
1066
1166
|
end sub
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1167
|
+
|
|
1168
|
+
function getValue()
|
|
1169
|
+
return 123
|
|
1170
|
+
end function
|
|
1171
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1172
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1173
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1174
|
+
let fn = statements[0];
|
|
1175
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1176
|
+
let assignment = fn.func.body.statements[0];
|
|
1177
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
|
|
1178
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value)).to.be.true;
|
|
1179
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)(assignment.value.callee)).to.be.true;
|
|
1180
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(assignment.value.callee.obj)).to.be.true;
|
|
1181
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(assignment.value.callee.obj.expression)).to.be.true;
|
|
1182
|
+
//grouping expression is an integer
|
|
1183
|
+
(0, testHelpers_spec_1.expectTypeToBe)(assignment.value.callee.obj.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), IntegerType_1.IntegerType);
|
|
1071
1184
|
});
|
|
1072
|
-
it('
|
|
1073
|
-
|
|
1185
|
+
it('allows type casts in a function call', () => {
|
|
1186
|
+
var _a;
|
|
1187
|
+
let { statements, diagnostics } = parse(`
|
|
1074
1188
|
sub main()
|
|
1075
|
-
|
|
1076
|
-
return new Person()
|
|
1077
|
-
end sub
|
|
1189
|
+
print cos(getAngle() as float)
|
|
1078
1190
|
end sub
|
|
1079
1191
|
|
|
1080
|
-
|
|
1081
|
-
|
|
1192
|
+
function getAngle()
|
|
1193
|
+
return 123
|
|
1194
|
+
end function
|
|
1082
1195
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1196
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1197
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1198
|
+
let fn = statements[0];
|
|
1199
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1200
|
+
let print = fn.func.body.statements[0];
|
|
1201
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
|
|
1202
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(print.expressions[0])).to.be.true;
|
|
1203
|
+
let fnCall = print.expressions[0];
|
|
1204
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(fnCall.args[0])).to.be.true;
|
|
1205
|
+
let arg = fnCall.args[0];
|
|
1206
|
+
//argument type is float
|
|
1207
|
+
(0, testHelpers_spec_1.expectTypeToBe)(arg.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), FloatType_1.FloatType);
|
|
1087
1208
|
});
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
const parser = parse(`
|
|
1209
|
+
it('allows multiple type casts', () => {
|
|
1210
|
+
var _a;
|
|
1211
|
+
let { statements, diagnostics } = parse(`
|
|
1092
1212
|
sub main()
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1213
|
+
print getData() as dynamic as float as string
|
|
1214
|
+
end sub
|
|
1215
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1216
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1217
|
+
(0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1218
|
+
let fn = statements[0];
|
|
1219
|
+
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1220
|
+
let print = fn.func.body.statements[0];
|
|
1221
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
|
|
1222
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(print.expressions[0])).to.be.true;
|
|
1223
|
+
//argument type is float
|
|
1224
|
+
(0, testHelpers_spec_1.expectTypeToBe)(print.expressions[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), StringType_1.StringType);
|
|
1225
|
+
});
|
|
1226
|
+
it('flags invalid type cast syntax - multiple as', () => {
|
|
1227
|
+
var _a;
|
|
1228
|
+
let { diagnostics } = parse(`
|
|
1229
|
+
sub foo(key)
|
|
1230
|
+
getData(key as as string)
|
|
1231
|
+
end sub
|
|
1232
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1233
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1234
|
+
});
|
|
1235
|
+
it('flags invalid type cast syntax - no type after as', () => {
|
|
1236
|
+
var _a;
|
|
1237
|
+
let { diagnostics } = parse(`
|
|
1238
|
+
sub foo(key)
|
|
1239
|
+
getData(key as)
|
|
1240
|
+
end sub
|
|
1241
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1242
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1243
|
+
});
|
|
1244
|
+
it('allows declaring types on assignment in Brighterscript mode', () => {
|
|
1245
|
+
let { diagnostics } = parse(`
|
|
1246
|
+
sub foo()
|
|
1247
|
+
x as string = formatJson("some string")
|
|
1248
|
+
end sub
|
|
1249
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1250
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1251
|
+
});
|
|
1252
|
+
it('does not allow declaring types on assignment in brightscript mode', () => {
|
|
1253
|
+
var _a, _b;
|
|
1254
|
+
let { diagnostics } = parse(`
|
|
1255
|
+
sub foo()
|
|
1256
|
+
x as string = formatJson("some string")
|
|
1257
|
+
end sub
|
|
1258
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1259
|
+
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1260
|
+
(0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.message).to.include('typed assignment');
|
|
1261
|
+
});
|
|
1262
|
+
});
|
|
1263
|
+
describe('union types', () => {
|
|
1264
|
+
it('is not allowed in brightscript mode', () => {
|
|
1265
|
+
let parser = parse(`
|
|
1266
|
+
sub main(param as string or integer)
|
|
1267
|
+
print param
|
|
1268
|
+
end sub
|
|
1269
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1270
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression()]);
|
|
1271
|
+
});
|
|
1272
|
+
it('allows union types in parameters', () => {
|
|
1273
|
+
let { diagnostics } = parse(`
|
|
1274
|
+
sub main(param as string or integer)
|
|
1275
|
+
print param
|
|
1276
|
+
end sub
|
|
1277
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1278
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1279
|
+
});
|
|
1280
|
+
it('allows union types in type casts', () => {
|
|
1281
|
+
let { diagnostics } = parse(`
|
|
1282
|
+
sub main(val)
|
|
1283
|
+
printThing(val as string or integer)
|
|
1097
1284
|
end sub
|
|
1098
1285
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1286
|
+
sub printThing(thing as string or integer)
|
|
1287
|
+
print thing
|
|
1288
|
+
end sub
|
|
1101
1289
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1102
|
-
testHelpers_spec_1.expectZeroDiagnostics(
|
|
1103
|
-
const mainSymbolTable = parser.references.functionExpressions[0].symbolTable;
|
|
1104
|
-
chai_1.expect(mainSymbolTable.getSymbolType('someNum')).to.be.instanceof(IntegerType_1.IntegerType);
|
|
1105
|
-
chai_1.expect(mainSymbolTable.getSymbolType('someString')).to.be.instanceof(StringType_1.StringType);
|
|
1106
|
-
chai_1.expect(mainSymbolTable.getSymbolType('someObj')).to.be.instanceof(ObjectType_1.ObjectType);
|
|
1107
|
-
chai_1.expect(mainSymbolTable.getSymbolType('someCustom')).to.be.instanceof(CustomType_1.CustomType);
|
|
1290
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1108
1291
|
});
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1292
|
+
});
|
|
1293
|
+
describe('typed arrays', () => {
|
|
1294
|
+
it('is not allowed in brightscript mode', () => {
|
|
1295
|
+
let parser = parse(`
|
|
1296
|
+
sub main(things as string[])
|
|
1297
|
+
print things
|
|
1298
|
+
end sub
|
|
1299
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1300
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typed arrays')]);
|
|
1301
|
+
});
|
|
1302
|
+
it('is allowed in brighterscript mode', () => {
|
|
1303
|
+
let { statements, diagnostics } = parse(`
|
|
1304
|
+
sub main(things as string[])
|
|
1305
|
+
print things
|
|
1113
1306
|
end sub
|
|
1114
1307
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1115
|
-
testHelpers_spec_1.expectZeroDiagnostics(
|
|
1116
|
-
const
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
chai_1.expect(someFuncSymbolTable.getSymbolType('temp')).to.be.instanceof(IntegerType_1.IntegerType);
|
|
1308
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1309
|
+
const paramType = statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1310
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1311
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, StringType_1.StringType);
|
|
1120
1312
|
});
|
|
1121
|
-
it('
|
|
1122
|
-
|
|
1123
|
-
sub
|
|
1124
|
-
|
|
1313
|
+
it('allows multi dimensional arrays', () => {
|
|
1314
|
+
let { statements, diagnostics } = parse(`
|
|
1315
|
+
sub main(things as string[][])
|
|
1316
|
+
print things
|
|
1317
|
+
end sub
|
|
1318
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1319
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1320
|
+
const paramType = statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1321
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1322
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, types_1.ArrayType);
|
|
1323
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType.defaultType, StringType_1.StringType);
|
|
1324
|
+
});
|
|
1325
|
+
it('allows arrays as return types', () => {
|
|
1326
|
+
let { statements, diagnostics } = parse(`
|
|
1327
|
+
function getFourPrimes() as integer[]
|
|
1328
|
+
return [2, 3, 5, 7]
|
|
1329
|
+
end function
|
|
1330
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1331
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1332
|
+
const paramType = statements[0].func.returnTypeExpression.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1333
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1334
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, IntegerType_1.IntegerType);
|
|
1335
|
+
});
|
|
1336
|
+
it('allows arrays in union types', () => {
|
|
1337
|
+
let { statements, diagnostics } = parse(`
|
|
1338
|
+
sub foo(x as integer or integer[] or string or string[])
|
|
1339
|
+
print x
|
|
1340
|
+
end sub
|
|
1341
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1342
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1343
|
+
const paramType = statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1344
|
+
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.UnionType);
|
|
1345
|
+
(0, chai_config_spec_1.expect)(paramType.toString().includes('Array<string>')).to.be.true;
|
|
1346
|
+
(0, chai_config_spec_1.expect)(paramType.toString().includes('Array<integer>')).to.be.true;
|
|
1347
|
+
});
|
|
1348
|
+
});
|
|
1349
|
+
describe('interfaces', () => {
|
|
1350
|
+
it('allows fields and methods', () => {
|
|
1351
|
+
let { statements, diagnostics } = parse(`
|
|
1352
|
+
interface SomeIFace
|
|
1353
|
+
name as string
|
|
1354
|
+
height as integer
|
|
1355
|
+
function getValue(thing as float) as object
|
|
1356
|
+
function getMe() as SomeIFace
|
|
1357
|
+
sub noop()
|
|
1358
|
+
end interface
|
|
1359
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1360
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1361
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1362
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1363
|
+
});
|
|
1364
|
+
it('allows untyped fields', () => {
|
|
1365
|
+
let { statements, diagnostics } = parse(`
|
|
1366
|
+
interface HasUntyped
|
|
1367
|
+
name
|
|
1368
|
+
end interface
|
|
1369
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1370
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1371
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1372
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1373
|
+
});
|
|
1374
|
+
it('allows optional fields', () => {
|
|
1375
|
+
let { statements, diagnostics } = parse(`
|
|
1376
|
+
interface HasOptional
|
|
1377
|
+
optional name as string
|
|
1378
|
+
optional height
|
|
1379
|
+
end interface
|
|
1380
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1381
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1382
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1383
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1384
|
+
const iface = statements[0];
|
|
1385
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1386
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1387
|
+
// eslint-disable-next-line no-bitwise
|
|
1388
|
+
ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1389
|
+
});
|
|
1390
|
+
it('allows fields named optional', () => {
|
|
1391
|
+
let { statements, diagnostics } = parse(`
|
|
1392
|
+
interface IsJustOptional
|
|
1393
|
+
optional
|
|
1394
|
+
someThingElse
|
|
1395
|
+
end interface
|
|
1396
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1397
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1398
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1399
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1400
|
+
const iface = statements[0];
|
|
1401
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
|
|
1402
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1403
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1404
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(2);
|
|
1405
|
+
// eslint-disable-next-line no-bitwise
|
|
1406
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(0));
|
|
1407
|
+
});
|
|
1408
|
+
it('allows fields named optional that are also optional', () => {
|
|
1409
|
+
let { statements, diagnostics } = parse(`
|
|
1410
|
+
interface IsJustOptional
|
|
1411
|
+
optional optional
|
|
1412
|
+
end interface
|
|
1413
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1414
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1415
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1416
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1417
|
+
const iface = statements[0];
|
|
1418
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1419
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1420
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1421
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1422
|
+
// eslint-disable-next-line no-bitwise
|
|
1423
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1424
|
+
});
|
|
1425
|
+
it('allows optional methods', () => {
|
|
1426
|
+
let { statements, diagnostics } = parse(`
|
|
1427
|
+
interface HasOptional
|
|
1428
|
+
optional function getValue() as boolean
|
|
1429
|
+
optional sub noop()
|
|
1430
|
+
optional function process()
|
|
1431
|
+
end interface
|
|
1432
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1433
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1434
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1435
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1436
|
+
const iface = statements[0];
|
|
1437
|
+
iface.methods.forEach(m => (0, chai_config_spec_1.expect)(m.isOptional).to.equal(true));
|
|
1438
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1439
|
+
// eslint-disable-next-line no-bitwise
|
|
1440
|
+
ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1441
|
+
});
|
|
1442
|
+
it('allows fields named `as` that are also optional', () => {
|
|
1443
|
+
let { statements, diagnostics } = parse(`
|
|
1444
|
+
interface IsJustOptional
|
|
1445
|
+
optional as
|
|
1446
|
+
end interface
|
|
1447
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1448
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1449
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1450
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1451
|
+
const iface = statements[0];
|
|
1452
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1453
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1454
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1455
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1456
|
+
// eslint-disable-next-line no-bitwise
|
|
1457
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1458
|
+
});
|
|
1459
|
+
it('allows fields named `as` that are also typed', () => {
|
|
1460
|
+
let { statements, diagnostics } = parse(`
|
|
1461
|
+
interface IsJustOptional
|
|
1462
|
+
optional as as string
|
|
1463
|
+
end interface
|
|
1464
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1465
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1466
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1467
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1468
|
+
const iface = statements[0];
|
|
1469
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1470
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1471
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1472
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1473
|
+
// eslint-disable-next-line no-bitwise
|
|
1474
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1475
|
+
});
|
|
1476
|
+
it('allows fields named `optional` that are also typed', () => {
|
|
1477
|
+
let { statements, diagnostics } = parse(`
|
|
1478
|
+
interface IsJustOptional
|
|
1479
|
+
optional as string
|
|
1480
|
+
end interface
|
|
1481
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1482
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1483
|
+
(0, chai_config_spec_1.expect)(statements.length).to.eq(1);
|
|
1484
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
|
|
1485
|
+
const iface = statements[0];
|
|
1486
|
+
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
|
|
1487
|
+
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1488
|
+
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1489
|
+
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1490
|
+
// eslint-disable-next-line no-bitwise
|
|
1491
|
+
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(0));
|
|
1492
|
+
});
|
|
1493
|
+
});
|
|
1494
|
+
describe('leadingTrivia', () => {
|
|
1495
|
+
it('gets leading trivia from functions', () => {
|
|
1496
|
+
let { statements } = parse(`
|
|
1497
|
+
' Nice function, bro
|
|
1498
|
+
function foo()
|
|
1499
|
+
return 1
|
|
1500
|
+
end function
|
|
1501
|
+
`);
|
|
1502
|
+
const funcStatements = statements.filter(reflection_1.isFunctionStatement);
|
|
1503
|
+
const fooTrivia = funcStatements[0].getLeadingTrivia();
|
|
1504
|
+
(0, chai_config_spec_1.expect)(fooTrivia.length).to.be.greaterThan(0);
|
|
1505
|
+
(0, chai_config_spec_1.expect)(fooTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1506
|
+
});
|
|
1507
|
+
it('gets multiple lines of leading trivia', () => {
|
|
1508
|
+
let { statements } = parse(`
|
|
1509
|
+
' Say hello to someone
|
|
1510
|
+
'
|
|
1511
|
+
' @param {string} name the person you want to say hello to.
|
|
1512
|
+
sub sayHello(name as string = "world")
|
|
1125
1513
|
end sub
|
|
1514
|
+
`);
|
|
1515
|
+
const funcStatements = statements.filter(reflection_1.isFunctionStatement);
|
|
1516
|
+
const helloTrivia = funcStatements[0].getLeadingTrivia();
|
|
1517
|
+
(0, chai_config_spec_1.expect)(helloTrivia.length).to.be.greaterThan(0);
|
|
1518
|
+
(0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(3);
|
|
1519
|
+
});
|
|
1520
|
+
it('gets leading trivia from classes', () => {
|
|
1521
|
+
let { statements } = parse(`
|
|
1522
|
+
' hello
|
|
1523
|
+
' classes
|
|
1524
|
+
class Hello
|
|
1525
|
+
end class
|
|
1526
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1527
|
+
const classStatements = statements.filter(reflection_1.isClassStatement);
|
|
1528
|
+
const trivia = classStatements[0].getLeadingTrivia();
|
|
1529
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1530
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1531
|
+
});
|
|
1532
|
+
it('gets leading trivia from functions with annotations', () => {
|
|
1533
|
+
let { statements } = parse(`
|
|
1534
|
+
' hello comment 1
|
|
1535
|
+
' hello comment 2
|
|
1536
|
+
@annotation
|
|
1537
|
+
sub sayHello(name as string = "world")
|
|
1538
|
+
end sub
|
|
1539
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1540
|
+
const funcStatements = statements.filter(reflection_1.isFunctionStatement);
|
|
1541
|
+
const helloTrivia = funcStatements[0].getLeadingTrivia();
|
|
1542
|
+
(0, chai_config_spec_1.expect)(helloTrivia.length).to.be.greaterThan(0);
|
|
1543
|
+
(0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1544
|
+
});
|
|
1545
|
+
it('gets leading trivia from class methods', () => {
|
|
1546
|
+
let { statements } = parse(`
|
|
1547
|
+
' hello
|
|
1548
|
+
' classes
|
|
1549
|
+
class Hello
|
|
1550
|
+
|
|
1551
|
+
' Gets the value of PI
|
|
1552
|
+
' Not a dessert
|
|
1553
|
+
function getPi() as float
|
|
1554
|
+
return 3.14
|
|
1555
|
+
end function
|
|
1556
|
+
|
|
1557
|
+
' Gets a dessert
|
|
1558
|
+
function getPie() as string
|
|
1559
|
+
return "Apple Pie"
|
|
1560
|
+
end function
|
|
1561
|
+
end class
|
|
1562
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1563
|
+
const classStatement = statements.filter(reflection_1.isClassStatement)[0];
|
|
1564
|
+
const methodStatements = classStatement.methods;
|
|
1565
|
+
// function getPi()
|
|
1566
|
+
let trivia = methodStatements[0].getLeadingTrivia();
|
|
1567
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1568
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1569
|
+
// function getPie()
|
|
1570
|
+
trivia = methodStatements[1].getLeadingTrivia();
|
|
1571
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1572
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1573
|
+
});
|
|
1574
|
+
it('gets leading trivia from class fields', () => {
|
|
1575
|
+
let { statements } = parse(`
|
|
1576
|
+
' hello
|
|
1577
|
+
' classes
|
|
1578
|
+
class Thing
|
|
1579
|
+
' like the sky
|
|
1580
|
+
' or a blueberry, evn though that's purple
|
|
1581
|
+
color = "blue"
|
|
1582
|
+
|
|
1583
|
+
' My name
|
|
1584
|
+
public name as string
|
|
1585
|
+
|
|
1586
|
+
' Only I know how old I am
|
|
1587
|
+
private age = 42
|
|
1588
|
+
end class
|
|
1589
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1590
|
+
const classStatement = statements.filter(reflection_1.isClassStatement)[0];
|
|
1591
|
+
const fieldStatements = classStatement.fields;
|
|
1592
|
+
// color = "blue"
|
|
1593
|
+
let trivia = fieldStatements[0].getLeadingTrivia();
|
|
1594
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1595
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1596
|
+
// public name as string
|
|
1597
|
+
trivia = fieldStatements[1].getLeadingTrivia();
|
|
1598
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1599
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1600
|
+
// private age = 42
|
|
1601
|
+
trivia = fieldStatements[2].getLeadingTrivia();
|
|
1602
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1603
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1604
|
+
});
|
|
1605
|
+
it('gets leading trivia from interfaces', () => {
|
|
1606
|
+
let { statements } = parse(`
|
|
1607
|
+
' Description of interface
|
|
1608
|
+
interface myIface
|
|
1609
|
+
' comment
|
|
1610
|
+
someField as integer
|
|
1611
|
+
|
|
1612
|
+
'comment
|
|
1613
|
+
function someFunc() as string
|
|
1614
|
+
end interface
|
|
1615
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1616
|
+
const ifaceStatement = statements.filter(reflection_1.isInterfaceStatement)[0];
|
|
1617
|
+
const fieldStatements = ifaceStatement.fields;
|
|
1618
|
+
const methodStatements = ifaceStatement.methods;
|
|
1619
|
+
// interface myIface
|
|
1620
|
+
let trivia = ifaceStatement.getLeadingTrivia();
|
|
1621
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1622
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1623
|
+
// someField as integer
|
|
1624
|
+
trivia = fieldStatements[0].getLeadingTrivia();
|
|
1625
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1626
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1627
|
+
// function someFunc() as string
|
|
1628
|
+
trivia = methodStatements[0].getLeadingTrivia();
|
|
1629
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1630
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1631
|
+
});
|
|
1632
|
+
it('gets leading trivia from namespaces', () => {
|
|
1633
|
+
let { statements } = parse(`
|
|
1634
|
+
' Description of interface
|
|
1635
|
+
namespace Nested.Name.Space
|
|
1126
1636
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1637
|
+
end namespace
|
|
1638
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1639
|
+
const nameSpaceStatement = statements.filter(reflection_1.isNamespaceStatement)[0];
|
|
1640
|
+
// namespace Nested.Name.Space
|
|
1641
|
+
let trivia = nameSpaceStatement.getLeadingTrivia();
|
|
1642
|
+
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1643
|
+
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1644
|
+
});
|
|
1645
|
+
});
|
|
1646
|
+
describe('unary/binary ordering', () => {
|
|
1647
|
+
it('creates the correct operator order for `not x = x` code', () => {
|
|
1648
|
+
let { diagnostics, statements } = parse(`
|
|
1649
|
+
function isStrNotEmpty(myStr as string) as boolean
|
|
1650
|
+
return not myStr = ""
|
|
1651
|
+
end function
|
|
1652
|
+
`);
|
|
1653
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1654
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1655
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1656
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1657
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
|
|
1658
|
+
});
|
|
1659
|
+
it('creates the correct operator order for `not x + x` code', () => {
|
|
1660
|
+
let { diagnostics, statements } = parse(`
|
|
1661
|
+
function tryStuff() as integer
|
|
1662
|
+
return not 1 + 3 ' same as "not (3)" ... eg. the "flipped bits" of 3 (0000 0011) -> 1111 1100, or -4
|
|
1663
|
+
end function
|
|
1664
|
+
`);
|
|
1665
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1666
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1667
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1668
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1669
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
|
|
1670
|
+
});
|
|
1671
|
+
it('creates the correct operator order for `x = not x` code', () => {
|
|
1672
|
+
let { diagnostics, statements } = parse(`
|
|
1673
|
+
function tryStuff() as boolean
|
|
1674
|
+
return 4 = not -5 ' same as "4 = 4"
|
|
1129
1675
|
end function
|
|
1676
|
+
`);
|
|
1677
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1678
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1679
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1680
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn)).to.be.true;
|
|
1681
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(insideReturn.left)).to.be.true;
|
|
1682
|
+
const right = insideReturn.right;
|
|
1683
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right)).to.be.true;
|
|
1684
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right.right)).to.be.true; // not ( - ( 5))
|
|
1685
|
+
});
|
|
1686
|
+
it('allows multiple nots', () => {
|
|
1687
|
+
let { diagnostics, statements } = parse(`
|
|
1688
|
+
function tryStuff() as integer
|
|
1689
|
+
return not not not 4
|
|
1690
|
+
end function
|
|
1691
|
+
`);
|
|
1692
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1693
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1694
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1695
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1696
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
|
|
1697
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
|
|
1698
|
+
});
|
|
1699
|
+
it('allows multiple -', () => {
|
|
1700
|
+
let { diagnostics, statements } = parse(`
|
|
1701
|
+
function tryStuff() as integer
|
|
1702
|
+
return - - - 4
|
|
1703
|
+
end function
|
|
1704
|
+
`);
|
|
1705
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1706
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
|
|
1707
|
+
const insideReturn = statements[0].func.body.statements[0].value;
|
|
1708
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1709
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
|
|
1710
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
|
|
1711
|
+
});
|
|
1712
|
+
});
|
|
1713
|
+
describe('typecast statement', () => {
|
|
1714
|
+
it('allows typecast statement ', () => {
|
|
1715
|
+
let { diagnostics, statements } = parse(`
|
|
1716
|
+
typeCAST m AS roAssociativeArray
|
|
1130
1717
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1131
|
-
testHelpers_spec_1.expectZeroDiagnostics(
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1718
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1719
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastStatement)(statements[0])).to.be.true;
|
|
1720
|
+
const stmt = statements[0];
|
|
1721
|
+
(0, chai_config_spec_1.expect)(stmt.tokens.typecast.text).to.eq('typeCAST');
|
|
1722
|
+
(0, chai_config_spec_1.expect)(stmt.typecastExpression).to.exist;
|
|
1135
1723
|
});
|
|
1136
|
-
it('
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1724
|
+
it('is disallowed in brightscript mode', () => {
|
|
1725
|
+
let { diagnostics } = parse(`
|
|
1726
|
+
typecast m AS roAssociativeArray
|
|
1727
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
1728
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
1729
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typecast statements')
|
|
1730
|
+
]);
|
|
1731
|
+
});
|
|
1732
|
+
it('allows `typecast` for function name', () => {
|
|
1733
|
+
let { statements, diagnostics } = parse(`
|
|
1734
|
+
function typecast() as integer
|
|
1735
|
+
return 1
|
|
1736
|
+
end function
|
|
1737
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1738
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1739
|
+
(0, chai_config_spec_1.expect)(statements[0].tokens.name.text).to.eq('typecast');
|
|
1740
|
+
});
|
|
1741
|
+
it('allows `typecast` for variable name', () => {
|
|
1742
|
+
let { statements, diagnostics } = parse(`
|
|
1743
|
+
function foo() as integer
|
|
1744
|
+
typecast = 1
|
|
1745
|
+
return typecast
|
|
1746
|
+
end function
|
|
1747
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1748
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1749
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[0].tokens.name.text).to.eq('typecast');
|
|
1750
|
+
});
|
|
1751
|
+
it('is allowed in function', () => {
|
|
1752
|
+
let { diagnostics } = parse(`
|
|
1753
|
+
function foo() as integer
|
|
1754
|
+
typecast m as MyObject
|
|
1755
|
+
return m.getNum()
|
|
1756
|
+
end function
|
|
1757
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1758
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1759
|
+
});
|
|
1760
|
+
it('is allowed in function literal', () => {
|
|
1761
|
+
let { diagnostics } = parse(`
|
|
1762
|
+
interface PiGetter
|
|
1763
|
+
pi as float
|
|
1764
|
+
function getPi() as float
|
|
1765
|
+
end interface
|
|
1766
|
+
|
|
1767
|
+
function makePiGetter() as object
|
|
1768
|
+
x = {
|
|
1769
|
+
pi: 3.14,
|
|
1770
|
+
getPi: function() as float
|
|
1771
|
+
typecast m as PiGetter
|
|
1772
|
+
return m.pi
|
|
1773
|
+
end function
|
|
1774
|
+
}
|
|
1775
|
+
return x
|
|
1776
|
+
end function
|
|
1777
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1778
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1779
|
+
});
|
|
1780
|
+
});
|
|
1781
|
+
describe('conditional compilation', () => {
|
|
1782
|
+
it('contains code from conditional compile blocks', () => {
|
|
1783
|
+
let { diagnostics, ast } = parse(`
|
|
1784
|
+
sub foo()
|
|
1785
|
+
#if DEBUG
|
|
1786
|
+
print "hello"
|
|
1787
|
+
#end if
|
|
1788
|
+
end sub
|
|
1789
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: true });
|
|
1790
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1791
|
+
const funcBlock = ast.statements[0].func.body;
|
|
1792
|
+
(0, chai_config_spec_1.expect)(funcBlock.statements.length).to.eq(1);
|
|
1793
|
+
const ccStmt = funcBlock.statements[0];
|
|
1794
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
1795
|
+
const printStmt = ccStmt.thenBranch.statements[0];
|
|
1796
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
|
|
1797
|
+
});
|
|
1798
|
+
it('contains code from conditional compile else blocks', () => {
|
|
1799
|
+
let { diagnostics, ast } = parse(`
|
|
1800
|
+
sub foo()
|
|
1801
|
+
#if DEBUG
|
|
1802
|
+
m.pi = 3.14
|
|
1803
|
+
#else
|
|
1804
|
+
print "hello"
|
|
1805
|
+
#end if
|
|
1143
1806
|
end sub
|
|
1144
1807
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1145
|
-
testHelpers_spec_1.expectZeroDiagnostics(
|
|
1146
|
-
const
|
|
1147
|
-
|
|
1808
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1809
|
+
const funcBlock = ast.statements[0].func.body;
|
|
1810
|
+
const ccStmt = funcBlock.statements[0];
|
|
1811
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
1812
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
|
|
1813
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBlock)(ccStmt.elseBranch)).to.true;
|
|
1814
|
+
const printStmt = ccStmt.elseBranch.statements[0];
|
|
1815
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
|
|
1148
1816
|
});
|
|
1149
|
-
it('
|
|
1150
|
-
|
|
1151
|
-
sub
|
|
1817
|
+
it('contains code from conditional compile else if blocks', () => {
|
|
1818
|
+
let { diagnostics, ast } = parse(`
|
|
1819
|
+
sub foo()
|
|
1820
|
+
#if DEBUG
|
|
1821
|
+
m.pi = 3.14
|
|
1822
|
+
#else if PROD
|
|
1823
|
+
print "hello"
|
|
1824
|
+
#end if
|
|
1825
|
+
end sub
|
|
1826
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1827
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1828
|
+
const funcBlock = ast.statements[0].func.body;
|
|
1829
|
+
const ccStmt = funcBlock.statements[0];
|
|
1830
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
1831
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
|
|
1832
|
+
const elseBranch = ccStmt.elseBranch;
|
|
1833
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
1834
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('PROD');
|
|
1835
|
+
const printStmt = elseBranch.thenBranch.statements[0];
|
|
1836
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
|
|
1837
|
+
});
|
|
1838
|
+
it('contains code from multiple conditional compile else if blocks', () => {
|
|
1839
|
+
let { diagnostics, ast } = parse(`
|
|
1840
|
+
sub foo()
|
|
1841
|
+
#if DEBUG
|
|
1842
|
+
m.pi = 3.14
|
|
1843
|
+
#else if PROD
|
|
1844
|
+
print "hello"
|
|
1845
|
+
#else if ABC
|
|
1846
|
+
print "hello"
|
|
1847
|
+
#else if DEF
|
|
1848
|
+
print "hello"
|
|
1849
|
+
#else if HIJ
|
|
1850
|
+
print "hello"
|
|
1851
|
+
#else
|
|
1852
|
+
x = 78
|
|
1853
|
+
#end if
|
|
1854
|
+
end sub
|
|
1855
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1856
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1857
|
+
const funcBlock = ast.statements[0].func.body;
|
|
1858
|
+
const ccStmt = funcBlock.statements[0];
|
|
1859
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
1860
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
|
|
1861
|
+
let elseBranch = ccStmt.elseBranch;
|
|
1862
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
1863
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('PROD');
|
|
1864
|
+
elseBranch = elseBranch.elseBranch;
|
|
1865
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
1866
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('ABC');
|
|
1867
|
+
elseBranch = elseBranch.elseBranch;
|
|
1868
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
1869
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('DEF');
|
|
1870
|
+
elseBranch = elseBranch.elseBranch;
|
|
1871
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
1872
|
+
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('HIJ');
|
|
1873
|
+
let lastElse = elseBranch.elseBranch;
|
|
1874
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isBlock)(lastElse)).to.true;
|
|
1875
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(lastElse.statements[0])).to.true;
|
|
1876
|
+
});
|
|
1877
|
+
it('allows empty conditional compilation blocks', () => {
|
|
1878
|
+
let { diagnostics, ast } = parse(`
|
|
1879
|
+
#if DEBUG
|
|
1880
|
+
#else if PROD
|
|
1881
|
+
#else
|
|
1882
|
+
#end if
|
|
1883
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1884
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1885
|
+
const ccStmt = ast.statements[0];
|
|
1886
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
1887
|
+
(0, chai_config_spec_1.expect)(ccStmt.thenBranch.statements.length).to.eq(0);
|
|
1888
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.thenBranch.statements.length).to.eq(0);
|
|
1889
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.elseBranch.statements.length).to.eq(0);
|
|
1890
|
+
});
|
|
1891
|
+
it('allows only comments in compilation blocks', () => {
|
|
1892
|
+
let { diagnostics, ast } = parse(`
|
|
1893
|
+
' before if
|
|
1894
|
+
#if DEBUG
|
|
1895
|
+
' this is debug
|
|
1896
|
+
#else if PROD
|
|
1897
|
+
' this is prod
|
|
1898
|
+
#else
|
|
1899
|
+
' this is neither
|
|
1900
|
+
#end if
|
|
1901
|
+
' after if
|
|
1902
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1903
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1904
|
+
const ccStmt = ast.statements[0];
|
|
1905
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
1906
|
+
(0, chai_config_spec_1.expect)(ccStmt.thenBranch.statements.length).to.eq(0);
|
|
1907
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.thenBranch.statements.length).to.eq(0);
|
|
1908
|
+
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.elseBranch.statements.length).to.eq(0);
|
|
1909
|
+
});
|
|
1910
|
+
it('has no error when safely closing block', () => {
|
|
1911
|
+
let { diagnostics } = parse(`
|
|
1912
|
+
sub foo()
|
|
1913
|
+
#if DEBUG
|
|
1914
|
+
if m.enabled
|
|
1915
|
+
print "hello"
|
|
1916
|
+
end if
|
|
1917
|
+
#end if
|
|
1918
|
+
end sub
|
|
1919
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
1920
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1921
|
+
});
|
|
1922
|
+
it('has error when unsafely closing block', () => {
|
|
1923
|
+
let { diagnostics } = parse(`
|
|
1924
|
+
sub foo()
|
|
1925
|
+
if m.enabled
|
|
1926
|
+
#if DEBUG
|
|
1927
|
+
print "hello"
|
|
1928
|
+
end if
|
|
1929
|
+
#end if
|
|
1152
1930
|
end sub
|
|
1153
1931
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1154
|
-
testHelpers_spec_1.
|
|
1155
|
-
|
|
1156
|
-
['p1', new DynamicType_1.DynamicType(), util_1.default.createRange(1, 26, 1, 28)],
|
|
1157
|
-
['p2', new StringType_1.StringType(), util_1.default.createRange(1, 30, 1, 32)],
|
|
1158
|
-
['p3', new IntegerType_1.IntegerType(), util_1.default.createRange(1, 44, 1, 46)]
|
|
1932
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
1933
|
+
DiagnosticMessages_1.DiagnosticMessages.unsafeUnmatchedTerminatorInConditionalCompileBlock('end if').message
|
|
1159
1934
|
]);
|
|
1160
1935
|
});
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1936
|
+
it('has error when unsafely opening block', () => {
|
|
1937
|
+
let { diagnostics } = parse(`
|
|
1938
|
+
sub foo()
|
|
1939
|
+
#if DEBUG
|
|
1940
|
+
if m.enabled
|
|
1941
|
+
print "hello"
|
|
1942
|
+
#end if
|
|
1943
|
+
end if
|
|
1944
|
+
end sub
|
|
1945
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: true });
|
|
1946
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
1947
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedEndIfToCloseIfStatement({ line: 3, character: 20 }).message,
|
|
1948
|
+
DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('end if').message
|
|
1949
|
+
]);
|
|
1950
|
+
});
|
|
1951
|
+
it('has no diagnostics from false blocks', () => {
|
|
1952
|
+
let { diagnostics } = parse(`
|
|
1953
|
+
sub foo()
|
|
1954
|
+
#if DEBUG
|
|
1955
|
+
blah blah blah
|
|
1956
|
+
#end if
|
|
1957
|
+
|
|
1958
|
+
#if false
|
|
1959
|
+
there are no diagnostics here
|
|
1960
|
+
#end if
|
|
1168
1961
|
end sub
|
|
1962
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: false });
|
|
1963
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1964
|
+
});
|
|
1965
|
+
it('allows #if not bs_const', () => {
|
|
1966
|
+
let { diagnostics } = parse(`
|
|
1967
|
+
sub foo()
|
|
1968
|
+
#if not DEBUG
|
|
1969
|
+
print "not debug"
|
|
1970
|
+
#end if
|
|
1971
|
+
end sub
|
|
1972
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: false });
|
|
1973
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1974
|
+
});
|
|
1975
|
+
it('allows #elseif not bs_const', () => {
|
|
1976
|
+
let { diagnostics } = parse(`
|
|
1977
|
+
sub foo()
|
|
1978
|
+
#if DEBUG
|
|
1979
|
+
print "debug"
|
|
1980
|
+
#else if not STAGING
|
|
1981
|
+
print "not debug and not staging"
|
|
1982
|
+
#end if
|
|
1983
|
+
end sub
|
|
1984
|
+
`, Parser_1.ParseMode.BrighterScript, { debug: false, staging: false });
|
|
1985
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1986
|
+
});
|
|
1987
|
+
describe('#const', () => {
|
|
1988
|
+
it('parses #const', () => {
|
|
1989
|
+
let { diagnostics, ast } = parse(`
|
|
1990
|
+
#const test = true
|
|
1991
|
+
sub foo()
|
|
1992
|
+
#const debug = test
|
|
1993
|
+
end sub
|
|
1994
|
+
# const spaces = false
|
|
1169
1995
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1170
|
-
testHelpers_spec_1.expectZeroDiagnostics(
|
|
1171
|
-
const
|
|
1172
|
-
|
|
1996
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1997
|
+
//#const test = true
|
|
1998
|
+
let ccc = ast.statements[0];
|
|
1999
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
|
|
2000
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('test');
|
|
2001
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(ccc.assignment.value)).to.be.true;
|
|
2002
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.value.text).to.eq('true');
|
|
2003
|
+
//#const debug = test
|
|
2004
|
+
ccc = ast.statements[1].func.body.statements[0];
|
|
2005
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
|
|
2006
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('debug');
|
|
2007
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)(ccc.assignment.value)).to.be.true;
|
|
2008
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.name.text).to.eq('test');
|
|
2009
|
+
//# const spaces = false
|
|
2010
|
+
ccc = ast.statements[2];
|
|
2011
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
|
|
2012
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('spaces');
|
|
2013
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(ccc.assignment.value)).to.be.true;
|
|
2014
|
+
(0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.value.text).to.eq('false');
|
|
1173
2015
|
});
|
|
1174
|
-
it('
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
2016
|
+
it('has diagnostic if no lhs', () => {
|
|
2017
|
+
let { diagnostics } = parse(`
|
|
2018
|
+
#const test
|
|
2019
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2020
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2021
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedOperatorAfterIdentifier([TokenKind_1.TokenKind.Equal], 'test').message
|
|
2022
|
+
]);
|
|
2023
|
+
});
|
|
2024
|
+
it('has diagnostic if invalid operator', () => {
|
|
2025
|
+
let { diagnostics } = parse(`
|
|
2026
|
+
#const test += other
|
|
1181
2027
|
`, Parser_1.ParseMode.BrighterScript);
|
|
1182
|
-
testHelpers_spec_1.
|
|
1183
|
-
|
|
1184
|
-
|
|
2028
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2029
|
+
DiagnosticMessages_1.DiagnosticMessages.expectedOperatorAfterIdentifier([TokenKind_1.TokenKind.Equal], 'test').message
|
|
2030
|
+
]);
|
|
2031
|
+
});
|
|
2032
|
+
it('has diagnostic if invalid lhs', () => {
|
|
2033
|
+
let { diagnostics } = parse(`
|
|
2034
|
+
#const test = 4
|
|
2035
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2036
|
+
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2037
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidHashConstValue().message
|
|
2038
|
+
]);
|
|
2039
|
+
});
|
|
2040
|
+
});
|
|
2041
|
+
describe('#error', () => {
|
|
2042
|
+
it('parses #error', () => {
|
|
2043
|
+
let { diagnostics, ast } = parse(`
|
|
2044
|
+
#error
|
|
2045
|
+
sub foo()
|
|
2046
|
+
#error this is a LONG "message" :: with colons, etc.
|
|
2047
|
+
end sub
|
|
2048
|
+
# error this one has spaces
|
|
2049
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2050
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2051
|
+
//#error
|
|
2052
|
+
let cce = ast.statements[0];
|
|
2053
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
|
|
2054
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
|
|
2055
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('');
|
|
2056
|
+
//#error this is a long "message" :: with colons, etc.
|
|
2057
|
+
cce = ast.statements[1].func.body.statements[0];
|
|
2058
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
|
|
2059
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
|
|
2060
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('this is a LONG "message" :: with colons, etc.');
|
|
2061
|
+
//# error this one has spaces
|
|
2062
|
+
cce = ast.statements[2];
|
|
2063
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
|
|
2064
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
|
|
2065
|
+
(0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('this one has spaces');
|
|
1185
2066
|
});
|
|
1186
2067
|
});
|
|
1187
2068
|
});
|
|
2069
|
+
describe('alias statement', () => {
|
|
2070
|
+
it('allows alias statement ', () => {
|
|
2071
|
+
let { diagnostics, statements } = parse(`
|
|
2072
|
+
ALIAS x = lcase
|
|
2073
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2074
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2075
|
+
(0, chai_config_spec_1.expect)((0, reflection_1.isAliasStatement)(statements[0])).to.be.true;
|
|
2076
|
+
const stmt = statements[0];
|
|
2077
|
+
(0, chai_config_spec_1.expect)(stmt.tokens.alias.text).to.eq('ALIAS');
|
|
2078
|
+
(0, chai_config_spec_1.expect)(stmt.value).to.exist;
|
|
2079
|
+
});
|
|
2080
|
+
it('is disallowed in brightscript mode', () => {
|
|
2081
|
+
let { diagnostics } = parse(`
|
|
2082
|
+
alias x = lcase
|
|
2083
|
+
`, Parser_1.ParseMode.BrightScript);
|
|
2084
|
+
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2085
|
+
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('alias statements')
|
|
2086
|
+
]);
|
|
2087
|
+
});
|
|
2088
|
+
it('allows `alias` for function name', () => {
|
|
2089
|
+
let { statements, diagnostics } = parse(`
|
|
2090
|
+
function alias() as integer
|
|
2091
|
+
return 1
|
|
2092
|
+
end function
|
|
2093
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2094
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2095
|
+
(0, chai_config_spec_1.expect)(statements[0].tokens.name.text).to.eq('alias');
|
|
2096
|
+
});
|
|
2097
|
+
it('allows `alias` for variable name', () => {
|
|
2098
|
+
let { statements, diagnostics } = parse(`
|
|
2099
|
+
function foo() as integer
|
|
2100
|
+
alias = 1
|
|
2101
|
+
return alias
|
|
2102
|
+
end function
|
|
2103
|
+
`, Parser_1.ParseMode.BrighterScript);
|
|
2104
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2105
|
+
(0, chai_config_spec_1.expect)(statements[0].func.body.statements[0].tokens.name.text).to.eq('alias');
|
|
2106
|
+
});
|
|
2107
|
+
});
|
|
1188
2108
|
});
|
|
1189
|
-
function parse(text, mode) {
|
|
1190
|
-
let { tokens } =
|
|
2109
|
+
function parse(text, mode, bsConsts = {}) {
|
|
2110
|
+
let { tokens } = Lexer_1.Lexer.scan(text);
|
|
2111
|
+
const bsConstMap = new Map();
|
|
2112
|
+
for (const constName in bsConsts) {
|
|
2113
|
+
bsConstMap.set(constName.toLowerCase(), bsConsts[constName]);
|
|
2114
|
+
}
|
|
1191
2115
|
return Parser_1.Parser.parse(tokens, {
|
|
1192
|
-
mode: mode
|
|
2116
|
+
mode: mode,
|
|
2117
|
+
bsConsts: bsConstMap
|
|
1193
2118
|
});
|
|
1194
2119
|
}
|
|
2120
|
+
exports.parse = parse;
|
|
1195
2121
|
function rangeToArray(range) {
|
|
1196
2122
|
return [
|
|
1197
2123
|
range.start.line,
|
|
@@ -1202,15 +2128,16 @@ function rangeToArray(range) {
|
|
|
1202
2128
|
}
|
|
1203
2129
|
exports.rangeToArray = rangeToArray;
|
|
1204
2130
|
function expectCommentWithText(stat, text) {
|
|
1205
|
-
|
|
1206
|
-
|
|
2131
|
+
const trivia = stat.getLeadingTrivia();
|
|
2132
|
+
if (trivia) {
|
|
2133
|
+
(0, chai_config_spec_1.expect)(trivia.filter(tok => tok.kind === TokenKind_1.TokenKind.Comment).map(t => t.text).join('\n')).to.equal(text);
|
|
1207
2134
|
}
|
|
1208
2135
|
else {
|
|
1209
2136
|
failStatementType(stat, 'Comment');
|
|
1210
2137
|
}
|
|
1211
2138
|
}
|
|
1212
2139
|
function failStatementType(stat, type) {
|
|
1213
|
-
|
|
2140
|
+
chai_config_spec_1.assert.fail(`Statement ${stat.constructor.name} line ${stat.range.start.line} is not a ${type}`);
|
|
1214
2141
|
}
|
|
1215
2142
|
exports.failStatementType = failStatementType;
|
|
1216
2143
|
//# sourceMappingURL=Parser.spec.js.map
|