brighterscript 1.0.0-alpha.50 → 1.0.0-alpha.51
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/README.md +3 -0
- package/bsconfig.schema.json +75 -0
- package/dist/BsConfig.d.ts +90 -5
- package/dist/CodeActionUtil.d.ts +17 -0
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +16 -12
- package/dist/CommentFlagProcessor.js +141 -59
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/CrossScopeValidator.js +13 -5
- package/dist/CrossScopeValidator.js.map +1 -1
- package/dist/DiagnosticManager.d.ts +1 -0
- package/dist/DiagnosticManager.js +25 -9
- package/dist/DiagnosticManager.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +61 -17
- package/dist/DiagnosticMessages.js +78 -24
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.d.ts +39 -2
- package/dist/LanguageServer.js +142 -5
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Program.d.ts +62 -1
- package/dist/Program.js +185 -13
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +1 -8
- package/dist/ProgramBuilder.js +31 -11
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +87 -6
- package/dist/Scope.js +76 -31
- package/dist/Scope.js.map +1 -1
- package/dist/ScopeNamespaceLookup.d.ts +73 -0
- package/dist/ScopeNamespaceLookup.js +242 -0
- package/dist/ScopeNamespaceLookup.js.map +1 -0
- package/dist/SymbolTable.d.ts +9 -2
- package/dist/SymbolTable.js +24 -14
- package/dist/SymbolTable.js.map +1 -1
- package/dist/astUtils/CachedLookups.js +3 -0
- package/dist/astUtils/CachedLookups.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +4 -1
- package/dist/astUtils/reflection.js +24 -4
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +2 -1
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +4 -2
- package/dist/bscPlugin/BscPlugin.js +10 -2
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +1 -1
- package/dist/bscPlugin/CallExpressionInfo.js +1 -2
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
- package/dist/bscPlugin/FileWriter.d.ts +13 -0
- package/dist/bscPlugin/FileWriter.js +56 -1
- package/dist/bscPlugin/FileWriter.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +106 -5
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +630 -126
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.d.ts +17 -0
- package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.js +66 -0
- package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.js.map +1 -0
- package/dist/bscPlugin/codeActions/codeActionHelpers.d.ts +18 -0
- package/dist/bscPlugin/codeActions/codeActionHelpers.js +31 -0
- package/dist/bscPlugin/codeActions/codeActionHelpers.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.js +5 -5
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/definition/DefinitionProvider.js +8 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.js +11 -3
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.d.ts +7 -0
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.js +77 -0
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.js.map +1 -0
- package/dist/bscPlugin/serialize/FileSerializer.d.ts +1 -1
- package/dist/bscPlugin/serialize/FileSerializer.js +12 -7
- package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -1
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +7 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +87 -1
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +14 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +97 -21
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +17 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +162 -4
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/XmlFileValidator.js +14 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
- package/dist/cli.js +13 -0
- package/dist/cli.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +51 -1
- package/dist/diagnosticUtils.js +222 -1
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/files/BrsFile.d.ts +18 -2
- package/dist/files/BrsFile.js +87 -6
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/XmlFile.js +2 -1
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/interfaces.d.ts +68 -23
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Lexer.js +4 -5
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Token.d.ts +1 -1
- package/dist/lexer/TokenKind.d.ts +8 -0
- package/dist/lexer/TokenKind.js +21 -1
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/lsp/LspProject.d.ts +49 -1
- package/dist/lsp/Project.d.ts +33 -1
- package/dist/lsp/Project.js +129 -4
- package/dist/lsp/Project.js.map +1 -1
- package/dist/lsp/ProjectManager.d.ts +48 -2
- package/dist/lsp/ProjectManager.js +152 -9
- package/dist/lsp/ProjectManager.js.map +1 -1
- package/dist/lsp/worker/WorkerThreadProject.d.ts +27 -2
- package/dist/lsp/worker/WorkerThreadProject.js +16 -0
- package/dist/lsp/worker/WorkerThreadProject.js.map +1 -1
- package/dist/parser/AstNode.d.ts +3 -1
- package/dist/parser/AstNode.js +2 -0
- package/dist/parser/AstNode.js.map +1 -1
- package/dist/parser/Expression.d.ts +54 -5
- package/dist/parser/Expression.js +112 -7
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.d.ts +24 -1
- package/dist/parser/Parser.js +180 -41
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/SGParser.d.ts +1 -0
- package/dist/parser/SGParser.js +9 -0
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/Statement.d.ts +6 -1
- package/dist/parser/Statement.js +22 -14
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +4 -2
- package/dist/parser/TranspileState.js +10 -4
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/roku-types/data.json +210 -3
- package/dist/types/ArrayType.js +6 -1
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/BooleanType.js +1 -1
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/CallFuncableType.d.ts +1 -1
- package/dist/types/ClassType.js +3 -0
- package/dist/types/ClassType.js.map +1 -1
- package/dist/types/ComponentType.js +3 -0
- package/dist/types/ComponentType.js.map +1 -1
- package/dist/types/EnumType.js +3 -0
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/IntersectionType.js +3 -0
- package/dist/types/IntersectionType.js.map +1 -1
- package/dist/types/ReferenceType.js +6 -0
- package/dist/types/ReferenceType.js.map +1 -1
- package/dist/types/TypeStatementType.d.ts +1 -0
- package/dist/types/TypeStatementType.js +12 -1
- package/dist/types/TypeStatementType.js.map +1 -1
- package/dist/types/TypedFunctionType.js +20 -10
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/UnionType.js +3 -0
- package/dist/types/UnionType.js.map +1 -1
- package/dist/types/helpers.js +6 -0
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +42 -3
- package/dist/util.js +131 -7
- package/dist/util.js.map +1 -1
- package/package.json +24 -26
- package/dist/astUtils/CachedLookups.spec.d.ts +0 -1
- package/dist/astUtils/CachedLookups.spec.js +0 -39
- package/dist/astUtils/CachedLookups.spec.js.map +0 -1
- package/dist/astUtils/Editor.spec.d.ts +0 -1
- package/dist/astUtils/Editor.spec.js +0 -258
- package/dist/astUtils/Editor.spec.js.map +0 -1
- package/dist/astUtils/creators.spec.d.ts +0 -1
- package/dist/astUtils/creators.spec.js +0 -21
- package/dist/astUtils/creators.spec.js.map +0 -1
- package/dist/astUtils/reflection.spec.d.ts +0 -1
- package/dist/astUtils/reflection.spec.js +0 -392
- package/dist/astUtils/reflection.spec.js.map +0 -1
- package/dist/astUtils/stackedVisitor.spec.d.ts +0 -1
- package/dist/astUtils/stackedVisitor.spec.js +0 -79
- package/dist/astUtils/stackedVisitor.spec.js.map +0 -1
- package/dist/astUtils/visitors.spec.d.ts +0 -1
- package/dist/astUtils/visitors.spec.js +0 -1432
- package/dist/astUtils/visitors.spec.js.map +0 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +0 -311
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +0 -2512
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/definition/DefinitionProvider.spec.d.ts +0 -1
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js +0 -87
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +0 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +0 -991
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +0 -1
- package/dist/bscPlugin/references/ReferencesProvider.spec.js +0 -51
- package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +0 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +0 -564
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +0 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.js +0 -33
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +0 -1
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +0 -291
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +0 -245
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +0 -75
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +0 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +0 -1517
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +0 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +0 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +0 -6135
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +0 -1
- package/dist/common/Sequencer.spec.d.ts +0 -1
- package/dist/common/Sequencer.spec.js +0 -75
- package/dist/common/Sequencer.spec.js.map +0 -1
- package/dist/files/BrsFile.Class.spec.d.ts +0 -1
- package/dist/files/BrsFile.Class.spec.js +0 -2035
- package/dist/files/BrsFile.Class.spec.js.map +0 -1
- package/dist/files/BrsFile.spec.d.ts +0 -1
- package/dist/files/BrsFile.spec.js +0 -5848
- package/dist/files/BrsFile.spec.js.map +0 -1
- package/dist/files/LazyFileData.spec.d.ts +0 -1
- package/dist/files/LazyFileData.spec.js +0 -27
- package/dist/files/LazyFileData.spec.js.map +0 -1
- package/dist/files/XmlFile.spec.d.ts +0 -1
- package/dist/files/XmlFile.spec.js +0 -1173
- package/dist/files/XmlFile.spec.js.map +0 -1
- package/dist/files/tests/imports.spec.d.ts +0 -1
- package/dist/files/tests/imports.spec.js +0 -251
- package/dist/files/tests/imports.spec.js.map +0 -1
- package/dist/files/tests/optionalChaning.spec.d.ts +0 -1
- package/dist/files/tests/optionalChaning.spec.js +0 -152
- package/dist/files/tests/optionalChaning.spec.js.map +0 -1
- package/dist/lexer/Character.spec.d.ts +0 -1
- package/dist/lexer/Character.spec.js +0 -27
- package/dist/lexer/Character.spec.js.map +0 -1
- package/dist/lexer/Lexer.spec.d.ts +0 -1
- package/dist/lexer/Lexer.spec.js +0 -1345
- package/dist/lexer/Lexer.spec.js.map +0 -1
- package/dist/lsp/ActionQueue.spec.d.ts +0 -1
- package/dist/lsp/ActionQueue.spec.js +0 -80
- package/dist/lsp/ActionQueue.spec.js.map +0 -1
- package/dist/lsp/DocumentManager.spec.d.ts +0 -1
- package/dist/lsp/DocumentManager.spec.js +0 -103
- package/dist/lsp/DocumentManager.spec.js.map +0 -1
- package/dist/lsp/PathFilterer.spec.d.ts +0 -1
- package/dist/lsp/PathFilterer.spec.js +0 -182
- package/dist/lsp/PathFilterer.spec.js.map +0 -1
- package/dist/lsp/Project.spec.d.ts +0 -1
- package/dist/lsp/Project.spec.js +0 -267
- package/dist/lsp/Project.spec.js.map +0 -1
- package/dist/lsp/ProjectManager.spec.d.ts +0 -1
- package/dist/lsp/ProjectManager.spec.js +0 -913
- package/dist/lsp/ProjectManager.spec.js.map +0 -1
- package/dist/lsp/worker/MessageHandler.spec.d.ts +0 -1
- package/dist/lsp/worker/MessageHandler.spec.js +0 -64
- package/dist/lsp/worker/MessageHandler.spec.js.map +0 -1
- package/dist/lsp/worker/WorkerPool.spec.d.ts +0 -1
- package/dist/lsp/worker/WorkerPool.spec.js +0 -59
- package/dist/lsp/worker/WorkerPool.spec.js.map +0 -1
- package/dist/lsp/worker/WorkerThreadProject.spec.d.ts +0 -2
- package/dist/lsp/worker/WorkerThreadProject.spec.js +0 -71
- package/dist/lsp/worker/WorkerThreadProject.spec.js.map +0 -1
- package/dist/parser/AstNode.spec.d.ts +0 -1
- package/dist/parser/AstNode.spec.js +0 -1455
- package/dist/parser/AstNode.spec.js.map +0 -1
- package/dist/parser/BrightScriptDocParser.spec.d.ts +0 -1
- package/dist/parser/BrightScriptDocParser.spec.js +0 -310
- package/dist/parser/BrightScriptDocParser.spec.js.map +0 -1
- package/dist/parser/Expression.spec.d.ts +0 -1
- package/dist/parser/Expression.spec.js +0 -40
- package/dist/parser/Expression.spec.js.map +0 -1
- package/dist/parser/Parser.Class.spec.d.ts +0 -1
- package/dist/parser/Parser.Class.spec.js +0 -520
- package/dist/parser/Parser.Class.spec.js.map +0 -1
- package/dist/parser/Parser.spec.d.ts +0 -6
- package/dist/parser/Parser.spec.js +0 -2802
- package/dist/parser/Parser.spec.js.map +0 -1
- package/dist/parser/SGParser.spec.d.ts +0 -1
- package/dist/parser/SGParser.spec.js +0 -130
- package/dist/parser/SGParser.spec.js.map +0 -1
- package/dist/parser/Statement.spec.d.ts +0 -1
- package/dist/parser/Statement.spec.js +0 -191
- package/dist/parser/Statement.spec.js.map +0 -1
- package/dist/parser/tests/Parser.spec.d.ts +0 -12
- package/dist/parser/tests/Parser.spec.js +0 -29
- package/dist/parser/tests/Parser.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/For.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/For.spec.js +0 -169
- package/dist/parser/tests/controlFlow/For.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +0 -140
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/If.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/If.spec.js +0 -694
- package/dist/parser/tests/controlFlow/If.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/While.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/While.spec.js +0 -114
- package/dist/parser/tests/controlFlow/While.spec.js.map +0 -1
- package/dist/parser/tests/expression/Additive.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Additive.spec.js +0 -107
- package/dist/parser/tests/expression/Additive.spec.js.map +0 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.d.ts +0 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +0 -304
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +0 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.d.ts +0 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +0 -342
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +0 -1
- package/dist/parser/tests/expression/Boolean.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Boolean.spec.js +0 -90
- package/dist/parser/tests/expression/Boolean.spec.js.map +0 -1
- package/dist/parser/tests/expression/Call.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Call.spec.js +0 -252
- package/dist/parser/tests/expression/Call.spec.js.map +0 -1
- package/dist/parser/tests/expression/Exponential.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Exponential.spec.js +0 -37
- package/dist/parser/tests/expression/Exponential.spec.js.map +0 -1
- package/dist/parser/tests/expression/Function.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Function.spec.js +0 -412
- package/dist/parser/tests/expression/Function.spec.js.map +0 -1
- package/dist/parser/tests/expression/Indexing.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Indexing.spec.js +0 -302
- package/dist/parser/tests/expression/Indexing.spec.js.map +0 -1
- package/dist/parser/tests/expression/Multiplicative.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +0 -67
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +0 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +0 -346
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.d.ts +0 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +0 -111
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +0 -1
- package/dist/parser/tests/expression/Primary.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Primary.spec.js +0 -165
- package/dist/parser/tests/expression/Primary.spec.js.map +0 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +0 -171
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/Relational.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Relational.spec.js +0 -83
- package/dist/parser/tests/expression/Relational.spec.js.map +0 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +0 -201
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +0 -389
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +0 -878
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TypeExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TypeExpression.spec.js +0 -126
- package/dist/parser/tests/expression/TypeExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/UnaryExpression.spec.js +0 -52
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +0 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.d.ts +0 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +0 -79
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +0 -1
- package/dist/parser/tests/statement/ConstStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ConstStatement.spec.js +0 -500
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Continue.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Continue.spec.js +0 -119
- package/dist/parser/tests/statement/Continue.spec.js.map +0 -1
- package/dist/parser/tests/statement/Declaration.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Declaration.spec.js +0 -114
- package/dist/parser/tests/statement/Declaration.spec.js.map +0 -1
- package/dist/parser/tests/statement/Dim.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Dim.spec.js +0 -80
- package/dist/parser/tests/statement/Dim.spec.js.map +0 -1
- package/dist/parser/tests/statement/Enum.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Enum.spec.js +0 -744
- package/dist/parser/tests/statement/Enum.spec.js.map +0 -1
- package/dist/parser/tests/statement/For.spec.d.ts +0 -1
- package/dist/parser/tests/statement/For.spec.js +0 -45
- package/dist/parser/tests/statement/For.spec.js.map +0 -1
- package/dist/parser/tests/statement/ForEach.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ForEach.spec.js +0 -36
- package/dist/parser/tests/statement/ForEach.spec.js.map +0 -1
- package/dist/parser/tests/statement/Function.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Function.spec.js +0 -343
- package/dist/parser/tests/statement/Function.spec.js.map +0 -1
- package/dist/parser/tests/statement/Goto.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Goto.spec.js +0 -51
- package/dist/parser/tests/statement/Goto.spec.js.map +0 -1
- package/dist/parser/tests/statement/Increment.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Increment.spec.js +0 -120
- package/dist/parser/tests/statement/Increment.spec.js.map +0 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +0 -110
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +0 -74
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Misc.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Misc.spec.js +0 -292
- package/dist/parser/tests/statement/Misc.spec.js.map +0 -1
- package/dist/parser/tests/statement/PrintStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +0 -200
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +0 -97
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Set.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Set.spec.js +0 -232
- package/dist/parser/tests/statement/Set.spec.js.map +0 -1
- package/dist/parser/tests/statement/Stop.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Stop.spec.js +0 -38
- package/dist/parser/tests/statement/Stop.spec.js.map +0 -1
- package/dist/parser/tests/statement/Throw.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Throw.spec.js +0 -38
- package/dist/parser/tests/statement/Throw.spec.js.map +0 -1
- package/dist/parser/tests/statement/TryCatch.spec.d.ts +0 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +0 -151
- package/dist/parser/tests/statement/TryCatch.spec.js.map +0 -1
- package/dist/preprocessor/Manifest.spec.d.ts +0 -1
- package/dist/preprocessor/Manifest.spec.js +0 -80
- package/dist/preprocessor/Manifest.spec.js.map +0 -1
- package/dist/types/ArrayType.spec.d.ts +0 -1
- package/dist/types/ArrayType.spec.js +0 -58
- package/dist/types/ArrayType.spec.js.map +0 -1
- package/dist/types/BooleanType.spec.d.ts +0 -1
- package/dist/types/BooleanType.spec.js +0 -18
- package/dist/types/BooleanType.spec.js.map +0 -1
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +0 -1
- package/dist/types/BuiltInInterfaceAdder.spec.js +0 -115
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +0 -1
- package/dist/types/ClassType.spec.d.ts +0 -1
- package/dist/types/ClassType.spec.js +0 -76
- package/dist/types/ClassType.spec.js.map +0 -1
- package/dist/types/DoubleType.spec.d.ts +0 -1
- package/dist/types/DoubleType.spec.js +0 -20
- package/dist/types/DoubleType.spec.js.map +0 -1
- package/dist/types/DynamicType.spec.d.ts +0 -1
- package/dist/types/DynamicType.spec.js +0 -23
- package/dist/types/DynamicType.spec.js.map +0 -1
- package/dist/types/EnumType.spec.d.ts +0 -1
- package/dist/types/EnumType.spec.js +0 -33
- package/dist/types/EnumType.spec.js.map +0 -1
- package/dist/types/FloatType.spec.d.ts +0 -1
- package/dist/types/FloatType.spec.js +0 -12
- package/dist/types/FloatType.spec.js.map +0 -1
- package/dist/types/IntegerType.spec.d.ts +0 -1
- package/dist/types/IntegerType.spec.js +0 -16
- package/dist/types/IntegerType.spec.js.map +0 -1
- package/dist/types/InterfaceType.spec.d.ts +0 -1
- package/dist/types/InterfaceType.spec.js +0 -227
- package/dist/types/InterfaceType.spec.js.map +0 -1
- package/dist/types/IntersectionType.spec.d.ts +0 -1
- package/dist/types/IntersectionType.spec.js +0 -150
- package/dist/types/IntersectionType.spec.js.map +0 -1
- package/dist/types/InvalidType.spec.d.ts +0 -1
- package/dist/types/InvalidType.spec.js +0 -16
- package/dist/types/InvalidType.spec.js.map +0 -1
- package/dist/types/LongIntegerType.spec.d.ts +0 -1
- package/dist/types/LongIntegerType.spec.js +0 -18
- package/dist/types/LongIntegerType.spec.js.map +0 -1
- package/dist/types/ObjectType.spec.d.ts +0 -1
- package/dist/types/ObjectType.spec.js +0 -12
- package/dist/types/ObjectType.spec.js.map +0 -1
- package/dist/types/ReferenceType.spec.d.ts +0 -1
- package/dist/types/ReferenceType.spec.js +0 -151
- package/dist/types/ReferenceType.spec.js.map +0 -1
- package/dist/types/StringType.spec.d.ts +0 -1
- package/dist/types/StringType.spec.js +0 -12
- package/dist/types/StringType.spec.js.map +0 -1
- package/dist/types/TypedFunctionType.spec.d.ts +0 -1
- package/dist/types/TypedFunctionType.spec.js +0 -122
- package/dist/types/TypedFunctionType.spec.js.map +0 -1
- package/dist/types/UnionType.spec.d.ts +0 -1
- package/dist/types/UnionType.spec.js +0 -205
- package/dist/types/UnionType.spec.js.map +0 -1
- package/dist/types/VoidType.spec.d.ts +0 -1
- package/dist/types/VoidType.spec.js +0 -12
- package/dist/types/VoidType.spec.js.map +0 -1
- package/dist/types/helper.spec.d.ts +0 -1
- package/dist/types/helper.spec.js +0 -174
- package/dist/types/helper.spec.js.map +0 -1
- package/dist/types/roFunctionType.spec.d.ts +0 -1
- package/dist/types/roFunctionType.spec.js +0 -20
- package/dist/types/roFunctionType.spec.js.map +0 -1
|
@@ -1,2802 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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");
|
|
7
|
-
const Expression_1 = require("./Expression");
|
|
8
|
-
const Parser_1 = require("./Parser");
|
|
9
|
-
const Statement_1 = require("./Statement");
|
|
10
|
-
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
11
|
-
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
12
|
-
const reflection_1 = require("../astUtils/reflection");
|
|
13
|
-
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
14
|
-
const visitors_1 = require("../astUtils/visitors");
|
|
15
|
-
const IntegerType_1 = require("../types/IntegerType");
|
|
16
|
-
const FloatType_1 = require("../types/FloatType");
|
|
17
|
-
const StringType_1 = require("../types/StringType");
|
|
18
|
-
const types_1 = require("../types");
|
|
19
|
-
const util_1 = require("../util");
|
|
20
|
-
const InlineInterfaceType_1 = require("../types/InlineInterfaceType");
|
|
21
|
-
describe('parser', () => {
|
|
22
|
-
it('emits empty object when empty token list is provided', () => {
|
|
23
|
-
let { ast, diagnostics } = Parser_1.Parser.parse([]);
|
|
24
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isBody)(ast)).to.be.true;
|
|
25
|
-
(0, chai_config_spec_1.expect)(ast.statements).to.be.empty;
|
|
26
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.empty;
|
|
27
|
-
});
|
|
28
|
-
describe('callfunc operator', () => {
|
|
29
|
-
it('is not allowed in brightscript mode', () => {
|
|
30
|
-
var _a;
|
|
31
|
-
let parser = parse(`
|
|
32
|
-
sub main(node as dynamic)
|
|
33
|
-
node@.doSomething(1, 2)
|
|
34
|
-
end sub
|
|
35
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
36
|
-
(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);
|
|
37
|
-
});
|
|
38
|
-
it('does not cause parse errors', () => {
|
|
39
|
-
var _a, _b, _c, _d, _e;
|
|
40
|
-
let parser = parse(`
|
|
41
|
-
sub main(node as dynamic)
|
|
42
|
-
node@.doSomething(1, 2)
|
|
43
|
-
end sub
|
|
44
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
45
|
-
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
46
|
-
(0, chai_config_spec_1.expect)((_e = (_d = (_c = (_b = parser.ast.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);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
it('flags function names with invalid characters', () => {
|
|
50
|
-
const { diagnostics } = Parser_1.Parser.parse(`
|
|
51
|
-
function alpha$() : end function
|
|
52
|
-
function beta%() : end function
|
|
53
|
-
function charlie!() : end function
|
|
54
|
-
function delta#() : end function
|
|
55
|
-
function echo&() : end function
|
|
56
|
-
`);
|
|
57
|
-
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
58
|
-
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('alpha$', '$'),
|
|
59
|
-
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('beta%', '%'),
|
|
60
|
-
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('charlie!', '!'),
|
|
61
|
-
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('delta#', '#'),
|
|
62
|
-
DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('echo&', '&')
|
|
63
|
-
]);
|
|
64
|
-
});
|
|
65
|
-
describe('optional chaining operator', () => {
|
|
66
|
-
function getExpression(text, options) {
|
|
67
|
-
const parser = parse(text, options === null || options === void 0 ? void 0 : options.parseMode);
|
|
68
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
69
|
-
const expressions = parser.ast.findChildren(reflection_1.isExpression);
|
|
70
|
-
if (options === null || options === void 0 ? void 0 : options.matcher) {
|
|
71
|
-
return expressions.find(options.matcher);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
return expressions[0];
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
it('works for ?.', () => {
|
|
78
|
-
const expression = getExpression(`value = person?.name`);
|
|
79
|
-
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.DottedGetExpression);
|
|
80
|
-
(0, chai_config_spec_1.expect)(expression.tokens.dot.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
|
|
81
|
-
});
|
|
82
|
-
it('works for ?[', () => {
|
|
83
|
-
const expression = getExpression(`value = person?["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
84
|
-
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
|
|
85
|
-
(0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftSquare);
|
|
86
|
-
(0, chai_config_spec_1.expect)(expression.tokens.questionDot).not.to.exist;
|
|
87
|
-
});
|
|
88
|
-
it('works for ?.[', () => {
|
|
89
|
-
var _a;
|
|
90
|
-
const expression = getExpression(`value = person?.["name"]`, { matcher: reflection_1.isIndexedGetExpression });
|
|
91
|
-
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
|
|
92
|
-
(0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.LeftSquareBracket);
|
|
93
|
-
(0, chai_config_spec_1.expect)((_a = expression.tokens.questionDot) === null || _a === void 0 ? void 0 : _a.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
|
|
94
|
-
});
|
|
95
|
-
it('works for ?@', () => {
|
|
96
|
-
const expression = getExpression(`value = someXml?@someAttr`);
|
|
97
|
-
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.XmlAttributeGetExpression);
|
|
98
|
-
(0, chai_config_spec_1.expect)(expression.tokens.at.kind).to.eql(TokenKind_1.TokenKind.QuestionAt);
|
|
99
|
-
});
|
|
100
|
-
it('works for ?(', () => {
|
|
101
|
-
const expression = getExpression(`value = person.getName?()`);
|
|
102
|
-
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
|
|
103
|
-
(0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
104
|
-
});
|
|
105
|
-
it('works for print statements using question mark', () => {
|
|
106
|
-
const { ast } = parse(`
|
|
107
|
-
?[1]
|
|
108
|
-
?(1+1)
|
|
109
|
-
`);
|
|
110
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceOf(Statement_1.PrintStatement);
|
|
111
|
-
(0, chai_config_spec_1.expect)(ast.statements[1]).to.be.instanceOf(Statement_1.PrintStatement);
|
|
112
|
-
});
|
|
113
|
-
//TODO enable this once we properly parse IIFEs
|
|
114
|
-
it.skip('works for ?( in anonymous function', () => {
|
|
115
|
-
const expression = getExpression(`thing = (function() : end function)?()`);
|
|
116
|
-
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
|
|
117
|
-
(0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
118
|
-
});
|
|
119
|
-
it('works for ?( in new call', () => {
|
|
120
|
-
const expression = getExpression(`thing = new Person?()`, { parseMode: Parser_1.ParseMode.BrighterScript });
|
|
121
|
-
(0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.NewExpression);
|
|
122
|
-
(0, chai_config_spec_1.expect)(expression.call.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
|
|
123
|
-
});
|
|
124
|
-
it('distinguishes between optional chaining and ternary expression', () => {
|
|
125
|
-
const parser = parse(`
|
|
126
|
-
sub main()
|
|
127
|
-
name = person?["name"]
|
|
128
|
-
isTrue = true
|
|
129
|
-
key = isTrue ? ["name"] : ["age"]
|
|
130
|
-
end sub
|
|
131
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
132
|
-
const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
|
|
133
|
-
(0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
|
|
134
|
-
(0, chai_config_spec_1.expect)(assignmentStatements[2].value).is.instanceof(Expression_1.TernaryExpression);
|
|
135
|
-
});
|
|
136
|
-
it('distinguishes between optional chaining and ternary expression', () => {
|
|
137
|
-
const parser = parse(`
|
|
138
|
-
sub main()
|
|
139
|
-
'optional chain. the lack of whitespace between ? and [ matters
|
|
140
|
-
key = isTrue ?["name"] : getDefault()
|
|
141
|
-
'ternary
|
|
142
|
-
key = isTrue ? ["name"] : getDefault()
|
|
143
|
-
end sub
|
|
144
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
145
|
-
const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
|
|
146
|
-
(0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
|
|
147
|
-
(0, chai_config_spec_1.expect)(assignmentStatements[1].value).is.instanceof(Expression_1.TernaryExpression);
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
describe('diagnostic locations', () => {
|
|
151
|
-
it('tracks basic diagnostic locations', () => {
|
|
152
|
-
(0, chai_config_spec_1.expect)(parse(`
|
|
153
|
-
sub main()
|
|
154
|
-
call()a
|
|
155
|
-
end sub
|
|
156
|
-
`).diagnostics.map(x => rangeToArray(x.location.range))).to.eql([
|
|
157
|
-
[2, 26, 2, 27],
|
|
158
|
-
[2, 27, 2, 28]
|
|
159
|
-
]);
|
|
160
|
-
});
|
|
161
|
-
it.skip('handles edge cases', () => {
|
|
162
|
-
var _a, _b;
|
|
163
|
-
let diagnostics = parse(`
|
|
164
|
-
function BuildCommit()
|
|
165
|
-
return "6c5cdf1"
|
|
166
|
-
end functionasdf
|
|
167
|
-
`).diagnostics;
|
|
168
|
-
(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.expectedStatement().message);
|
|
169
|
-
(0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.location.range).to.eql(vscode_languageserver_1.Range.create(3, 20, 3, 32));
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
describe('parse', () => {
|
|
173
|
-
it('supports ungrouped iife in assignment', () => {
|
|
174
|
-
const parser = parse(`
|
|
175
|
-
sub main()
|
|
176
|
-
result = sub()
|
|
177
|
-
end sub()
|
|
178
|
-
result = function()
|
|
179
|
-
end function()
|
|
180
|
-
end sub
|
|
181
|
-
`);
|
|
182
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
183
|
-
});
|
|
184
|
-
it('supports grouped iife in assignment', () => {
|
|
185
|
-
const parser = parse(`
|
|
186
|
-
sub main()
|
|
187
|
-
result = (sub()
|
|
188
|
-
end sub)()
|
|
189
|
-
result = (function()
|
|
190
|
-
end function)()
|
|
191
|
-
end sub
|
|
192
|
-
`);
|
|
193
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
194
|
-
});
|
|
195
|
-
it('supports returning iife call', () => {
|
|
196
|
-
const parser = parse(`
|
|
197
|
-
sub main()
|
|
198
|
-
return (sub()
|
|
199
|
-
end sub)()
|
|
200
|
-
end sub
|
|
201
|
-
`);
|
|
202
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
203
|
-
});
|
|
204
|
-
it('supports using "interface" as parameter name', () => {
|
|
205
|
-
var _a;
|
|
206
|
-
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
207
|
-
sub main(interface as object)
|
|
208
|
-
end sub
|
|
209
|
-
`, Parser_1.ParseMode.BrighterScript).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
210
|
-
});
|
|
211
|
-
it('does not scrap the entire function when encountering unknown parameter type', () => {
|
|
212
|
-
const parser = parse(`
|
|
213
|
-
sub test(param1 as unknownType)
|
|
214
|
-
end sub
|
|
215
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
216
|
-
// type validation happens at scope validation, not at the parser
|
|
217
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
218
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(parser.ast.statements[0])).to.be.true;
|
|
219
|
-
});
|
|
220
|
-
it('does not scrap the entire function when encountering unknown parameter type in brightscript mode', () => {
|
|
221
|
-
const parser = parse(`
|
|
222
|
-
sub test(param1 as unknownType)
|
|
223
|
-
end sub
|
|
224
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
225
|
-
// type validation happens at scope validation, not at the parser
|
|
226
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types'));
|
|
227
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(parser.ast.statements[0])).to.be.true;
|
|
228
|
-
});
|
|
229
|
-
it('adds diagnostics when missing end for statements', () => {
|
|
230
|
-
let parser = parse(`
|
|
231
|
-
sub test1(x)
|
|
232
|
-
for each item in x
|
|
233
|
-
print item
|
|
234
|
-
end sub
|
|
235
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
236
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
|
|
237
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop('for each')
|
|
238
|
-
]);
|
|
239
|
-
parser = parse(`
|
|
240
|
-
sub test2()
|
|
241
|
-
for i = 0 to 10
|
|
242
|
-
print i
|
|
243
|
-
end sub
|
|
244
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
245
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
|
|
246
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop('for')
|
|
247
|
-
]);
|
|
248
|
-
parser = parse(`
|
|
249
|
-
sub test3(x )
|
|
250
|
-
for each item in x
|
|
251
|
-
print item
|
|
252
|
-
next
|
|
253
|
-
|
|
254
|
-
for i = 0 to 10
|
|
255
|
-
print i
|
|
256
|
-
next ' next works the same as "end for"
|
|
257
|
-
end sub
|
|
258
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
259
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
260
|
-
});
|
|
261
|
-
it('does not allow return type as invalid', () => {
|
|
262
|
-
let parser = parse(`
|
|
263
|
-
function test(x) as invalid
|
|
264
|
-
return invalid
|
|
265
|
-
end function
|
|
266
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
267
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
|
|
268
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('as').message
|
|
269
|
-
]);
|
|
270
|
-
});
|
|
271
|
-
it('does not allow param type as invalid', () => {
|
|
272
|
-
let parser = parse(`
|
|
273
|
-
function test(x as invalid)
|
|
274
|
-
return invalid
|
|
275
|
-
end function
|
|
276
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
277
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
|
|
278
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('as').message
|
|
279
|
-
]);
|
|
280
|
-
});
|
|
281
|
-
it('validates when theres a fraction hex', () => {
|
|
282
|
-
let parser = parse(`
|
|
283
|
-
function test()
|
|
284
|
-
x = &HFF.01234
|
|
285
|
-
return x
|
|
286
|
-
end function
|
|
287
|
-
`);
|
|
288
|
-
(0, testHelpers_spec_1.expectDiagnostics)(parser, [
|
|
289
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedStatement(),
|
|
290
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon()
|
|
291
|
-
]);
|
|
292
|
-
});
|
|
293
|
-
it('allows print statement with hex followed by dot <number>', () => {
|
|
294
|
-
let parser = parse(`
|
|
295
|
-
function test()
|
|
296
|
-
print &HFF.01234
|
|
297
|
-
end function
|
|
298
|
-
`);
|
|
299
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
300
|
-
});
|
|
301
|
-
describe('namespace', () => {
|
|
302
|
-
it('allows namespaces declared inside other namespaces', () => {
|
|
303
|
-
const parser = parse(`
|
|
304
|
-
namespace Level1
|
|
305
|
-
namespace Level2.Level3
|
|
306
|
-
sub main()
|
|
307
|
-
end sub
|
|
308
|
-
end namespace
|
|
309
|
-
end namespace
|
|
310
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
311
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
312
|
-
// We expect these names to be "as given" in this context, because we aren't evaluating a full program.
|
|
313
|
-
const namespaceStatements = parser.ast.findChildren(reflection_1.isNamespaceStatement);
|
|
314
|
-
(0, chai_config_spec_1.expect)(namespaceStatements.map(statement => statement.getName(Parser_1.ParseMode.BrighterScript))).to.have.deep.members([
|
|
315
|
-
'Level1.Level2.Level3',
|
|
316
|
-
'Level1'
|
|
317
|
-
]);
|
|
318
|
-
});
|
|
319
|
-
it('parses empty namespace', () => {
|
|
320
|
-
var _a;
|
|
321
|
-
let { ast, diagnostics } = parse(`
|
|
322
|
-
namespace Name.Space
|
|
323
|
-
end namespace
|
|
324
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
325
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
326
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
327
|
-
});
|
|
328
|
-
it('includes body', () => {
|
|
329
|
-
var _a;
|
|
330
|
-
let { ast, diagnostics } = parse(`
|
|
331
|
-
namespace Name.Space
|
|
332
|
-
sub main()
|
|
333
|
-
end sub
|
|
334
|
-
end namespace
|
|
335
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
336
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
337
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
338
|
-
(0, chai_config_spec_1.expect)(ast.statements[0].body.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
339
|
-
});
|
|
340
|
-
it('supports comments and newlines', () => {
|
|
341
|
-
var _a;
|
|
342
|
-
let { diagnostics } = parse(`
|
|
343
|
-
namespace Name.Space 'comment
|
|
344
|
-
|
|
345
|
-
'comment
|
|
346
|
-
|
|
347
|
-
sub main() 'comment
|
|
348
|
-
end sub 'comment
|
|
349
|
-
'comment
|
|
350
|
-
|
|
351
|
-
'comment
|
|
352
|
-
end namespace 'comment
|
|
353
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
354
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
355
|
-
});
|
|
356
|
-
it('catches missing name', () => {
|
|
357
|
-
var _a;
|
|
358
|
-
let { diagnostics } = parse(`
|
|
359
|
-
namespace
|
|
360
|
-
end namespace
|
|
361
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
362
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('namespace').message);
|
|
363
|
-
});
|
|
364
|
-
it('recovers after missing `end namespace`', () => {
|
|
365
|
-
var _a, _b, _c;
|
|
366
|
-
let parser = parse(`
|
|
367
|
-
namespace Name.Space
|
|
368
|
-
sub main()
|
|
369
|
-
end sub
|
|
370
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
371
|
-
(0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
|
|
372
|
-
(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);
|
|
373
|
-
(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);
|
|
374
|
-
});
|
|
375
|
-
it('adds diagnostic when encountering namespace in brightscript mode', () => {
|
|
376
|
-
var _a;
|
|
377
|
-
let parser = Parser_1.Parser.parse(`
|
|
378
|
-
namespace Name.Space
|
|
379
|
-
end namespace
|
|
380
|
-
`);
|
|
381
|
-
(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);
|
|
382
|
-
});
|
|
383
|
-
});
|
|
384
|
-
it('supports << operator', () => {
|
|
385
|
-
var _a;
|
|
386
|
-
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
387
|
-
sub main()
|
|
388
|
-
print ((r << 24) + (g << 16) + (b << 8) + a)
|
|
389
|
-
end sub
|
|
390
|
-
`).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
391
|
-
});
|
|
392
|
-
it('supports >> operator', () => {
|
|
393
|
-
var _a;
|
|
394
|
-
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
395
|
-
sub main()
|
|
396
|
-
print ((r >> 24) + (g >> 16) + (b >> 8) + a)
|
|
397
|
-
end sub
|
|
398
|
-
`).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
399
|
-
});
|
|
400
|
-
it('allows global function names with same as token to be called', () => {
|
|
401
|
-
var _a;
|
|
402
|
-
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
403
|
-
sub main()
|
|
404
|
-
print string(123)
|
|
405
|
-
end sub
|
|
406
|
-
`).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
407
|
-
});
|
|
408
|
-
it('supports @ symbol between names', () => {
|
|
409
|
-
var _a;
|
|
410
|
-
let parser = parse(`
|
|
411
|
-
sub main()
|
|
412
|
-
firstName = personXml@firstName
|
|
413
|
-
age = personXml.firstChild@age
|
|
414
|
-
end sub
|
|
415
|
-
`);
|
|
416
|
-
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
|
|
417
|
-
let assignments = parser.ast.statements[0].func.body.statements;
|
|
418
|
-
let first = assignments[0].value;
|
|
419
|
-
(0, chai_config_spec_1.expect)(first).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
|
|
420
|
-
(0, chai_config_spec_1.expect)(first.tokens.name.text).to.equal('firstName');
|
|
421
|
-
(0, chai_config_spec_1.expect)(first.tokens.at.text).to.equal('@');
|
|
422
|
-
(0, chai_config_spec_1.expect)(first.obj.tokens.name.text).to.equal('personXml');
|
|
423
|
-
let second = assignments[1].value;
|
|
424
|
-
(0, chai_config_spec_1.expect)(second).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
|
|
425
|
-
(0, chai_config_spec_1.expect)(second.tokens.name.text).to.equal('age');
|
|
426
|
-
(0, chai_config_spec_1.expect)(second.tokens.at.text).to.equal('@');
|
|
427
|
-
(0, chai_config_spec_1.expect)(second.obj.tokens.name.text).to.equal('firstChild');
|
|
428
|
-
});
|
|
429
|
-
it('does not allow chaining of @ symbols', () => {
|
|
430
|
-
let parser = parse(`
|
|
431
|
-
sub main()
|
|
432
|
-
personXml = invalid
|
|
433
|
-
name = personXml@name@age@shoeSize
|
|
434
|
-
end sub
|
|
435
|
-
`);
|
|
436
|
-
(0, chai_config_spec_1.expect)(parser.diagnostics).not.to.be.empty;
|
|
437
|
-
});
|
|
438
|
-
it('unknown function type does not invalidate rest of function', () => {
|
|
439
|
-
let { ast, diagnostics } = parse(`
|
|
440
|
-
function log() as UNKNOWN_TYPE
|
|
441
|
-
end function
|
|
442
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
443
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types').message); // type validation happens at scope validation step
|
|
444
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
445
|
-
});
|
|
446
|
-
it('unknown function type is not a problem in Brighterscript mode', () => {
|
|
447
|
-
let { ast, diagnostics } = parse(`
|
|
448
|
-
function log() as UNKNOWN_TYPE
|
|
449
|
-
end function
|
|
450
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
451
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
452
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
453
|
-
});
|
|
454
|
-
it('allows namespaced function type in Brighterscript mode', () => {
|
|
455
|
-
let { ast, diagnostics } = parse(`
|
|
456
|
-
function log() as SOME_NAMESPACE.UNKNOWN_TYPE
|
|
457
|
-
end function
|
|
458
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
459
|
-
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
460
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
461
|
-
});
|
|
462
|
-
it('allows custom parameter types in BrighterscriptMode', () => {
|
|
463
|
-
let { ast, diagnostics } = parse(`
|
|
464
|
-
sub foo(value as UNKNOWN_TYPE)
|
|
465
|
-
end sub
|
|
466
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
467
|
-
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
468
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
469
|
-
});
|
|
470
|
-
it('does cause diagnostics when custom parameter types are used in Brightscript Mode', () => {
|
|
471
|
-
let { diagnostics } = parse(`
|
|
472
|
-
sub foo(value as UNKNOWN_TYPE)
|
|
473
|
-
end sub
|
|
474
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
475
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types').message);
|
|
476
|
-
});
|
|
477
|
-
it('allows custom namespaced parameter types in BrighterscriptMode', () => {
|
|
478
|
-
let { ast, diagnostics } = parse(`
|
|
479
|
-
sub foo(value as SOME_NAMESPACE.UNKNOWN_TYPE)
|
|
480
|
-
end sub
|
|
481
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
482
|
-
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
|
|
483
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
|
|
484
|
-
});
|
|
485
|
-
it('works with conditionals', () => {
|
|
486
|
-
var _a;
|
|
487
|
-
(0, chai_config_spec_1.expect)((_a = parse(`
|
|
488
|
-
function printNumber()
|
|
489
|
-
if true then
|
|
490
|
-
print 1
|
|
491
|
-
else if true
|
|
492
|
-
return false
|
|
493
|
-
end if
|
|
494
|
-
end function
|
|
495
|
-
`).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
496
|
-
});
|
|
497
|
-
it('supports single-line if statements', () => {
|
|
498
|
-
var _a;
|
|
499
|
-
(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;
|
|
500
|
-
});
|
|
501
|
-
it('works with excess newlines', () => {
|
|
502
|
-
var _a;
|
|
503
|
-
let { tokens } = Lexer_1.Lexer.scan('function boolToNumber() as string\n\n' +
|
|
504
|
-
' if true then\n\n' +
|
|
505
|
-
' print 1\n\n' +
|
|
506
|
-
' elseif true then\n\n' +
|
|
507
|
-
' print 0\n\n' +
|
|
508
|
-
' else\n\n' +
|
|
509
|
-
' print 1\n\n' +
|
|
510
|
-
' end if\n\n' +
|
|
511
|
-
'end function\n\n');
|
|
512
|
-
(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;
|
|
513
|
-
});
|
|
514
|
-
it('does not invalidate entire file when line ends with a period', () => {
|
|
515
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
516
|
-
sub main()
|
|
517
|
-
person.a
|
|
518
|
-
end sub
|
|
519
|
-
|
|
520
|
-
`);
|
|
521
|
-
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
522
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1, 'Error count should be 0');
|
|
523
|
-
});
|
|
524
|
-
it('allows printing object with trailing period', () => {
|
|
525
|
-
let { tokens } = Lexer_1.Lexer.scan(`print a.`);
|
|
526
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
527
|
-
let printStatement = ast.statements[0];
|
|
528
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier());
|
|
529
|
-
(0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
|
|
530
|
-
(0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.VariableExpression);
|
|
531
|
-
});
|
|
532
|
-
it('allows printing object with trailing period with multiple dotted gets', () => {
|
|
533
|
-
let { tokens } = Lexer_1.Lexer.scan(`print a.b.`);
|
|
534
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
535
|
-
let printStatement = ast.statements[0];
|
|
536
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier());
|
|
537
|
-
(0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
|
|
538
|
-
(0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.DottedGetExpression);
|
|
539
|
-
});
|
|
540
|
-
describe('incomplete statements in the ast', () => {
|
|
541
|
-
it('adds variable expressions to the ast', () => {
|
|
542
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
543
|
-
function a()
|
|
544
|
-
NameA.
|
|
545
|
-
end function
|
|
546
|
-
|
|
547
|
-
namespace NameA
|
|
548
|
-
sub noop()
|
|
549
|
-
end sub
|
|
550
|
-
end namespace
|
|
551
|
-
`);
|
|
552
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
553
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedStatement());
|
|
554
|
-
let stmt = ast.statements[0].func.body.statements[0];
|
|
555
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
556
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)((stmt).expression)).to.be.true;
|
|
557
|
-
(0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('NameA');
|
|
558
|
-
});
|
|
559
|
-
it('adds unended call statements', () => {
|
|
560
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
561
|
-
function a()
|
|
562
|
-
lcase(
|
|
563
|
-
end function
|
|
564
|
-
`);
|
|
565
|
-
let { ast } = Parser_1.Parser.parse(tokens);
|
|
566
|
-
let stmt = ast.statements[0].func.body.statements[0];
|
|
567
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
568
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)((stmt).expression)).to.be.true;
|
|
569
|
-
(0, chai_config_spec_1.expect)(stmt.expression.callee.tokens.name.text).to.equal('lcase');
|
|
570
|
-
});
|
|
571
|
-
it('adds unended indexed get statements', () => {
|
|
572
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
573
|
-
function a()
|
|
574
|
-
nums[
|
|
575
|
-
end function
|
|
576
|
-
|
|
577
|
-
const nums = [1, 2, 3]
|
|
578
|
-
`);
|
|
579
|
-
let { ast } = Parser_1.Parser.parse(tokens);
|
|
580
|
-
let stmt = ast.statements[0].func.body.statements[0];
|
|
581
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
582
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isIndexedGetExpression)((stmt).expression)).to.be.true;
|
|
583
|
-
(0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('nums');
|
|
584
|
-
});
|
|
585
|
-
it('adds dotted gets', () => {
|
|
586
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
587
|
-
function foo(a as KlassA)
|
|
588
|
-
a.b.
|
|
589
|
-
end function
|
|
590
|
-
|
|
591
|
-
class KlassA
|
|
592
|
-
b as KlassB
|
|
593
|
-
end class
|
|
594
|
-
|
|
595
|
-
class KlassB
|
|
596
|
-
sub noop()
|
|
597
|
-
end sub
|
|
598
|
-
end class
|
|
599
|
-
`);
|
|
600
|
-
let { ast } = Parser_1.Parser.parse(tokens);
|
|
601
|
-
let stmt = ast.statements[0].func.body.statements[0];
|
|
602
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
603
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)((stmt).expression)).to.be.true;
|
|
604
|
-
(0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('a');
|
|
605
|
-
(0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('b');
|
|
606
|
-
});
|
|
607
|
-
it('adds function statement with missing type after as', () => {
|
|
608
|
-
var _a;
|
|
609
|
-
let parser = parse(`
|
|
610
|
-
sub foo(thing as )
|
|
611
|
-
print thing
|
|
612
|
-
end sub
|
|
613
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
614
|
-
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
615
|
-
(0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
616
|
-
});
|
|
617
|
-
it('adds binary expressions to the ast', () => {
|
|
618
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
619
|
-
function a(x, y)
|
|
620
|
-
1 or 2
|
|
621
|
-
x * y
|
|
622
|
-
x + y
|
|
623
|
-
x - y
|
|
624
|
-
end function
|
|
625
|
-
`);
|
|
626
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
627
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedStatement());
|
|
628
|
-
for (const stmt of ast.statements[0].func.body.statements) {
|
|
629
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
|
|
630
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)((stmt).expression)).to.be.true;
|
|
631
|
-
}
|
|
632
|
-
});
|
|
633
|
-
it('adds callfunc expressions', () => {
|
|
634
|
-
var _a;
|
|
635
|
-
let parser = parse(`
|
|
636
|
-
sub foo(thing)
|
|
637
|
-
thing@.
|
|
638
|
-
end sub
|
|
639
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
640
|
-
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
641
|
-
let body = parser.ast.statements[0].func.body;
|
|
642
|
-
let callFunc = body.findChild(reflection_1.isCallfuncExpression);
|
|
643
|
-
(0, chai_config_spec_1.expect)(callFunc).to.exist;
|
|
644
|
-
});
|
|
645
|
-
it('adds if statements', () => {
|
|
646
|
-
var _a;
|
|
647
|
-
let parser = parse(`
|
|
648
|
-
sub foo(thing)
|
|
649
|
-
if thing.
|
|
650
|
-
end sub
|
|
651
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
652
|
-
(0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
653
|
-
let body = parser.ast.statements[0].func.body;
|
|
654
|
-
let ifStmt = body.findChild(reflection_1.isIfStatement);
|
|
655
|
-
(0, chai_config_spec_1.expect)(ifStmt).to.exist;
|
|
656
|
-
});
|
|
657
|
-
});
|
|
658
|
-
describe('comments', () => {
|
|
659
|
-
it('does not include comments', () => {
|
|
660
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
661
|
-
'line 1
|
|
662
|
-
'line 2
|
|
663
|
-
'line 3
|
|
664
|
-
`);
|
|
665
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
666
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
667
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.equal(0);
|
|
668
|
-
});
|
|
669
|
-
it('does matter if comments separated by newlines', () => {
|
|
670
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
671
|
-
'line 1
|
|
672
|
-
|
|
673
|
-
'line 2
|
|
674
|
-
|
|
675
|
-
'line 3
|
|
676
|
-
`);
|
|
677
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
678
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
679
|
-
(0, chai_config_spec_1.expect)(ast.statements).to.be.lengthOf(0);
|
|
680
|
-
});
|
|
681
|
-
it('works after print statement', () => {
|
|
682
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
683
|
-
sub main()
|
|
684
|
-
print "hi" 'comment 1
|
|
685
|
-
end sub
|
|
686
|
-
`);
|
|
687
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
688
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
689
|
-
(0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements.length).to.equal(1);
|
|
690
|
-
});
|
|
691
|
-
it('declaration-level should be set as leading trivia', () => {
|
|
692
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
693
|
-
'comment 1
|
|
694
|
-
function a()
|
|
695
|
-
end function
|
|
696
|
-
'comment 2
|
|
697
|
-
`);
|
|
698
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
699
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
700
|
-
(0, chai_config_spec_1.expect)(ast.statements[0].leadingTrivia[2].text).to.equal(`'comment 1`);
|
|
701
|
-
});
|
|
702
|
-
it('works in aa literal as its own statement', () => {
|
|
703
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
704
|
-
obj = {
|
|
705
|
-
"name": true,
|
|
706
|
-
'comment
|
|
707
|
-
}
|
|
708
|
-
`);
|
|
709
|
-
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
710
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
|
|
711
|
-
});
|
|
712
|
-
it('parses after function call', () => {
|
|
713
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
714
|
-
sub Main()
|
|
715
|
-
name = "Hello"
|
|
716
|
-
DoSomething(name) 'comment 1
|
|
717
|
-
end sub
|
|
718
|
-
`);
|
|
719
|
-
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
720
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
721
|
-
});
|
|
722
|
-
it('function', () => {
|
|
723
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
724
|
-
function a() 'comment 1
|
|
725
|
-
'comment 2
|
|
726
|
-
num = 1
|
|
727
|
-
'comment 3
|
|
728
|
-
end function 'comment 4
|
|
729
|
-
`);
|
|
730
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
731
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
732
|
-
(0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].leadingTrivia.filter(x => x.kind === TokenKind_1.TokenKind.Comment).map(x => x.text)).members([`'comment 1`, `'comment 2`]);
|
|
733
|
-
});
|
|
734
|
-
it('if statement`', () => {
|
|
735
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
736
|
-
function a()
|
|
737
|
-
if true then 'comment 1
|
|
738
|
-
'comment 2
|
|
739
|
-
print "hello"
|
|
740
|
-
'comment 3
|
|
741
|
-
else if true then 'comment 4
|
|
742
|
-
'comment 5
|
|
743
|
-
print "hello"
|
|
744
|
-
'comment 6
|
|
745
|
-
else 'comment 7
|
|
746
|
-
'comment 8
|
|
747
|
-
print "hello"
|
|
748
|
-
'comment 9
|
|
749
|
-
end if 'comment 10
|
|
750
|
-
end function
|
|
751
|
-
`);
|
|
752
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
753
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
|
|
754
|
-
let fnSmt = ast.statements[0];
|
|
755
|
-
if ((0, reflection_1.isFunctionStatement)(fnSmt)) {
|
|
756
|
-
let ifStmt = fnSmt.func.body.statements[0];
|
|
757
|
-
if ((0, reflection_1.isIfStatement)(ifStmt)) {
|
|
758
|
-
expectCommentWithText(ifStmt.thenBranch.statements[0], `'comment 1\n'comment 2`);
|
|
759
|
-
let elseIfBranch = ifStmt.elseBranch;
|
|
760
|
-
if ((0, reflection_1.isIfStatement)(elseIfBranch)) {
|
|
761
|
-
expectCommentWithText(elseIfBranch.thenBranch.statements[0], `'comment 4\n'comment 5`);
|
|
762
|
-
let elseBranch = elseIfBranch.elseBranch;
|
|
763
|
-
if ((0, reflection_1.isBlock)(elseBranch)) {
|
|
764
|
-
expectCommentWithText(elseBranch.statements[0], `'comment 7\n'comment 8`);
|
|
765
|
-
}
|
|
766
|
-
else {
|
|
767
|
-
failStatementType(elseBranch, 'Block');
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
else {
|
|
771
|
-
failStatementType(elseIfBranch, 'If');
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
else {
|
|
775
|
-
failStatementType(ifStmt, 'If');
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
else {
|
|
779
|
-
failStatementType(fnSmt, 'Function');
|
|
780
|
-
}
|
|
781
|
-
});
|
|
782
|
-
it('while', () => {
|
|
783
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
784
|
-
function a()
|
|
785
|
-
while true 'comment 1
|
|
786
|
-
'comment 2
|
|
787
|
-
print "true"
|
|
788
|
-
'comment 3
|
|
789
|
-
end while 'comment 4
|
|
790
|
-
end function
|
|
791
|
-
`);
|
|
792
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
793
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
794
|
-
let stmt = ast.statements[0].func.body.statements[0];
|
|
795
|
-
expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
|
|
796
|
-
});
|
|
797
|
-
it('for', () => {
|
|
798
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
799
|
-
function a()
|
|
800
|
-
for i = 0 to 10 step 1 'comment 1
|
|
801
|
-
'comment 2
|
|
802
|
-
print 1
|
|
803
|
-
'comment 3
|
|
804
|
-
end for 'comment 4
|
|
805
|
-
end function
|
|
806
|
-
`);
|
|
807
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
808
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
809
|
-
let stmt = ast.statements[0].func.body.statements[0];
|
|
810
|
-
expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
|
|
811
|
-
});
|
|
812
|
-
it('for each', () => {
|
|
813
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
814
|
-
function a()
|
|
815
|
-
for each val in [1,2,3] 'comment 1
|
|
816
|
-
'comment 2
|
|
817
|
-
print 1
|
|
818
|
-
'comment 3
|
|
819
|
-
end for 'comment 4
|
|
820
|
-
end function
|
|
821
|
-
`);
|
|
822
|
-
let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
|
|
823
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
|
|
824
|
-
let stmt = ast.statements[0].func.body.statements[0];
|
|
825
|
-
expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
|
|
826
|
-
});
|
|
827
|
-
});
|
|
828
|
-
});
|
|
829
|
-
describe('reservedWords', () => {
|
|
830
|
-
describe('`then`', () => {
|
|
831
|
-
it('is not allowed as a local identifier', () => {
|
|
832
|
-
let { diagnostics } = parse(`
|
|
833
|
-
sub main()
|
|
834
|
-
then = true
|
|
835
|
-
end sub
|
|
836
|
-
`);
|
|
837
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1);
|
|
838
|
-
});
|
|
839
|
-
it('is allowed as an AA property name', () => {
|
|
840
|
-
var _a;
|
|
841
|
-
let { diagnostics } = parse(`
|
|
842
|
-
sub main()
|
|
843
|
-
person = {
|
|
844
|
-
then: true
|
|
845
|
-
}
|
|
846
|
-
person.then = false
|
|
847
|
-
print person.then
|
|
848
|
-
end sub
|
|
849
|
-
`);
|
|
850
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
851
|
-
});
|
|
852
|
-
it('allows `mod` as an AA literal property', () => {
|
|
853
|
-
const parser = parse(`
|
|
854
|
-
sub main()
|
|
855
|
-
person = {
|
|
856
|
-
mod: true
|
|
857
|
-
}
|
|
858
|
-
person.mod = false
|
|
859
|
-
print person.mod
|
|
860
|
-
end sub
|
|
861
|
-
`);
|
|
862
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
863
|
-
});
|
|
864
|
-
it('converts aa literal property TokenKind to Identifier', () => {
|
|
865
|
-
const parser = parse(`
|
|
866
|
-
sub main()
|
|
867
|
-
person = {
|
|
868
|
-
mod: true
|
|
869
|
-
and: true
|
|
870
|
-
}
|
|
871
|
-
end sub
|
|
872
|
-
`);
|
|
873
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
|
|
874
|
-
const elements = [];
|
|
875
|
-
parser.ast.walk((0, visitors_1.createVisitor)({
|
|
876
|
-
AAMemberExpression: (node) => {
|
|
877
|
-
elements.push(node);
|
|
878
|
-
}
|
|
879
|
-
}), {
|
|
880
|
-
walkMode: visitors_1.WalkMode.visitAllRecursive
|
|
881
|
-
});
|
|
882
|
-
(0, chai_config_spec_1.expect)(elements.map(x => x.tokens.key.kind)).to.eql([TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.Identifier]);
|
|
883
|
-
});
|
|
884
|
-
});
|
|
885
|
-
it('"end" is not allowed as a local identifier', () => {
|
|
886
|
-
let { diagnostics } = parse(`
|
|
887
|
-
sub main()
|
|
888
|
-
end = true
|
|
889
|
-
end sub
|
|
890
|
-
`);
|
|
891
|
-
(0, chai_config_spec_1.expect)(diagnostics).to.be.length.greaterThan(0);
|
|
892
|
-
});
|
|
893
|
-
it('none of them can be used as local variables', () => {
|
|
894
|
-
let reservedWords = new Set(TokenKind_1.ReservedWords);
|
|
895
|
-
//remove the rem keyword because it's a comment...won't cause error
|
|
896
|
-
reservedWords.delete('rem');
|
|
897
|
-
for (let reservedWord of reservedWords) {
|
|
898
|
-
let { tokens } = Lexer_1.Lexer.scan(`
|
|
899
|
-
sub main()
|
|
900
|
-
${reservedWord} = true
|
|
901
|
-
end sub
|
|
902
|
-
`);
|
|
903
|
-
let { diagnostics } = Parser_1.Parser.parse(tokens);
|
|
904
|
-
(0, chai_config_spec_1.expect)(diagnostics, `assigning to reserved word "${reservedWord}" should have been an error`).to.be.length.greaterThan(0);
|
|
905
|
-
}
|
|
906
|
-
});
|
|
907
|
-
});
|
|
908
|
-
describe('import keyword', () => {
|
|
909
|
-
it('parses without errors', () => {
|
|
910
|
-
var _a;
|
|
911
|
-
let { ast, diagnostics } = parse(`
|
|
912
|
-
import "somePath"
|
|
913
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
914
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
915
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
916
|
-
});
|
|
917
|
-
it('catches import statements used in brightscript files', () => {
|
|
918
|
-
var _a;
|
|
919
|
-
let { ast, diagnostics } = parse(`
|
|
920
|
-
import "somePath"
|
|
921
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
922
|
-
(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);
|
|
923
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
924
|
-
});
|
|
925
|
-
it('catchs missing file path', () => {
|
|
926
|
-
var _a;
|
|
927
|
-
let { ast, diagnostics } = parse(`
|
|
928
|
-
import
|
|
929
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
930
|
-
(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);
|
|
931
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.ImportStatement);
|
|
932
|
-
});
|
|
933
|
-
});
|
|
934
|
-
describe('Annotations', () => {
|
|
935
|
-
it('parses with error if malformed', () => {
|
|
936
|
-
var _a;
|
|
937
|
-
let { diagnostics } = parse(`
|
|
938
|
-
@
|
|
939
|
-
sub main()
|
|
940
|
-
end sub
|
|
941
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
942
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('@').message);
|
|
943
|
-
});
|
|
944
|
-
it('properly handles empty annotation above class method', () => {
|
|
945
|
-
var _a;
|
|
946
|
-
//this code used to cause an infinite loop, so the fact that the test passes/fails on its own is a success!
|
|
947
|
-
let { diagnostics } = parse(`
|
|
948
|
-
class Person
|
|
949
|
-
@
|
|
950
|
-
sub new()
|
|
951
|
-
end sub
|
|
952
|
-
end class
|
|
953
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
954
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier().message);
|
|
955
|
-
});
|
|
956
|
-
it('parses with error if annotation is not followed by a statement', () => {
|
|
957
|
-
var _a, _b, _c, _d;
|
|
958
|
-
let { diagnostics } = parse(`
|
|
959
|
-
sub main()
|
|
960
|
-
@meta2
|
|
961
|
-
end sub
|
|
962
|
-
class MyClass
|
|
963
|
-
@meta3
|
|
964
|
-
@meta4
|
|
965
|
-
end class
|
|
966
|
-
@meta1
|
|
967
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
968
|
-
(0, chai_config_spec_1.expect)(diagnostics.length).to.equal(4);
|
|
969
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
970
|
-
(0, chai_config_spec_1.expect)((_b = diagnostics[1]) === null || _b === void 0 ? void 0 : _b.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
971
|
-
(0, chai_config_spec_1.expect)((_c = diagnostics[2]) === null || _c === void 0 ? void 0 : _c.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
972
|
-
(0, chai_config_spec_1.expect)((_d = diagnostics[3]) === null || _d === void 0 ? void 0 : _d.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
|
|
973
|
-
});
|
|
974
|
-
it('attaches an annotation to next statement', () => {
|
|
975
|
-
var _a;
|
|
976
|
-
let { ast, diagnostics } = parse(`
|
|
977
|
-
@meta1
|
|
978
|
-
function main()
|
|
979
|
-
end function
|
|
980
|
-
|
|
981
|
-
@meta2 sub init()
|
|
982
|
-
end sub
|
|
983
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
984
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
985
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
986
|
-
let fn = ast.statements[0];
|
|
987
|
-
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
988
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
989
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
|
|
990
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0].name).to.equal('meta1');
|
|
991
|
-
(0, chai_config_spec_1.expect)(ast.statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
992
|
-
fn = ast.statements[1];
|
|
993
|
-
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
994
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
995
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta2');
|
|
996
|
-
});
|
|
997
|
-
it('attaches annotations inside a function body', () => {
|
|
998
|
-
var _a, _b;
|
|
999
|
-
let { ast, diagnostics } = parse(`
|
|
1000
|
-
function main()
|
|
1001
|
-
@meta1
|
|
1002
|
-
print "hello"
|
|
1003
|
-
end function
|
|
1004
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1005
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1006
|
-
let fn = ast.statements[0];
|
|
1007
|
-
let fnStatements = fn.func.body.statements;
|
|
1008
|
-
let stat = fnStatements[0];
|
|
1009
|
-
(0, chai_config_spec_1.expect)(stat).to.exist;
|
|
1010
|
-
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1011
|
-
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1012
|
-
});
|
|
1013
|
-
it('attaches multiple annotations to next statement', () => {
|
|
1014
|
-
var _a;
|
|
1015
|
-
let { ast, diagnostics } = parse(`
|
|
1016
|
-
@meta1
|
|
1017
|
-
@meta2 @meta3
|
|
1018
|
-
function main()
|
|
1019
|
-
end function
|
|
1020
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1021
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1022
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1023
|
-
let fn = ast.statements[0];
|
|
1024
|
-
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1025
|
-
(0, chai_config_spec_1.expect)(fn.annotations.length).to.equal(3);
|
|
1026
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1027
|
-
(0, chai_config_spec_1.expect)(fn.annotations[1]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1028
|
-
(0, chai_config_spec_1.expect)(fn.annotations[2]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1029
|
-
});
|
|
1030
|
-
it('allows annotations with parameters', () => {
|
|
1031
|
-
var _a;
|
|
1032
|
-
let { ast, diagnostics } = parse(`
|
|
1033
|
-
@meta1("arg", 2, true, { prop: "value" })
|
|
1034
|
-
function main()
|
|
1035
|
-
end function
|
|
1036
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1037
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1038
|
-
let fn = ast.statements[0];
|
|
1039
|
-
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1040
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1041
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
|
|
1042
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0].call).to.be.instanceof(Expression_1.CallExpression);
|
|
1043
|
-
});
|
|
1044
|
-
it('attaches annotations to a class', () => {
|
|
1045
|
-
var _a, _b;
|
|
1046
|
-
let { ast, diagnostics } = parse(`
|
|
1047
|
-
@meta1
|
|
1048
|
-
class MyClass
|
|
1049
|
-
function main()
|
|
1050
|
-
print "hello"
|
|
1051
|
-
end function
|
|
1052
|
-
end class
|
|
1053
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1054
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1055
|
-
let cs = ast.statements[0];
|
|
1056
|
-
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1057
|
-
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1058
|
-
});
|
|
1059
|
-
it('attaches annotations to multiple clases', () => {
|
|
1060
|
-
var _a, _b, _c;
|
|
1061
|
-
let { ast, diagnostics } = parse(`
|
|
1062
|
-
@meta1
|
|
1063
|
-
class MyClass
|
|
1064
|
-
function main()
|
|
1065
|
-
print "hello"
|
|
1066
|
-
end function
|
|
1067
|
-
end class
|
|
1068
|
-
@meta2
|
|
1069
|
-
class MyClass2
|
|
1070
|
-
function main()
|
|
1071
|
-
print "hello"
|
|
1072
|
-
end function
|
|
1073
|
-
end class
|
|
1074
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1075
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1076
|
-
let cs = ast.statements[0];
|
|
1077
|
-
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1078
|
-
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1079
|
-
(0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
|
|
1080
|
-
let cs2 = ast.statements[1];
|
|
1081
|
-
(0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
|
|
1082
|
-
(0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1083
|
-
(0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
|
|
1084
|
-
});
|
|
1085
|
-
it('attaches annotations to a namespaced class', () => {
|
|
1086
|
-
var _a, _b;
|
|
1087
|
-
let { ast, diagnostics } = parse(`
|
|
1088
|
-
namespace ns
|
|
1089
|
-
@meta1
|
|
1090
|
-
class MyClass
|
|
1091
|
-
function main()
|
|
1092
|
-
print "hello"
|
|
1093
|
-
end function
|
|
1094
|
-
end class
|
|
1095
|
-
end namespace
|
|
1096
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1097
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1098
|
-
let ns = ast.statements[0];
|
|
1099
|
-
let cs = ns.body.statements[0];
|
|
1100
|
-
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1101
|
-
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1102
|
-
});
|
|
1103
|
-
it('attaches annotations to a namespaced class - multiple', () => {
|
|
1104
|
-
var _a, _b, _c;
|
|
1105
|
-
let { ast, diagnostics } = parse(`
|
|
1106
|
-
namespace ns
|
|
1107
|
-
@meta1
|
|
1108
|
-
class MyClass
|
|
1109
|
-
function main()
|
|
1110
|
-
print "hello"
|
|
1111
|
-
end function
|
|
1112
|
-
end class
|
|
1113
|
-
@meta2
|
|
1114
|
-
class MyClass2
|
|
1115
|
-
function main()
|
|
1116
|
-
print "hello"
|
|
1117
|
-
end function
|
|
1118
|
-
end class
|
|
1119
|
-
end namespace
|
|
1120
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1121
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1122
|
-
let ns = ast.statements[0];
|
|
1123
|
-
let cs = ns.body.statements[0];
|
|
1124
|
-
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1125
|
-
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1126
|
-
(0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
|
|
1127
|
-
let cs2 = ns.body.statements[1];
|
|
1128
|
-
(0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
|
|
1129
|
-
(0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1130
|
-
(0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
|
|
1131
|
-
});
|
|
1132
|
-
it('attaches annotations to a class constructor', () => {
|
|
1133
|
-
var _a, _b;
|
|
1134
|
-
let { ast, diagnostics } = parse(`
|
|
1135
|
-
class MyClass
|
|
1136
|
-
@meta1
|
|
1137
|
-
function new()
|
|
1138
|
-
print "hello"
|
|
1139
|
-
end function
|
|
1140
|
-
function methodA()
|
|
1141
|
-
print "hello"
|
|
1142
|
-
end function
|
|
1143
|
-
end class
|
|
1144
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1145
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1146
|
-
let cs = ast.statements[0];
|
|
1147
|
-
let stat = cs.body[0];
|
|
1148
|
-
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1149
|
-
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1150
|
-
});
|
|
1151
|
-
it('attaches annotations to a class methods', () => {
|
|
1152
|
-
var _a, _b;
|
|
1153
|
-
let { ast, diagnostics } = parse(`
|
|
1154
|
-
class MyClass
|
|
1155
|
-
function new()
|
|
1156
|
-
print "hello"
|
|
1157
|
-
end function
|
|
1158
|
-
@meta1
|
|
1159
|
-
function methodA()
|
|
1160
|
-
print "hello"
|
|
1161
|
-
end function
|
|
1162
|
-
end class
|
|
1163
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1164
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1165
|
-
let cs = ast.statements[0];
|
|
1166
|
-
let stat = cs.body[1];
|
|
1167
|
-
(0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
1168
|
-
(0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1169
|
-
});
|
|
1170
|
-
it('attaches annotations to a class methods, fields and constructor', () => {
|
|
1171
|
-
var _a, _b, _c, _d, _e;
|
|
1172
|
-
let { ast, diagnostics } = parse(`
|
|
1173
|
-
@meta2
|
|
1174
|
-
@meta1
|
|
1175
|
-
class MyClass
|
|
1176
|
-
@meta3
|
|
1177
|
-
@meta4
|
|
1178
|
-
function new()
|
|
1179
|
-
print "hello"
|
|
1180
|
-
end function
|
|
1181
|
-
@meta5
|
|
1182
|
-
@meta6
|
|
1183
|
-
function methodA()
|
|
1184
|
-
print "hello"
|
|
1185
|
-
end function
|
|
1186
|
-
|
|
1187
|
-
@meta5
|
|
1188
|
-
@meta6
|
|
1189
|
-
public foo="bar"
|
|
1190
|
-
end class
|
|
1191
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1192
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1193
|
-
let cs = ast.statements[0];
|
|
1194
|
-
(0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(2);
|
|
1195
|
-
(0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1196
|
-
let stat1 = cs.body[0];
|
|
1197
|
-
let stat2 = cs.body[1];
|
|
1198
|
-
let f1 = cs.body[2];
|
|
1199
|
-
(0, chai_config_spec_1.expect)((_c = stat1.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
|
|
1200
|
-
(0, chai_config_spec_1.expect)(stat1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1201
|
-
(0, chai_config_spec_1.expect)((_d = stat2.annotations) === null || _d === void 0 ? void 0 : _d.length).to.equal(2);
|
|
1202
|
-
(0, chai_config_spec_1.expect)(stat2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1203
|
-
(0, chai_config_spec_1.expect)((_e = f1.annotations) === null || _e === void 0 ? void 0 : _e.length).to.equal(2);
|
|
1204
|
-
(0, chai_config_spec_1.expect)(f1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1205
|
-
});
|
|
1206
|
-
it('ignores annotations on commented out lines', () => {
|
|
1207
|
-
var _a;
|
|
1208
|
-
let { ast, diagnostics } = parse(`
|
|
1209
|
-
'@meta1
|
|
1210
|
-
' @meta1
|
|
1211
|
-
function new()
|
|
1212
|
-
print "hello"
|
|
1213
|
-
end function
|
|
1214
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1215
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1216
|
-
let cs = ast.statements[0];
|
|
1217
|
-
(0, chai_config_spec_1.expect)(cs.annotations).to.be.undefined;
|
|
1218
|
-
});
|
|
1219
|
-
it('can convert argument of an annotation to JS types', () => {
|
|
1220
|
-
var _a;
|
|
1221
|
-
let { ast, diagnostics } = parse(`
|
|
1222
|
-
@meta1
|
|
1223
|
-
function main()
|
|
1224
|
-
end function
|
|
1225
|
-
|
|
1226
|
-
@meta2(
|
|
1227
|
-
"arg", 2, true,
|
|
1228
|
-
{ prop: "value" }, [1, 2],
|
|
1229
|
-
sub()
|
|
1230
|
-
end sub
|
|
1231
|
-
)
|
|
1232
|
-
sub init()
|
|
1233
|
-
end sub
|
|
1234
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1235
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1236
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1237
|
-
let fn = ast.statements[0];
|
|
1238
|
-
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1239
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([]);
|
|
1240
|
-
(0, chai_config_spec_1.expect)(ast.statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1241
|
-
fn = ast.statements[1];
|
|
1242
|
-
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1243
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
|
|
1244
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([
|
|
1245
|
-
'arg', 2, true,
|
|
1246
|
-
{ prop: 'value' }, [1, 2],
|
|
1247
|
-
null
|
|
1248
|
-
]);
|
|
1249
|
-
let allArgs = fn.annotations[0].getArguments(false);
|
|
1250
|
-
(0, chai_config_spec_1.expect)(allArgs.pop()).to.be.instanceOf(Expression_1.FunctionExpression);
|
|
1251
|
-
});
|
|
1252
|
-
it('can handle negative numbers', () => {
|
|
1253
|
-
var _a;
|
|
1254
|
-
let { ast, diagnostics } = parse(`
|
|
1255
|
-
@meta(-100)
|
|
1256
|
-
function main()
|
|
1257
|
-
end function
|
|
1258
|
-
|
|
1259
|
-
sub init()
|
|
1260
|
-
end sub
|
|
1261
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1262
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1263
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1264
|
-
let fn = ast.statements[0];
|
|
1265
|
-
(0, chai_config_spec_1.expect)(fn.annotations).to.exist;
|
|
1266
|
-
(0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([-100]);
|
|
1267
|
-
});
|
|
1268
|
-
});
|
|
1269
|
-
describe('type casts', () => {
|
|
1270
|
-
it('is not allowed in brightscript mode', () => {
|
|
1271
|
-
var _a;
|
|
1272
|
-
let parser = parse(`
|
|
1273
|
-
sub main(node as dynamic)
|
|
1274
|
-
print lcase((node as string))
|
|
1275
|
-
end sub
|
|
1276
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
1277
|
-
(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);
|
|
1278
|
-
});
|
|
1279
|
-
it('allows type casts after function calls', () => {
|
|
1280
|
-
var _a;
|
|
1281
|
-
let { ast, diagnostics } = parse(`
|
|
1282
|
-
sub main()
|
|
1283
|
-
value = getValue() as integer
|
|
1284
|
-
end sub
|
|
1285
|
-
|
|
1286
|
-
function getValue()
|
|
1287
|
-
return 123
|
|
1288
|
-
end function
|
|
1289
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1290
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1291
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1292
|
-
let fn = ast.statements[0];
|
|
1293
|
-
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1294
|
-
let assignment = fn.func.body.statements[0];
|
|
1295
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
|
|
1296
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(assignment.value)).to.be.true;
|
|
1297
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value.obj)).to.be.true;
|
|
1298
|
-
(0, testHelpers_spec_1.expectTypeToBe)(assignment.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), IntegerType_1.IntegerType);
|
|
1299
|
-
});
|
|
1300
|
-
it('allows type casts in the middle of expressions', () => {
|
|
1301
|
-
var _a;
|
|
1302
|
-
let { ast, diagnostics } = parse(`
|
|
1303
|
-
sub main()
|
|
1304
|
-
value = (getValue() as integer).toStr()
|
|
1305
|
-
end sub
|
|
1306
|
-
|
|
1307
|
-
function getValue()
|
|
1308
|
-
return 123
|
|
1309
|
-
end function
|
|
1310
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1311
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1312
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1313
|
-
let fn = ast.statements[0];
|
|
1314
|
-
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1315
|
-
let assignment = fn.func.body.statements[0];
|
|
1316
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
|
|
1317
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value)).to.be.true;
|
|
1318
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)(assignment.value.callee)).to.be.true;
|
|
1319
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(assignment.value.callee.obj)).to.be.true;
|
|
1320
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(assignment.value.callee.obj.expression)).to.be.true;
|
|
1321
|
-
//grouping expression is an integer
|
|
1322
|
-
(0, testHelpers_spec_1.expectTypeToBe)(assignment.value.callee.obj.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), IntegerType_1.IntegerType);
|
|
1323
|
-
});
|
|
1324
|
-
it('allows type casts in a function call', () => {
|
|
1325
|
-
var _a;
|
|
1326
|
-
let { ast, diagnostics } = parse(`
|
|
1327
|
-
sub main()
|
|
1328
|
-
print cos(getAngle() as float)
|
|
1329
|
-
end sub
|
|
1330
|
-
|
|
1331
|
-
function getAngle()
|
|
1332
|
-
return 123
|
|
1333
|
-
end function
|
|
1334
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1335
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1336
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1337
|
-
let fn = ast.statements[0];
|
|
1338
|
-
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1339
|
-
let print = fn.func.body.statements[0];
|
|
1340
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
|
|
1341
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(print.expressions[0])).to.be.true;
|
|
1342
|
-
let fnCall = print.expressions[0];
|
|
1343
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(fnCall.args[0])).to.be.true;
|
|
1344
|
-
let arg = fnCall.args[0];
|
|
1345
|
-
//argument type is float
|
|
1346
|
-
(0, testHelpers_spec_1.expectTypeToBe)(arg.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), FloatType_1.FloatType);
|
|
1347
|
-
});
|
|
1348
|
-
it('allows multiple type casts', () => {
|
|
1349
|
-
var _a;
|
|
1350
|
-
let { ast, diagnostics } = parse(`
|
|
1351
|
-
sub main()
|
|
1352
|
-
print getData() as dynamic as float as string
|
|
1353
|
-
end sub
|
|
1354
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1355
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
|
|
1356
|
-
(0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
|
|
1357
|
-
let fn = ast.statements[0];
|
|
1358
|
-
(0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
|
|
1359
|
-
let print = fn.func.body.statements[0];
|
|
1360
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
|
|
1361
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(print.expressions[0])).to.be.true;
|
|
1362
|
-
//argument type is float
|
|
1363
|
-
(0, testHelpers_spec_1.expectTypeToBe)(print.expressions[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), StringType_1.StringType);
|
|
1364
|
-
});
|
|
1365
|
-
it('flags invalid type cast syntax - multiple as', () => {
|
|
1366
|
-
var _a;
|
|
1367
|
-
let { diagnostics } = parse(`
|
|
1368
|
-
sub foo(key)
|
|
1369
|
-
getData(key as as string)
|
|
1370
|
-
end sub
|
|
1371
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1372
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1373
|
-
});
|
|
1374
|
-
it('flags invalid type cast syntax - no type after as', () => {
|
|
1375
|
-
var _a;
|
|
1376
|
-
let { diagnostics } = parse(`
|
|
1377
|
-
sub foo(key)
|
|
1378
|
-
getData(key as)
|
|
1379
|
-
end sub
|
|
1380
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1381
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1382
|
-
});
|
|
1383
|
-
it('allows declaring types on assignment in Brighterscript mode', () => {
|
|
1384
|
-
let { diagnostics } = parse(`
|
|
1385
|
-
sub foo()
|
|
1386
|
-
x as string = formatJson("some string")
|
|
1387
|
-
end sub
|
|
1388
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1389
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1390
|
-
});
|
|
1391
|
-
it('does not allow declaring types on assignment in brightscript mode', () => {
|
|
1392
|
-
var _a, _b;
|
|
1393
|
-
let { diagnostics } = parse(`
|
|
1394
|
-
sub foo()
|
|
1395
|
-
x as string = formatJson("some string")
|
|
1396
|
-
end sub
|
|
1397
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
1398
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1399
|
-
(0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.message).to.include('typed assignment');
|
|
1400
|
-
});
|
|
1401
|
-
});
|
|
1402
|
-
describe('grouped type expressions', () => {
|
|
1403
|
-
it('is not allowed in brightscript mode', () => {
|
|
1404
|
-
let parser = parse(`
|
|
1405
|
-
sub main(param as (string or integer))
|
|
1406
|
-
print param
|
|
1407
|
-
end sub
|
|
1408
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
1409
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')]);
|
|
1410
|
-
});
|
|
1411
|
-
it('allows group type expressions in parameters', () => {
|
|
1412
|
-
let { diagnostics } = parse(`
|
|
1413
|
-
sub main(param as (string or integer))
|
|
1414
|
-
print param
|
|
1415
|
-
end sub
|
|
1416
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1417
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1418
|
-
});
|
|
1419
|
-
it('allows group type expressions in type casts', () => {
|
|
1420
|
-
let { diagnostics } = parse(`
|
|
1421
|
-
sub main(val)
|
|
1422
|
-
printThing(val as (string or integer))
|
|
1423
|
-
end sub
|
|
1424
|
-
sub printThing(thing as (string or integer))
|
|
1425
|
-
print thing
|
|
1426
|
-
end sub
|
|
1427
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1428
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1429
|
-
});
|
|
1430
|
-
it('allows union of grouped type expressions', () => {
|
|
1431
|
-
let { diagnostics } = parse(`
|
|
1432
|
-
sub main(param as (string or integer) or (float or dynamic))
|
|
1433
|
-
print param
|
|
1434
|
-
end sub
|
|
1435
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1436
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1437
|
-
});
|
|
1438
|
-
it('allows nested grouped type expressions', () => {
|
|
1439
|
-
let { diagnostics } = parse(`
|
|
1440
|
-
sub main(param as ((string or integer) or (float or dynamic)))
|
|
1441
|
-
print param
|
|
1442
|
-
end sub
|
|
1443
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1444
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1445
|
-
});
|
|
1446
|
-
it('allows complicated grouped type expression', () => {
|
|
1447
|
-
let { diagnostics } = parse(`
|
|
1448
|
-
sub main(param as (({name as string} and {age as integer}) or (string and SomeInterface) or Klass and roAssociativeArray) )
|
|
1449
|
-
print param
|
|
1450
|
-
end sub
|
|
1451
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1452
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1453
|
-
});
|
|
1454
|
-
});
|
|
1455
|
-
describe('union types', () => {
|
|
1456
|
-
it('is not allowed in brightscript mode', () => {
|
|
1457
|
-
let parser = parse(`
|
|
1458
|
-
sub main(param as string or integer)
|
|
1459
|
-
print param
|
|
1460
|
-
end sub
|
|
1461
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
1462
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')]);
|
|
1463
|
-
});
|
|
1464
|
-
it('allows union types in parameters', () => {
|
|
1465
|
-
let { diagnostics } = parse(`
|
|
1466
|
-
sub main(param as string or integer)
|
|
1467
|
-
print param
|
|
1468
|
-
end sub
|
|
1469
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1470
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1471
|
-
});
|
|
1472
|
-
it('allows union types in type casts', () => {
|
|
1473
|
-
let { diagnostics } = parse(`
|
|
1474
|
-
sub main(val)
|
|
1475
|
-
printThing(val as string or integer)
|
|
1476
|
-
end sub
|
|
1477
|
-
sub printThing(thing as string or integer)
|
|
1478
|
-
print thing
|
|
1479
|
-
end sub
|
|
1480
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1481
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1482
|
-
});
|
|
1483
|
-
});
|
|
1484
|
-
describe('intersection types', () => {
|
|
1485
|
-
it('is not allowed in brightscript mode', () => {
|
|
1486
|
-
let parser = parse(`
|
|
1487
|
-
sub main(param as string and integer)
|
|
1488
|
-
print param
|
|
1489
|
-
end sub
|
|
1490
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
1491
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')]);
|
|
1492
|
-
});
|
|
1493
|
-
it('allows intersection types in parameters', () => {
|
|
1494
|
-
let { diagnostics } = parse(`
|
|
1495
|
-
sub main(param as string and integer)
|
|
1496
|
-
print param
|
|
1497
|
-
end sub
|
|
1498
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1499
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1500
|
-
});
|
|
1501
|
-
it('allows intersection types in type casts', () => {
|
|
1502
|
-
let { diagnostics } = parse(`
|
|
1503
|
-
sub main(val)
|
|
1504
|
-
printThing(val as string and integer)
|
|
1505
|
-
end sub
|
|
1506
|
-
sub printThing(thing as string and integer)
|
|
1507
|
-
print thing
|
|
1508
|
-
end sub
|
|
1509
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1510
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1511
|
-
});
|
|
1512
|
-
it('follows order of operations with "or" first lexically', () => {
|
|
1513
|
-
let { ast, diagnostics } = parse(`
|
|
1514
|
-
sub main(param as string or integer and float)
|
|
1515
|
-
print param
|
|
1516
|
-
end sub
|
|
1517
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1518
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1519
|
-
const func = ast.statements[0].func;
|
|
1520
|
-
const paramExpr = func.parameters[0];
|
|
1521
|
-
let binExpr = paramExpr.typeExpression.expression;
|
|
1522
|
-
//first level should be 'or'
|
|
1523
|
-
(0, chai_config_spec_1.expect)(binExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.Or);
|
|
1524
|
-
//right side should be 'and'
|
|
1525
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(binExpr.right)).to.be.true;
|
|
1526
|
-
const rightAndExpr = binExpr.right;
|
|
1527
|
-
(0, chai_config_spec_1.expect)(rightAndExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.And);
|
|
1528
|
-
});
|
|
1529
|
-
it('follows order of operations with "and" first lexically', () => {
|
|
1530
|
-
let { ast, diagnostics } = parse(`
|
|
1531
|
-
sub main(param as string and integer or float)
|
|
1532
|
-
print param
|
|
1533
|
-
end sub
|
|
1534
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1535
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1536
|
-
const func = ast.statements[0].func;
|
|
1537
|
-
const paramExpr = func.parameters[0];
|
|
1538
|
-
let binExpr = paramExpr.typeExpression.expression;
|
|
1539
|
-
//first level should be 'or'
|
|
1540
|
-
(0, chai_config_spec_1.expect)(binExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.Or);
|
|
1541
|
-
//left side should be 'and'
|
|
1542
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(binExpr.left)).to.be.true;
|
|
1543
|
-
const leftAndExpr = binExpr.left;
|
|
1544
|
-
(0, chai_config_spec_1.expect)(leftAndExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.And);
|
|
1545
|
-
});
|
|
1546
|
-
it('allows grouped expression to override order of operations', () => {
|
|
1547
|
-
let { ast, diagnostics } = parse(`
|
|
1548
|
-
sub main(param as string and (integer or float))
|
|
1549
|
-
print param
|
|
1550
|
-
end sub
|
|
1551
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1552
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1553
|
-
const func = ast.statements[0].func;
|
|
1554
|
-
const paramExpr = func.parameters[0];
|
|
1555
|
-
let binExpr = paramExpr.typeExpression.expression;
|
|
1556
|
-
//first level should be 'and'
|
|
1557
|
-
(0, chai_config_spec_1.expect)(binExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.And);
|
|
1558
|
-
//right side should be 'or'
|
|
1559
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(binExpr.right)).to.be.true;
|
|
1560
|
-
const groupedExpr = binExpr.right;
|
|
1561
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(groupedExpr)).to.be.true;
|
|
1562
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeExpression)(groupedExpr.expression)).to.be.true;
|
|
1563
|
-
const rightOrExpr = groupedExpr.expression.expression;
|
|
1564
|
-
(0, chai_config_spec_1.expect)(rightOrExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.Or);
|
|
1565
|
-
});
|
|
1566
|
-
describe('invalid syntax', () => {
|
|
1567
|
-
it('flags union type with missing sides', () => {
|
|
1568
|
-
let { diagnostics } = parse(`
|
|
1569
|
-
sub main(param as Thing or )
|
|
1570
|
-
print param
|
|
1571
|
-
end sub
|
|
1572
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1573
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('or').message);
|
|
1574
|
-
});
|
|
1575
|
-
it('flags missing type inside binary type', () => {
|
|
1576
|
-
var _a;
|
|
1577
|
-
let { diagnostics } = parse(`
|
|
1578
|
-
sub main(param as string or and float)
|
|
1579
|
-
print param
|
|
1580
|
-
end sub
|
|
1581
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1582
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1583
|
-
});
|
|
1584
|
-
it('flags missing group paren', () => {
|
|
1585
|
-
var _a;
|
|
1586
|
-
let { diagnostics } = parse(`
|
|
1587
|
-
sub main(param as (string or float)
|
|
1588
|
-
print param
|
|
1589
|
-
end sub
|
|
1590
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1591
|
-
(0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
|
|
1592
|
-
});
|
|
1593
|
-
});
|
|
1594
|
-
});
|
|
1595
|
-
describe('typed arrays', () => {
|
|
1596
|
-
it('is not allowed in brightscript mode', () => {
|
|
1597
|
-
let parser = parse(`
|
|
1598
|
-
sub main(things as string[])
|
|
1599
|
-
print things
|
|
1600
|
-
end sub
|
|
1601
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
1602
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typed arrays')]);
|
|
1603
|
-
});
|
|
1604
|
-
it('is allowed in brighterscript mode', () => {
|
|
1605
|
-
let { ast, diagnostics } = parse(`
|
|
1606
|
-
sub main(things as string[])
|
|
1607
|
-
print things
|
|
1608
|
-
end sub
|
|
1609
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1610
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1611
|
-
const paramType = ast.statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1612
|
-
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1613
|
-
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, StringType_1.StringType);
|
|
1614
|
-
});
|
|
1615
|
-
it('allows multi dimensional arrays', () => {
|
|
1616
|
-
let { ast, diagnostics } = parse(`
|
|
1617
|
-
sub main(things as string[][])
|
|
1618
|
-
print things
|
|
1619
|
-
end sub
|
|
1620
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1621
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1622
|
-
const paramType = ast.statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1623
|
-
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1624
|
-
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, types_1.ArrayType);
|
|
1625
|
-
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType.defaultType, StringType_1.StringType);
|
|
1626
|
-
});
|
|
1627
|
-
it('allows arrays as return types', () => {
|
|
1628
|
-
let { ast, diagnostics } = parse(`
|
|
1629
|
-
function getFourPrimes() as integer[]
|
|
1630
|
-
return [2, 3, 5, 7]
|
|
1631
|
-
end function
|
|
1632
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1633
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1634
|
-
const paramType = ast.statements[0].func.returnTypeExpression.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1635
|
-
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
|
|
1636
|
-
(0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, IntegerType_1.IntegerType);
|
|
1637
|
-
});
|
|
1638
|
-
it('allows arrays in union types', () => {
|
|
1639
|
-
let { ast, diagnostics } = parse(`
|
|
1640
|
-
sub foo(x as integer or integer[] or string or string[])
|
|
1641
|
-
print x
|
|
1642
|
-
end sub
|
|
1643
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1644
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1645
|
-
const paramType = ast.statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1646
|
-
(0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.UnionType);
|
|
1647
|
-
(0, chai_config_spec_1.expect)(paramType.toString().includes('Array<string>')).to.be.true;
|
|
1648
|
-
(0, chai_config_spec_1.expect)(paramType.toString().includes('Array<integer>')).to.be.true;
|
|
1649
|
-
});
|
|
1650
|
-
});
|
|
1651
|
-
describe('interfaces', () => {
|
|
1652
|
-
it('allows fields and methods', () => {
|
|
1653
|
-
let { ast, diagnostics } = parse(`
|
|
1654
|
-
interface SomeIFace
|
|
1655
|
-
name as string
|
|
1656
|
-
height as integer
|
|
1657
|
-
function getValue(thing as float) as object
|
|
1658
|
-
function getMe() as SomeIFace
|
|
1659
|
-
sub noop()
|
|
1660
|
-
end interface
|
|
1661
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1662
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1663
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1664
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1665
|
-
});
|
|
1666
|
-
it('allows untyped fields', () => {
|
|
1667
|
-
let { ast, diagnostics } = parse(`
|
|
1668
|
-
interface HasUntyped
|
|
1669
|
-
name
|
|
1670
|
-
end interface
|
|
1671
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1672
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1673
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1674
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1675
|
-
});
|
|
1676
|
-
it('allows optional fields', () => {
|
|
1677
|
-
let { ast, diagnostics } = parse(`
|
|
1678
|
-
interface HasOptional
|
|
1679
|
-
optional name as string
|
|
1680
|
-
optional height
|
|
1681
|
-
end interface
|
|
1682
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1683
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1684
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1685
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1686
|
-
const iface = ast.statements[0];
|
|
1687
|
-
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1688
|
-
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1689
|
-
// eslint-disable-next-line no-bitwise
|
|
1690
|
-
ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1691
|
-
});
|
|
1692
|
-
it('allows fields named optional', () => {
|
|
1693
|
-
let { ast, diagnostics } = parse(`
|
|
1694
|
-
interface IsJustOptional
|
|
1695
|
-
optional
|
|
1696
|
-
someThingElse
|
|
1697
|
-
end interface
|
|
1698
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1699
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1700
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1701
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1702
|
-
const iface = ast.statements[0];
|
|
1703
|
-
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
|
|
1704
|
-
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1705
|
-
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1706
|
-
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(2);
|
|
1707
|
-
// eslint-disable-next-line no-bitwise
|
|
1708
|
-
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(0));
|
|
1709
|
-
});
|
|
1710
|
-
it('allows fields named optional that are also optional', () => {
|
|
1711
|
-
let { ast, diagnostics } = parse(`
|
|
1712
|
-
interface IsJustOptional
|
|
1713
|
-
optional optional
|
|
1714
|
-
end interface
|
|
1715
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1716
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1717
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1718
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1719
|
-
const iface = ast.statements[0];
|
|
1720
|
-
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1721
|
-
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1722
|
-
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1723
|
-
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1724
|
-
// eslint-disable-next-line no-bitwise
|
|
1725
|
-
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1726
|
-
});
|
|
1727
|
-
it('allows optional methods', () => {
|
|
1728
|
-
let { ast, diagnostics } = parse(`
|
|
1729
|
-
interface HasOptional
|
|
1730
|
-
optional function getValue() as boolean
|
|
1731
|
-
optional sub noop()
|
|
1732
|
-
optional function process()
|
|
1733
|
-
end interface
|
|
1734
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1735
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1736
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1737
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1738
|
-
const iface = ast.statements[0];
|
|
1739
|
-
iface.methods.forEach(m => (0, chai_config_spec_1.expect)(m.isOptional).to.equal(true));
|
|
1740
|
-
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1741
|
-
// eslint-disable-next-line no-bitwise
|
|
1742
|
-
ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1743
|
-
});
|
|
1744
|
-
it('allows fields named `as` that are also optional', () => {
|
|
1745
|
-
let { ast, diagnostics } = parse(`
|
|
1746
|
-
interface IsJustOptional
|
|
1747
|
-
optional as
|
|
1748
|
-
end interface
|
|
1749
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1750
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1751
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1752
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1753
|
-
const iface = ast.statements[0];
|
|
1754
|
-
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1755
|
-
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1756
|
-
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1757
|
-
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1758
|
-
// eslint-disable-next-line no-bitwise
|
|
1759
|
-
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1760
|
-
});
|
|
1761
|
-
it('allows fields named `as` that are also typed', () => {
|
|
1762
|
-
let { ast, diagnostics } = parse(`
|
|
1763
|
-
interface IsJustOptional
|
|
1764
|
-
optional as as string
|
|
1765
|
-
end interface
|
|
1766
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1767
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1768
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1769
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1770
|
-
const iface = ast.statements[0];
|
|
1771
|
-
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
|
|
1772
|
-
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1773
|
-
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1774
|
-
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1775
|
-
// eslint-disable-next-line no-bitwise
|
|
1776
|
-
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
|
|
1777
|
-
});
|
|
1778
|
-
it('allows fields named `optional` that are also typed', () => {
|
|
1779
|
-
let { ast, diagnostics } = parse(`
|
|
1780
|
-
interface IsJustOptional
|
|
1781
|
-
optional as string
|
|
1782
|
-
end interface
|
|
1783
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1784
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1785
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
1786
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
|
|
1787
|
-
const iface = ast.statements[0];
|
|
1788
|
-
iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
|
|
1789
|
-
const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
1790
|
-
const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
|
|
1791
|
-
(0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
|
|
1792
|
-
// eslint-disable-next-line no-bitwise
|
|
1793
|
-
iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(0));
|
|
1794
|
-
});
|
|
1795
|
-
});
|
|
1796
|
-
describe('leadingTrivia', () => {
|
|
1797
|
-
it('gets leading trivia from functions', () => {
|
|
1798
|
-
let { ast } = parse(`
|
|
1799
|
-
' Nice function, bro
|
|
1800
|
-
function foo()
|
|
1801
|
-
return 1
|
|
1802
|
-
end function
|
|
1803
|
-
`);
|
|
1804
|
-
const funcStatements = ast.statements.filter(reflection_1.isFunctionStatement);
|
|
1805
|
-
const fooTrivia = funcStatements[0].leadingTrivia;
|
|
1806
|
-
(0, chai_config_spec_1.expect)(fooTrivia.length).to.be.greaterThan(0);
|
|
1807
|
-
(0, chai_config_spec_1.expect)(fooTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1808
|
-
});
|
|
1809
|
-
it('gets multiple lines of leading trivia', () => {
|
|
1810
|
-
let { ast, diagnostics } = parse(`
|
|
1811
|
-
' Say hello to someone
|
|
1812
|
-
'
|
|
1813
|
-
' @param {string} name the person you want to say hello to.
|
|
1814
|
-
sub sayHello(name = "world" as string)
|
|
1815
|
-
end sub
|
|
1816
|
-
`);
|
|
1817
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1818
|
-
const funcStatements = ast.statements.filter(reflection_1.isFunctionStatement);
|
|
1819
|
-
const helloTrivia = funcStatements[0].leadingTrivia;
|
|
1820
|
-
(0, chai_config_spec_1.expect)(helloTrivia.length).to.be.greaterThan(0);
|
|
1821
|
-
(0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(3);
|
|
1822
|
-
});
|
|
1823
|
-
it('gets leading trivia from classes', () => {
|
|
1824
|
-
let { ast } = parse(`
|
|
1825
|
-
' hello
|
|
1826
|
-
' classes
|
|
1827
|
-
class Hello
|
|
1828
|
-
end class
|
|
1829
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1830
|
-
const classStatements = ast.statements.filter(reflection_1.isClassStatement);
|
|
1831
|
-
const trivia = classStatements[0].leadingTrivia;
|
|
1832
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1833
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1834
|
-
});
|
|
1835
|
-
it('gets leading trivia from functions with annotations', () => {
|
|
1836
|
-
let { ast } = parse(`
|
|
1837
|
-
' hello comment 1
|
|
1838
|
-
' hello comment 2
|
|
1839
|
-
@annotation
|
|
1840
|
-
' hello comment 3
|
|
1841
|
-
@otherAnnotation
|
|
1842
|
-
sub sayHello(name = "world" as string)
|
|
1843
|
-
end sub
|
|
1844
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1845
|
-
const funcStatements = ast.statements.filter(reflection_1.isFunctionStatement);
|
|
1846
|
-
const helloTrivia = funcStatements[0].leadingTrivia;
|
|
1847
|
-
(0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(0);
|
|
1848
|
-
const helloAnnotationTrivia = funcStatements[0].annotations[0].leadingTrivia;
|
|
1849
|
-
(0, chai_config_spec_1.expect)(helloAnnotationTrivia.length).to.be.greaterThan(0);
|
|
1850
|
-
(0, chai_config_spec_1.expect)(helloAnnotationTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1851
|
-
const otherAnnotationTrivia = funcStatements[0].annotations[1].leadingTrivia;
|
|
1852
|
-
(0, chai_config_spec_1.expect)(otherAnnotationTrivia.length).to.be.greaterThan(0);
|
|
1853
|
-
(0, chai_config_spec_1.expect)(otherAnnotationTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1854
|
-
});
|
|
1855
|
-
it('gets leading trivia from class methods', () => {
|
|
1856
|
-
let { ast } = parse(`
|
|
1857
|
-
' hello
|
|
1858
|
-
' classes
|
|
1859
|
-
class Hello
|
|
1860
|
-
|
|
1861
|
-
' Gets the value of PI
|
|
1862
|
-
' Not a dessert
|
|
1863
|
-
function getPi() as float
|
|
1864
|
-
return 3.14
|
|
1865
|
-
end function
|
|
1866
|
-
|
|
1867
|
-
' Gets a dessert
|
|
1868
|
-
function getPie() as string
|
|
1869
|
-
return "Apple Pie"
|
|
1870
|
-
end function
|
|
1871
|
-
end class
|
|
1872
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1873
|
-
const classStatement = ast.statements.filter(reflection_1.isClassStatement)[0];
|
|
1874
|
-
const methodStatements = classStatement.methods;
|
|
1875
|
-
// function getPi()
|
|
1876
|
-
let trivia = methodStatements[0].leadingTrivia;
|
|
1877
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1878
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1879
|
-
// function getPie()
|
|
1880
|
-
trivia = methodStatements[1].leadingTrivia;
|
|
1881
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1882
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1883
|
-
});
|
|
1884
|
-
it('gets leading trivia from class fields', () => {
|
|
1885
|
-
let { ast } = parse(`
|
|
1886
|
-
' hello
|
|
1887
|
-
' classes
|
|
1888
|
-
class Thing
|
|
1889
|
-
' like the sky
|
|
1890
|
-
' or a blueberry, evn though that's purple
|
|
1891
|
-
color = "blue"
|
|
1892
|
-
|
|
1893
|
-
' My name
|
|
1894
|
-
public name as string
|
|
1895
|
-
|
|
1896
|
-
' Only I know how old I am
|
|
1897
|
-
private age = 42
|
|
1898
|
-
end class
|
|
1899
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1900
|
-
const classStatement = ast.statements.filter(reflection_1.isClassStatement)[0];
|
|
1901
|
-
const fieldStatements = classStatement.fields;
|
|
1902
|
-
// color = "blue"
|
|
1903
|
-
let trivia = fieldStatements[0].leadingTrivia;
|
|
1904
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1905
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
|
|
1906
|
-
// public name as string
|
|
1907
|
-
trivia = fieldStatements[1].leadingTrivia;
|
|
1908
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1909
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1910
|
-
// private age = 42
|
|
1911
|
-
trivia = fieldStatements[2].leadingTrivia;
|
|
1912
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1913
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1914
|
-
});
|
|
1915
|
-
it('gets leading trivia from interfaces', () => {
|
|
1916
|
-
let { ast } = parse(`
|
|
1917
|
-
' Description of interface
|
|
1918
|
-
interface myIface
|
|
1919
|
-
' comment
|
|
1920
|
-
someField as integer
|
|
1921
|
-
|
|
1922
|
-
'comment
|
|
1923
|
-
function someFunc() as string
|
|
1924
|
-
end interface
|
|
1925
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1926
|
-
const ifaceStatement = ast.statements.filter(reflection_1.isInterfaceStatement)[0];
|
|
1927
|
-
const fieldStatements = ifaceStatement.fields;
|
|
1928
|
-
const methodStatements = ifaceStatement.methods;
|
|
1929
|
-
// interface myIface
|
|
1930
|
-
let trivia = ifaceStatement.leadingTrivia;
|
|
1931
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1932
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1933
|
-
// someField as integer
|
|
1934
|
-
trivia = fieldStatements[0].leadingTrivia;
|
|
1935
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1936
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1937
|
-
// function someFunc() as string
|
|
1938
|
-
trivia = methodStatements[0].leadingTrivia;
|
|
1939
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1940
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1941
|
-
});
|
|
1942
|
-
it('gets leading trivia from namespaces', () => {
|
|
1943
|
-
let { ast } = parse(`
|
|
1944
|
-
' Description of interface
|
|
1945
|
-
namespace Nested.Name.Space
|
|
1946
|
-
|
|
1947
|
-
end namespace
|
|
1948
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
1949
|
-
const nameSpaceStatement = ast.statements.filter(reflection_1.isNamespaceStatement)[0];
|
|
1950
|
-
// namespace Nested.Name.Space
|
|
1951
|
-
let trivia = nameSpaceStatement.leadingTrivia;
|
|
1952
|
-
(0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
|
|
1953
|
-
(0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
|
|
1954
|
-
});
|
|
1955
|
-
});
|
|
1956
|
-
describe('unary/binary ordering', () => {
|
|
1957
|
-
it('creates the correct operator order for `not x = x` code', () => {
|
|
1958
|
-
let { ast, diagnostics } = parse(`
|
|
1959
|
-
function isStrNotEmpty(myStr as string) as boolean
|
|
1960
|
-
return not myStr = ""
|
|
1961
|
-
end function
|
|
1962
|
-
`);
|
|
1963
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1964
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
1965
|
-
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
1966
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1967
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
|
|
1968
|
-
});
|
|
1969
|
-
it('creates the correct operator order for `not x + x` code', () => {
|
|
1970
|
-
let { ast, diagnostics } = parse(`
|
|
1971
|
-
function tryStuff() as integer
|
|
1972
|
-
return not 1 + 3 ' same as "not (3)" ... eg. the "flipped bits" of 3 (0000 0011) -> 1111 1100, or -4
|
|
1973
|
-
end function
|
|
1974
|
-
`);
|
|
1975
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1976
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
1977
|
-
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
1978
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
1979
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
|
|
1980
|
-
});
|
|
1981
|
-
it('creates the correct operator order for `x = not x` code', () => {
|
|
1982
|
-
let { ast, diagnostics } = parse(`
|
|
1983
|
-
function tryStuff() as boolean
|
|
1984
|
-
return 4 = not -5 ' same as "4 = 4"
|
|
1985
|
-
end function
|
|
1986
|
-
`);
|
|
1987
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
1988
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
1989
|
-
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
1990
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn)).to.be.true;
|
|
1991
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(insideReturn.left)).to.be.true;
|
|
1992
|
-
const right = insideReturn.right;
|
|
1993
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right)).to.be.true;
|
|
1994
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right.right)).to.be.true; // not ( - ( 5))
|
|
1995
|
-
});
|
|
1996
|
-
it('allows multiple nots', () => {
|
|
1997
|
-
let { ast, diagnostics } = parse(`
|
|
1998
|
-
function tryStuff() as integer
|
|
1999
|
-
return not not not 4
|
|
2000
|
-
end function
|
|
2001
|
-
`);
|
|
2002
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2003
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
2004
|
-
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
2005
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
2006
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
|
|
2007
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
|
|
2008
|
-
});
|
|
2009
|
-
it('allows multiple -', () => {
|
|
2010
|
-
let { ast, diagnostics } = parse(`
|
|
2011
|
-
function tryStuff() as integer
|
|
2012
|
-
return - - - 4
|
|
2013
|
-
end function
|
|
2014
|
-
`);
|
|
2015
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2016
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
|
|
2017
|
-
const insideReturn = ast.statements[0].func.body.statements[0].value;
|
|
2018
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
|
|
2019
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
|
|
2020
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
|
|
2021
|
-
});
|
|
2022
|
-
});
|
|
2023
|
-
describe('typecast statement', () => {
|
|
2024
|
-
it('allows typecast statement ', () => {
|
|
2025
|
-
let { ast, diagnostics } = parse(`
|
|
2026
|
-
typeCAST m AS roAssociativeArray
|
|
2027
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2028
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2029
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isTypecastStatement)(ast.statements[0])).to.be.true;
|
|
2030
|
-
const stmt = ast.statements[0];
|
|
2031
|
-
(0, chai_config_spec_1.expect)(stmt.tokens.typecast.text).to.eq('typeCAST');
|
|
2032
|
-
(0, chai_config_spec_1.expect)(stmt.typecastExpression).to.exist;
|
|
2033
|
-
});
|
|
2034
|
-
it('is disallowed in brightscript mode', () => {
|
|
2035
|
-
let { diagnostics } = parse(`
|
|
2036
|
-
typecast m AS roAssociativeArray
|
|
2037
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
2038
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2039
|
-
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typecast statements')
|
|
2040
|
-
]);
|
|
2041
|
-
});
|
|
2042
|
-
it('allows `typecast` for function name', () => {
|
|
2043
|
-
let { ast, diagnostics } = parse(`
|
|
2044
|
-
function typecast() as integer
|
|
2045
|
-
return 1
|
|
2046
|
-
end function
|
|
2047
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2048
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2049
|
-
(0, chai_config_spec_1.expect)(ast.statements[0].tokens.name.text).to.eq('typecast');
|
|
2050
|
-
});
|
|
2051
|
-
it('allows `typecast` for variable name', () => {
|
|
2052
|
-
let { ast, diagnostics } = parse(`
|
|
2053
|
-
function foo() as integer
|
|
2054
|
-
typecast = 1
|
|
2055
|
-
return typecast
|
|
2056
|
-
end function
|
|
2057
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2058
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2059
|
-
(0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].tokens.name.text).to.eq('typecast');
|
|
2060
|
-
});
|
|
2061
|
-
it('is allowed in function', () => {
|
|
2062
|
-
let { diagnostics } = parse(`
|
|
2063
|
-
function foo() as integer
|
|
2064
|
-
typecast m as MyObject
|
|
2065
|
-
return m.getNum()
|
|
2066
|
-
end function
|
|
2067
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2068
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2069
|
-
});
|
|
2070
|
-
it('is allowed in function literal', () => {
|
|
2071
|
-
let { diagnostics } = parse(`
|
|
2072
|
-
interface PiGetter
|
|
2073
|
-
pi as float
|
|
2074
|
-
function getPi() as float
|
|
2075
|
-
end interface
|
|
2076
|
-
|
|
2077
|
-
function makePiGetter() as object
|
|
2078
|
-
x = {
|
|
2079
|
-
pi: 3.14,
|
|
2080
|
-
getPi: function() as float
|
|
2081
|
-
typecast m as PiGetter
|
|
2082
|
-
return m.pi
|
|
2083
|
-
end function
|
|
2084
|
-
}
|
|
2085
|
-
return x
|
|
2086
|
-
end function
|
|
2087
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2088
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2089
|
-
});
|
|
2090
|
-
});
|
|
2091
|
-
describe('conditional compilation', () => {
|
|
2092
|
-
it('contains code from conditional compile blocks', () => {
|
|
2093
|
-
let { ast, diagnostics } = parse(`
|
|
2094
|
-
sub foo()
|
|
2095
|
-
#if DEBUG
|
|
2096
|
-
print "hello"
|
|
2097
|
-
#end if
|
|
2098
|
-
end sub
|
|
2099
|
-
`, Parser_1.ParseMode.BrighterScript, { debug: true });
|
|
2100
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2101
|
-
const funcBlock = ast.statements[0].func.body;
|
|
2102
|
-
(0, chai_config_spec_1.expect)(funcBlock.statements.length).to.eq(1);
|
|
2103
|
-
const ccStmt = funcBlock.statements[0];
|
|
2104
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2105
|
-
const printStmt = ccStmt.thenBranch.statements[0];
|
|
2106
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
|
|
2107
|
-
});
|
|
2108
|
-
it('contains code from conditional compile else blocks', () => {
|
|
2109
|
-
let { ast, diagnostics } = parse(`
|
|
2110
|
-
sub foo()
|
|
2111
|
-
#if DEBUG
|
|
2112
|
-
m.pi = 3.14
|
|
2113
|
-
#else
|
|
2114
|
-
print "hello"
|
|
2115
|
-
#end if
|
|
2116
|
-
end sub
|
|
2117
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2118
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2119
|
-
const funcBlock = ast.statements[0].func.body;
|
|
2120
|
-
const ccStmt = funcBlock.statements[0];
|
|
2121
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2122
|
-
(0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
|
|
2123
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isBlock)(ccStmt.elseBranch)).to.true;
|
|
2124
|
-
const printStmt = ccStmt.elseBranch.statements[0];
|
|
2125
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
|
|
2126
|
-
});
|
|
2127
|
-
it('contains code from conditional compile else if blocks', () => {
|
|
2128
|
-
let { ast, diagnostics } = parse(`
|
|
2129
|
-
sub foo()
|
|
2130
|
-
#if DEBUG
|
|
2131
|
-
m.pi = 3.14
|
|
2132
|
-
#else if PROD
|
|
2133
|
-
print "hello"
|
|
2134
|
-
#end if
|
|
2135
|
-
end sub
|
|
2136
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2137
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2138
|
-
const funcBlock = ast.statements[0].func.body;
|
|
2139
|
-
const ccStmt = funcBlock.statements[0];
|
|
2140
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2141
|
-
(0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
|
|
2142
|
-
const elseBranch = ccStmt.elseBranch;
|
|
2143
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2144
|
-
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('PROD');
|
|
2145
|
-
const printStmt = elseBranch.thenBranch.statements[0];
|
|
2146
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
|
|
2147
|
-
});
|
|
2148
|
-
it('contains code from multiple conditional compile else if blocks', () => {
|
|
2149
|
-
let { ast, diagnostics } = parse(`
|
|
2150
|
-
sub foo()
|
|
2151
|
-
#if DEBUG
|
|
2152
|
-
m.pi = 3.14
|
|
2153
|
-
#else if PROD
|
|
2154
|
-
print "hello"
|
|
2155
|
-
#else if ABC
|
|
2156
|
-
print "hello"
|
|
2157
|
-
#else if DEF
|
|
2158
|
-
print "hello"
|
|
2159
|
-
#else if HIJ
|
|
2160
|
-
print "hello"
|
|
2161
|
-
#else
|
|
2162
|
-
x = 78
|
|
2163
|
-
#end if
|
|
2164
|
-
end sub
|
|
2165
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2166
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2167
|
-
const funcBlock = ast.statements[0].func.body;
|
|
2168
|
-
const ccStmt = funcBlock.statements[0];
|
|
2169
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2170
|
-
(0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
|
|
2171
|
-
let elseBranch = ccStmt.elseBranch;
|
|
2172
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2173
|
-
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('PROD');
|
|
2174
|
-
elseBranch = elseBranch.elseBranch;
|
|
2175
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2176
|
-
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('ABC');
|
|
2177
|
-
elseBranch = elseBranch.elseBranch;
|
|
2178
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2179
|
-
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('DEF');
|
|
2180
|
-
elseBranch = elseBranch.elseBranch;
|
|
2181
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
|
|
2182
|
-
(0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('HIJ');
|
|
2183
|
-
let lastElse = elseBranch.elseBranch;
|
|
2184
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isBlock)(lastElse)).to.true;
|
|
2185
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(lastElse.statements[0])).to.true;
|
|
2186
|
-
});
|
|
2187
|
-
it('allows empty conditional compilation blocks', () => {
|
|
2188
|
-
let { ast, diagnostics } = parse(`
|
|
2189
|
-
#if DEBUG
|
|
2190
|
-
#else if PROD
|
|
2191
|
-
#else
|
|
2192
|
-
#end if
|
|
2193
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2194
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2195
|
-
const ccStmt = ast.statements[0];
|
|
2196
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2197
|
-
(0, chai_config_spec_1.expect)(ccStmt.thenBranch.statements.length).to.eq(0);
|
|
2198
|
-
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.thenBranch.statements.length).to.eq(0);
|
|
2199
|
-
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.elseBranch.statements.length).to.eq(0);
|
|
2200
|
-
});
|
|
2201
|
-
it('allows only comments in compilation blocks', () => {
|
|
2202
|
-
let { ast, diagnostics } = parse(`
|
|
2203
|
-
' before if
|
|
2204
|
-
#if DEBUG
|
|
2205
|
-
' this is debug
|
|
2206
|
-
#else if PROD
|
|
2207
|
-
' this is prod
|
|
2208
|
-
#else
|
|
2209
|
-
' this is neither
|
|
2210
|
-
#end if
|
|
2211
|
-
' after if
|
|
2212
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2213
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2214
|
-
const ccStmt = ast.statements[0];
|
|
2215
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
|
|
2216
|
-
(0, chai_config_spec_1.expect)(ccStmt.thenBranch.statements.length).to.eq(0);
|
|
2217
|
-
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.thenBranch.statements.length).to.eq(0);
|
|
2218
|
-
(0, chai_config_spec_1.expect)(ccStmt.elseBranch.elseBranch.statements.length).to.eq(0);
|
|
2219
|
-
});
|
|
2220
|
-
it('has no error when safely closing block', () => {
|
|
2221
|
-
let { diagnostics } = parse(`
|
|
2222
|
-
sub foo()
|
|
2223
|
-
#if DEBUG
|
|
2224
|
-
if m.enabled
|
|
2225
|
-
print "hello"
|
|
2226
|
-
end if
|
|
2227
|
-
#end if
|
|
2228
|
-
end sub
|
|
2229
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2230
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2231
|
-
});
|
|
2232
|
-
it('has error when unsafely closing block', () => {
|
|
2233
|
-
let { diagnostics } = parse(`
|
|
2234
|
-
sub foo()
|
|
2235
|
-
if m.enabled
|
|
2236
|
-
#if DEBUG
|
|
2237
|
-
print "hello"
|
|
2238
|
-
end if
|
|
2239
|
-
#end if
|
|
2240
|
-
end sub
|
|
2241
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2242
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2243
|
-
DiagnosticMessages_1.DiagnosticMessages.unsafeUnmatchedTerminatorInConditionalCompileBlock('end if').message
|
|
2244
|
-
]);
|
|
2245
|
-
});
|
|
2246
|
-
it('has error when unsafely opening block', () => {
|
|
2247
|
-
let { diagnostics } = parse(`
|
|
2248
|
-
sub foo()
|
|
2249
|
-
#if DEBUG
|
|
2250
|
-
if m.enabled
|
|
2251
|
-
print "hello"
|
|
2252
|
-
#end if
|
|
2253
|
-
end if
|
|
2254
|
-
end sub
|
|
2255
|
-
`, Parser_1.ParseMode.BrighterScript, { debug: true });
|
|
2256
|
-
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2257
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedTerminator('end if', 'if').message,
|
|
2258
|
-
DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('end if').message
|
|
2259
|
-
]);
|
|
2260
|
-
});
|
|
2261
|
-
it('has no diagnostics from false blocks', () => {
|
|
2262
|
-
let { diagnostics } = parse(`
|
|
2263
|
-
sub foo()
|
|
2264
|
-
#if DEBUG
|
|
2265
|
-
blah blah blah
|
|
2266
|
-
#end if
|
|
2267
|
-
|
|
2268
|
-
#if false
|
|
2269
|
-
there are no diagnostics here
|
|
2270
|
-
#end if
|
|
2271
|
-
end sub
|
|
2272
|
-
`, Parser_1.ParseMode.BrighterScript, { debug: false });
|
|
2273
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2274
|
-
});
|
|
2275
|
-
it('allows #if not bs_const', () => {
|
|
2276
|
-
let { diagnostics } = parse(`
|
|
2277
|
-
sub foo()
|
|
2278
|
-
#if not DEBUG
|
|
2279
|
-
print "not debug"
|
|
2280
|
-
#end if
|
|
2281
|
-
end sub
|
|
2282
|
-
`, Parser_1.ParseMode.BrighterScript, { debug: false });
|
|
2283
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2284
|
-
});
|
|
2285
|
-
it('allows #elseif not bs_const', () => {
|
|
2286
|
-
let { diagnostics } = parse(`
|
|
2287
|
-
sub foo()
|
|
2288
|
-
#if DEBUG
|
|
2289
|
-
print "debug"
|
|
2290
|
-
#else if not STAGING
|
|
2291
|
-
print "not debug and not staging"
|
|
2292
|
-
#end if
|
|
2293
|
-
end sub
|
|
2294
|
-
`, Parser_1.ParseMode.BrighterScript, { debug: false, staging: false });
|
|
2295
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2296
|
-
});
|
|
2297
|
-
describe('#const', () => {
|
|
2298
|
-
it('parses #const', () => {
|
|
2299
|
-
let { ast, diagnostics } = parse(`
|
|
2300
|
-
#const test = true
|
|
2301
|
-
sub foo()
|
|
2302
|
-
#const debug = test
|
|
2303
|
-
end sub
|
|
2304
|
-
# const spaces = false
|
|
2305
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2306
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2307
|
-
//#const test = true
|
|
2308
|
-
let ccc = ast.statements[0];
|
|
2309
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
|
|
2310
|
-
(0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('test');
|
|
2311
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(ccc.assignment.value)).to.be.true;
|
|
2312
|
-
(0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.value.text).to.eq('true');
|
|
2313
|
-
//#const debug = test
|
|
2314
|
-
ccc = ast.statements[1].func.body.statements[0];
|
|
2315
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
|
|
2316
|
-
(0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('debug');
|
|
2317
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)(ccc.assignment.value)).to.be.true;
|
|
2318
|
-
(0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.name.text).to.eq('test');
|
|
2319
|
-
//# const spaces = false
|
|
2320
|
-
ccc = ast.statements[2];
|
|
2321
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
|
|
2322
|
-
(0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('spaces');
|
|
2323
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(ccc.assignment.value)).to.be.true;
|
|
2324
|
-
(0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.value.text).to.eq('false');
|
|
2325
|
-
});
|
|
2326
|
-
it('has diagnostic if no lhs', () => {
|
|
2327
|
-
let { diagnostics } = parse(`
|
|
2328
|
-
#const test
|
|
2329
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2330
|
-
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2331
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedOperator([TokenKind_1.TokenKind.Equal], 'test').message
|
|
2332
|
-
]);
|
|
2333
|
-
});
|
|
2334
|
-
it('has diagnostic if invalid operator', () => {
|
|
2335
|
-
let { diagnostics } = parse(`
|
|
2336
|
-
#const test += other
|
|
2337
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2338
|
-
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2339
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedOperator([TokenKind_1.TokenKind.Equal], 'test').message
|
|
2340
|
-
]);
|
|
2341
|
-
});
|
|
2342
|
-
it('has diagnostic if invalid lhs', () => {
|
|
2343
|
-
let { diagnostics } = parse(`
|
|
2344
|
-
#const test = 4
|
|
2345
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2346
|
-
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2347
|
-
DiagnosticMessages_1.DiagnosticMessages.invalidHashConstValue().message
|
|
2348
|
-
]);
|
|
2349
|
-
});
|
|
2350
|
-
});
|
|
2351
|
-
describe('#error', () => {
|
|
2352
|
-
it('parses #error', () => {
|
|
2353
|
-
let { ast, diagnostics } = parse(`
|
|
2354
|
-
#error
|
|
2355
|
-
sub foo()
|
|
2356
|
-
#error this is a LONG "message" :: with colons, etc.
|
|
2357
|
-
end sub
|
|
2358
|
-
# error this one has spaces
|
|
2359
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2360
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2361
|
-
//#error
|
|
2362
|
-
let cce = ast.statements[0];
|
|
2363
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
|
|
2364
|
-
(0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
|
|
2365
|
-
(0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('');
|
|
2366
|
-
//#error this is a long "message" :: with colons, etc.
|
|
2367
|
-
cce = ast.statements[1].func.body.statements[0];
|
|
2368
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
|
|
2369
|
-
(0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
|
|
2370
|
-
(0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('this is a LONG "message" :: with colons, etc.');
|
|
2371
|
-
//# error this one has spaces
|
|
2372
|
-
cce = ast.statements[2];
|
|
2373
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
|
|
2374
|
-
(0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
|
|
2375
|
-
(0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('this one has spaces');
|
|
2376
|
-
});
|
|
2377
|
-
});
|
|
2378
|
-
});
|
|
2379
|
-
describe('alias statement', () => {
|
|
2380
|
-
it('allows alias statement ', () => {
|
|
2381
|
-
let { ast, diagnostics } = parse(`
|
|
2382
|
-
ALIAS x = lcase
|
|
2383
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2384
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2385
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isAliasStatement)(ast.statements[0])).to.be.true;
|
|
2386
|
-
const stmt = ast.statements[0];
|
|
2387
|
-
(0, chai_config_spec_1.expect)(stmt.tokens.alias.text).to.eq('ALIAS');
|
|
2388
|
-
(0, chai_config_spec_1.expect)(stmt.value).to.exist;
|
|
2389
|
-
});
|
|
2390
|
-
it('is disallowed in brightscript mode', () => {
|
|
2391
|
-
let { diagnostics } = parse(`
|
|
2392
|
-
alias x = lcase
|
|
2393
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
2394
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2395
|
-
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('alias statements')
|
|
2396
|
-
]);
|
|
2397
|
-
});
|
|
2398
|
-
it('allows `alias` for function name', () => {
|
|
2399
|
-
let { ast, diagnostics } = parse(`
|
|
2400
|
-
function alias() as integer
|
|
2401
|
-
return 1
|
|
2402
|
-
end function
|
|
2403
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2404
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2405
|
-
(0, chai_config_spec_1.expect)(ast.statements[0].tokens.name.text).to.eq('alias');
|
|
2406
|
-
});
|
|
2407
|
-
it('allows `alias` for variable name', () => {
|
|
2408
|
-
let { ast, diagnostics } = parse(`
|
|
2409
|
-
function foo() as integer
|
|
2410
|
-
alias = 1
|
|
2411
|
-
return alias
|
|
2412
|
-
end function
|
|
2413
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2414
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2415
|
-
(0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].tokens.name.text).to.eq('alias');
|
|
2416
|
-
});
|
|
2417
|
-
});
|
|
2418
|
-
describe('type statement', () => {
|
|
2419
|
-
it('allows type statement ', () => {
|
|
2420
|
-
let { ast, diagnostics } = parse(`
|
|
2421
|
-
TYPE x = string
|
|
2422
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2423
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2424
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
|
|
2425
|
-
const stmt = ast.statements[0];
|
|
2426
|
-
(0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('TYPE');
|
|
2427
|
-
(0, chai_config_spec_1.expect)(stmt.value).to.exist;
|
|
2428
|
-
});
|
|
2429
|
-
it('is disallowed in brightscript mode', () => {
|
|
2430
|
-
let { diagnostics } = parse(`
|
|
2431
|
-
type x = string
|
|
2432
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
2433
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2434
|
-
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('type statements')
|
|
2435
|
-
]);
|
|
2436
|
-
});
|
|
2437
|
-
it('disallows `type` for function name', () => {
|
|
2438
|
-
let { diagnostics } = parse(`
|
|
2439
|
-
function type() as integer
|
|
2440
|
-
return 1
|
|
2441
|
-
end function
|
|
2442
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2443
|
-
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2444
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier('type').message
|
|
2445
|
-
]);
|
|
2446
|
-
});
|
|
2447
|
-
it('disallows `type` for variable name', () => {
|
|
2448
|
-
let { diagnostics } = parse(`
|
|
2449
|
-
function foo() as integer
|
|
2450
|
-
type = 1
|
|
2451
|
-
return type
|
|
2452
|
-
end function
|
|
2453
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2454
|
-
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2455
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier('type').message
|
|
2456
|
-
]);
|
|
2457
|
-
});
|
|
2458
|
-
it('has error when rhs is not a type', () => {
|
|
2459
|
-
let { diagnostics } = parse(`
|
|
2460
|
-
type x = 123
|
|
2461
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2462
|
-
(0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
|
|
2463
|
-
DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('=').message
|
|
2464
|
-
]);
|
|
2465
|
-
});
|
|
2466
|
-
it('allows type statement with complicated type', () => {
|
|
2467
|
-
let { ast, diagnostics } = parse(`
|
|
2468
|
-
type x = string or CustomKlass or roAssociativeArray
|
|
2469
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2470
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2471
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
|
|
2472
|
-
const stmt = ast.statements[0];
|
|
2473
|
-
(0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('type');
|
|
2474
|
-
(0, chai_config_spec_1.expect)(stmt.value).to.exist;
|
|
2475
|
-
});
|
|
2476
|
-
it('allows grouped expressions in type statement', () => {
|
|
2477
|
-
let { ast, diagnostics } = parse(`
|
|
2478
|
-
type guy = ({name as string} or {age as integer}) and {foo as boolean, age as integer}
|
|
2479
|
-
|
|
2480
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2481
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2482
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
|
|
2483
|
-
const stmt = ast.statements[0];
|
|
2484
|
-
(0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('type');
|
|
2485
|
-
(0, chai_config_spec_1.expect)(stmt.value).to.exist;
|
|
2486
|
-
});
|
|
2487
|
-
});
|
|
2488
|
-
describe('jump statements', () => {
|
|
2489
|
-
it('should recognize `exit for`', () => {
|
|
2490
|
-
let { ast, diagnostics } = parse(`
|
|
2491
|
-
sub main()
|
|
2492
|
-
for i = 1 to 10
|
|
2493
|
-
exit for
|
|
2494
|
-
end for
|
|
2495
|
-
end sub
|
|
2496
|
-
`);
|
|
2497
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2498
|
-
let loop = ast.statements[0].func.body.statements[0];
|
|
2499
|
-
let exitStmt = loop.body.statements[0];
|
|
2500
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
|
|
2501
|
-
(0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('for');
|
|
2502
|
-
});
|
|
2503
|
-
it('should recognize `exit while`', () => {
|
|
2504
|
-
let { ast, diagnostics } = parse(`
|
|
2505
|
-
sub main(i)
|
|
2506
|
-
while i < 10
|
|
2507
|
-
exit while
|
|
2508
|
-
i++
|
|
2509
|
-
end while
|
|
2510
|
-
end sub
|
|
2511
|
-
`);
|
|
2512
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2513
|
-
let loop = ast.statements[0].func.body.statements[0];
|
|
2514
|
-
let exitStmt = loop.body.statements[0];
|
|
2515
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
|
|
2516
|
-
(0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('while');
|
|
2517
|
-
});
|
|
2518
|
-
it('should recognize `exitwhile` (one word)', () => {
|
|
2519
|
-
let { ast, diagnostics } = parse(`
|
|
2520
|
-
sub main(i)
|
|
2521
|
-
while i < 10
|
|
2522
|
-
exitwhile
|
|
2523
|
-
i++
|
|
2524
|
-
end while
|
|
2525
|
-
end sub
|
|
2526
|
-
`);
|
|
2527
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2528
|
-
let loop = ast.statements[0].func.body.statements[0];
|
|
2529
|
-
let exitStmt = loop.body.statements[0];
|
|
2530
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
|
|
2531
|
-
(0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('while');
|
|
2532
|
-
});
|
|
2533
|
-
it('should allow identifiers named `exitfor` (one word)', () => {
|
|
2534
|
-
let { ast, diagnostics } = parse(`
|
|
2535
|
-
sub main()
|
|
2536
|
-
for i = 1 to 10
|
|
2537
|
-
exitfor = 1
|
|
2538
|
-
exit for
|
|
2539
|
-
end for
|
|
2540
|
-
end sub
|
|
2541
|
-
`);
|
|
2542
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2543
|
-
let loop = ast.statements[0].func.body.statements[0];
|
|
2544
|
-
let assignment = loop.body.statements[0];
|
|
2545
|
-
(0, chai_config_spec_1.expect)(assignment.tokens.name.text).to.eq('exitfor');
|
|
2546
|
-
let exitStmt = loop.body.statements[1];
|
|
2547
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
|
|
2548
|
-
(0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('for');
|
|
2549
|
-
});
|
|
2550
|
-
});
|
|
2551
|
-
describe('custom types', () => {
|
|
2552
|
-
it('built-in interface param types disallowed in brightscript mode', () => {
|
|
2553
|
-
let { diagnostics } = parse(`
|
|
2554
|
-
sub test(foo as roAssociativeArray)
|
|
2555
|
-
print foo.x
|
|
2556
|
-
end sub
|
|
2557
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
2558
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2559
|
-
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2560
|
-
]);
|
|
2561
|
-
});
|
|
2562
|
-
it('built-in interface types disallowed in brightscript mode', () => {
|
|
2563
|
-
let { diagnostics } = parse(`
|
|
2564
|
-
function test(foo) as roAssociativeArray
|
|
2565
|
-
return foo.x
|
|
2566
|
-
end function
|
|
2567
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
2568
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2569
|
-
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2570
|
-
]);
|
|
2571
|
-
});
|
|
2572
|
-
it('custom param types disallowed in brightscript mode', () => {
|
|
2573
|
-
let { diagnostics } = parse(`
|
|
2574
|
-
sub test(foo as Whatever)
|
|
2575
|
-
print foo.x
|
|
2576
|
-
end sub
|
|
2577
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
2578
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2579
|
-
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2580
|
-
]);
|
|
2581
|
-
});
|
|
2582
|
-
it('custom return types disallowed in brightscript mode', () => {
|
|
2583
|
-
let { diagnostics } = parse(`
|
|
2584
|
-
function test(foo) as Whatever
|
|
2585
|
-
return foo.x
|
|
2586
|
-
end function
|
|
2587
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
2588
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2589
|
-
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2590
|
-
]);
|
|
2591
|
-
});
|
|
2592
|
-
it('built-in interface param types allowed in brighterscript mode', () => {
|
|
2593
|
-
let { diagnostics } = parse(`
|
|
2594
|
-
sub test(foo as roAssociativeArray)
|
|
2595
|
-
print foo.x
|
|
2596
|
-
end sub
|
|
2597
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2598
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2599
|
-
});
|
|
2600
|
-
it('built-in interface types allowed in brighterscript mode', () => {
|
|
2601
|
-
let { diagnostics } = parse(`
|
|
2602
|
-
function test(foo) as roAssociativeArray
|
|
2603
|
-
return foo.x
|
|
2604
|
-
end function
|
|
2605
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2606
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2607
|
-
});
|
|
2608
|
-
it('custom param types allowed in brighterscript mode', () => {
|
|
2609
|
-
let { diagnostics } = parse(`
|
|
2610
|
-
sub test(foo as Whatever)
|
|
2611
|
-
print foo.x
|
|
2612
|
-
end sub
|
|
2613
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2614
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2615
|
-
});
|
|
2616
|
-
it('custom return types allowed in brighterscript mode', () => {
|
|
2617
|
-
let { diagnostics } = parse(`
|
|
2618
|
-
function test(foo) as Whatever
|
|
2619
|
-
return foo.x
|
|
2620
|
-
end function
|
|
2621
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2622
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2623
|
-
});
|
|
2624
|
-
});
|
|
2625
|
-
describe('inline interfaces', () => {
|
|
2626
|
-
it('inline interface param types disallowed in brightscript mode', () => {
|
|
2627
|
-
let { diagnostics } = parse(`
|
|
2628
|
-
sub test(foo as {x as string})
|
|
2629
|
-
print foo.x
|
|
2630
|
-
end sub
|
|
2631
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
2632
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2633
|
-
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2634
|
-
]);
|
|
2635
|
-
});
|
|
2636
|
-
it('inline interface return types disallowed in brightscript mode', () => {
|
|
2637
|
-
let { diagnostics } = parse(`
|
|
2638
|
-
function test() as {x as string}
|
|
2639
|
-
print {x: "hello"}
|
|
2640
|
-
end function
|
|
2641
|
-
`, Parser_1.ParseMode.BrightScript);
|
|
2642
|
-
(0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
|
|
2643
|
-
DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
|
|
2644
|
-
]);
|
|
2645
|
-
});
|
|
2646
|
-
it('inline interface as param type', () => {
|
|
2647
|
-
var _a;
|
|
2648
|
-
let { ast, diagnostics } = parse(`
|
|
2649
|
-
sub test(foo as {x as string})
|
|
2650
|
-
print foo.x
|
|
2651
|
-
end sub
|
|
2652
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2653
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2654
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
2655
|
-
const func = ast.statements[0].func;
|
|
2656
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)((_a = func.parameters[0].typeExpression) === null || _a === void 0 ? void 0 : _a.expression)).to.be.true;
|
|
2657
|
-
});
|
|
2658
|
-
it('inline interface as return type', () => {
|
|
2659
|
-
let { ast, diagnostics } = parse(`
|
|
2660
|
-
function test() as {x as string}
|
|
2661
|
-
print {x: "hello"}
|
|
2662
|
-
end function
|
|
2663
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2664
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2665
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
2666
|
-
const func = ast.statements[0].func;
|
|
2667
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)(func.returnTypeExpression.expression)).to.be.true;
|
|
2668
|
-
});
|
|
2669
|
-
it('parses a big inline interface as param type', () => {
|
|
2670
|
-
var _a;
|
|
2671
|
-
let { ast, diagnostics } = parse(`
|
|
2672
|
-
sub test(foo as {
|
|
2673
|
-
x as string,
|
|
2674
|
-
y as {a as integer}
|
|
2675
|
-
z})
|
|
2676
|
-
print foo.x + y.a.toStr()
|
|
2677
|
-
end sub
|
|
2678
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2679
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2680
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
2681
|
-
const func = ast.statements[0].func;
|
|
2682
|
-
const inlineIface = (_a = func.parameters[0].typeExpression) === null || _a === void 0 ? void 0 : _a.expression;
|
|
2683
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)(inlineIface)).to.be.true;
|
|
2684
|
-
(0, chai_config_spec_1.expect)(inlineIface.tokens.open).not.to.be.undefined;
|
|
2685
|
-
(0, chai_config_spec_1.expect)(inlineIface.tokens.close).not.to.be.undefined;
|
|
2686
|
-
(0, chai_config_spec_1.expect)(inlineIface.members).to.have.length(3);
|
|
2687
|
-
const iFaceType = inlineIface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
|
|
2688
|
-
(0, testHelpers_spec_1.expectTypeToBe)(iFaceType, InlineInterfaceType_1.InlineInterfaceType);
|
|
2689
|
-
(0, testHelpers_spec_1.expectTypeToBe)(iFaceType.getMemberType('x', { flags: 1 /* SymbolTypeFlag.runtime */ }), StringType_1.StringType);
|
|
2690
|
-
(0, testHelpers_spec_1.expectTypeToBe)(iFaceType.getMemberType('y', { flags: 1 /* SymbolTypeFlag.runtime */ }), InlineInterfaceType_1.InlineInterfaceType);
|
|
2691
|
-
(0, testHelpers_spec_1.expectTypeToBe)(iFaceType.getMemberType('z', { flags: 1 /* SymbolTypeFlag.runtime */ }), types_1.DynamicType);
|
|
2692
|
-
});
|
|
2693
|
-
it('allows optional members', () => {
|
|
2694
|
-
var _a;
|
|
2695
|
-
let { ast, diagnostics } = parse(`
|
|
2696
|
-
sub test(p as {x as string, optional y})
|
|
2697
|
-
end sub
|
|
2698
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2699
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2700
|
-
(0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
|
|
2701
|
-
const func = ast.statements[0].func;
|
|
2702
|
-
const inlineIface = (_a = func.parameters[0].typeExpression) === null || _a === void 0 ? void 0 : _a.expression;
|
|
2703
|
-
(0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)(inlineIface)).to.be.true;
|
|
2704
|
-
(0, chai_config_spec_1.expect)(inlineIface.members).to.have.length(2);
|
|
2705
|
-
(0, chai_config_spec_1.expect)(inlineIface.members[1].isOptional).to.be.true;
|
|
2706
|
-
});
|
|
2707
|
-
it('is allowed as typecast', () => {
|
|
2708
|
-
let { diagnostics } = parse(`
|
|
2709
|
-
sub test(p)
|
|
2710
|
-
print (p as {name as string}).name
|
|
2711
|
-
end sub
|
|
2712
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2713
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2714
|
-
});
|
|
2715
|
-
it('is allowed as class and interface field', () => {
|
|
2716
|
-
let { diagnostics } = parse(`
|
|
2717
|
-
class Klass
|
|
2718
|
-
x as {name as string}
|
|
2719
|
-
end class
|
|
2720
|
-
|
|
2721
|
-
interface Iface
|
|
2722
|
-
y as {age as integer}
|
|
2723
|
-
end interface
|
|
2724
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2725
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2726
|
-
});
|
|
2727
|
-
it('can have custom type as member type', () => {
|
|
2728
|
-
let { diagnostics } = parse(`
|
|
2729
|
-
interface IFace
|
|
2730
|
-
name as string
|
|
2731
|
-
end interface
|
|
2732
|
-
|
|
2733
|
-
function test(z as {foo as IFace})
|
|
2734
|
-
return z.foo.name
|
|
2735
|
-
end function
|
|
2736
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2737
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2738
|
-
});
|
|
2739
|
-
it('can have per-member doc comment', () => {
|
|
2740
|
-
let { diagnostics } = parse(`
|
|
2741
|
-
interface IFace
|
|
2742
|
-
inline as {
|
|
2743
|
-
' comment 1
|
|
2744
|
-
name as string
|
|
2745
|
-
' comment 2
|
|
2746
|
-
age as integer
|
|
2747
|
-
}
|
|
2748
|
-
end interface
|
|
2749
|
-
|
|
2750
|
-
function test(z as {foo as IFace})
|
|
2751
|
-
return z.foo.inline.name
|
|
2752
|
-
end function
|
|
2753
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2754
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2755
|
-
});
|
|
2756
|
-
it('can have string literals as members', () => {
|
|
2757
|
-
let { diagnostics } = parse(`
|
|
2758
|
-
function test(z as {"this is a stringliteral" as string})
|
|
2759
|
-
return z["this is a stringliteral"]
|
|
2760
|
-
end function
|
|
2761
|
-
`, Parser_1.ParseMode.BrighterScript);
|
|
2762
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
|
|
2763
|
-
});
|
|
2764
|
-
});
|
|
2765
|
-
});
|
|
2766
|
-
function parse(text, mode, bsConsts = {}) {
|
|
2767
|
-
let { tokens } = Lexer_1.Lexer.scan(text);
|
|
2768
|
-
const bsConstMap = new Map();
|
|
2769
|
-
for (const constName in bsConsts) {
|
|
2770
|
-
bsConstMap.set(constName.toLowerCase(), bsConsts[constName]);
|
|
2771
|
-
}
|
|
2772
|
-
return Parser_1.Parser.parse(tokens, {
|
|
2773
|
-
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
|
|
2774
|
-
mode: mode,
|
|
2775
|
-
bsConsts: bsConstMap
|
|
2776
|
-
});
|
|
2777
|
-
}
|
|
2778
|
-
exports.parse = parse;
|
|
2779
|
-
function rangeToArray(range) {
|
|
2780
|
-
return [
|
|
2781
|
-
range.start.line,
|
|
2782
|
-
range.start.character,
|
|
2783
|
-
range.end.line,
|
|
2784
|
-
range.end.character
|
|
2785
|
-
];
|
|
2786
|
-
}
|
|
2787
|
-
exports.rangeToArray = rangeToArray;
|
|
2788
|
-
function expectCommentWithText(stat, text) {
|
|
2789
|
-
const trivia = stat.leadingTrivia;
|
|
2790
|
-
if (trivia) {
|
|
2791
|
-
(0, chai_config_spec_1.expect)(trivia.filter(tok => tok.kind === TokenKind_1.TokenKind.Comment).map(t => t.text).join('\n')).to.equal(text);
|
|
2792
|
-
}
|
|
2793
|
-
else {
|
|
2794
|
-
failStatementType(stat, 'Comment');
|
|
2795
|
-
}
|
|
2796
|
-
}
|
|
2797
|
-
function failStatementType(stat, type) {
|
|
2798
|
-
var _a;
|
|
2799
|
-
chai_config_spec_1.assert.fail(`Statement ${stat.constructor.name} line ${(_a = stat.location) === null || _a === void 0 ? void 0 : _a.range.start.line} is not a ${type}`);
|
|
2800
|
-
}
|
|
2801
|
-
exports.failStatementType = failStatementType;
|
|
2802
|
-
//# sourceMappingURL=Parser.spec.js.map
|