brighterscript 1.0.0-alpha.2 → 1.0.0-alpha.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +643 -253
- package/README.md +33 -9
- package/bsconfig.schema.json +22 -2
- package/dist/BsConfig.d.ts +9 -0
- package/dist/Cache.d.ts +5 -6
- package/dist/Cache.js +12 -11
- package/dist/Cache.js.map +1 -1
- package/dist/CodeActionUtil.d.ts +11 -2
- package/dist/CodeActionUtil.js +17 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +4 -4
- package/dist/CommentFlagProcessor.js +5 -3
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +2 -2
- package/dist/DependencyGraph.js +20 -7
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.d.ts +3 -3
- package/dist/DiagnosticCollection.js +11 -11
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.js +5 -4
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +59 -4
- package/dist/DiagnosticMessages.js +65 -7
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.d.ts +51 -39
- package/dist/LanguageServer.js +316 -232
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +2 -0
- package/dist/Logger.js +10 -8
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +7 -3
- package/dist/PluginInterface.js +9 -0
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +43 -25
- package/dist/Program.js +212 -95
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +4 -0
- package/dist/ProgramBuilder.js +36 -20
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +126 -29
- package/dist/Scope.js +433 -156
- package/dist/Scope.js.map +1 -1
- package/dist/SemanticTokenUtils.d.ts +14 -0
- package/dist/SemanticTokenUtils.js +81 -0
- package/dist/SemanticTokenUtils.js.map +1 -0
- package/dist/SymbolTable.d.ts +10 -4
- package/dist/SymbolTable.js +55 -13
- package/dist/SymbolTable.js.map +1 -1
- package/dist/XmlScope.d.ts +7 -2
- package/dist/XmlScope.js +65 -27
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/AstEditor.d.ts +65 -0
- package/dist/astUtils/AstEditor.js +239 -0
- package/dist/astUtils/AstEditor.js.map +1 -0
- package/dist/{types/FunctionType.spec.d.ts → astUtils/AstEditor.spec.d.ts} +0 -0
- package/dist/astUtils/AstEditor.spec.js +254 -0
- package/dist/astUtils/AstEditor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +28 -6
- package/dist/astUtils/creators.js +137 -19
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +14 -4
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +32 -10
- package/dist/astUtils/reflection.js +82 -7
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +130 -119
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +13 -13
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +76 -51
- package/dist/astUtils/visitors.js +31 -11
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +126 -32
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +4 -3
- package/dist/astUtils/xml.js +8 -3
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +7 -1
- package/dist/bscPlugin/BscPlugin.js +28 -0
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +4 -4
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +26 -26
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +9 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +108 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +130 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +8 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +52 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +32 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +9 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +66 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +29 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +183 -0
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
- package/dist/cli.js +10 -3
- package/dist/cli.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +1 -0
- package/dist/diagnosticUtils.js +15 -8
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +12 -14
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/BrsFile.Class.spec.js +717 -147
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +70 -30
- package/dist/files/BrsFile.js +719 -353
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1238 -449
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.d.ts +6 -5
- package/dist/files/XmlFile.js +38 -30
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +302 -237
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +44 -42
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.d.ts +1 -0
- package/dist/files/tests/optionalChaning.spec.js +88 -0
- package/dist/files/tests/optionalChaning.spec.js.map +1 -0
- package/dist/globalCallables.d.ts +3 -1
- package/dist/globalCallables.js +424 -152
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.js +28 -5
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +133 -16
- package/dist/lexer/Lexer.d.ts +19 -1
- package/dist/lexer/Lexer.js +127 -21
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +657 -536
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +2 -2
- package/dist/lexer/TokenKind.d.ts +13 -1
- package/dist/lexer/TokenKind.js +60 -3
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/BrsTranspileState.d.ts +9 -0
- package/dist/parser/BrsTranspileState.js +14 -0
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +150 -34
- package/dist/parser/Expression.js +335 -165
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +189 -89
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +153 -30
- package/dist/parser/Parser.js +1100 -503
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +687 -266
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +41 -4
- package/dist/parser/SGParser.js +186 -175
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +35 -22
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +206 -38
- package/dist/parser/SGTypes.js +470 -161
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/SGTypes.spec.d.ts +1 -0
- package/dist/parser/SGTypes.spec.js +351 -0
- package/dist/parser/SGTypes.spec.js.map +1 -0
- package/dist/parser/Statement.d.ts +202 -48
- package/dist/parser/Statement.js +648 -193
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +11 -11
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +1 -1
- package/dist/parser/TranspileState.js +15 -7
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.d.ts +10 -9
- package/dist/parser/tests/Parser.spec.js +15 -11
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +60 -60
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +40 -39
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +213 -194
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +37 -37
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +30 -30
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +119 -119
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +162 -138
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +24 -24
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +41 -40
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +17 -17
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +256 -256
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +87 -87
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +37 -37
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +75 -63
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +41 -41
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +41 -41
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +171 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/Relational.spec.js +43 -43
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +9 -9
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +28 -28
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +102 -102
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +36 -36
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/Declaration.spec.js +44 -44
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +21 -21
- package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.d.ts +1 -0
- package/dist/parser/tests/statement/Enum.spec.js +840 -0
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
- package/dist/parser/tests/statement/For.spec.d.ts +1 -0
- package/dist/parser/tests/statement/For.spec.js +46 -0
- package/dist/parser/tests/statement/For.spec.js.map +1 -0
- package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ForEach.spec.js +37 -0
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
- package/dist/parser/tests/statement/Function.spec.js +198 -197
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +15 -14
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +50 -50
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +254 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/LibraryStatement.spec.js +17 -17
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +108 -106
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +40 -40
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +46 -46
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +83 -83
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +12 -11
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +5 -5
- package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +15 -13
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Chunk.d.ts +1 -1
- package/dist/preprocessor/Chunk.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +5 -5
- package/dist/preprocessor/Manifest.js +14 -35
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/preprocessor/Manifest.spec.d.ts +1 -0
- package/dist/preprocessor/Manifest.spec.js +78 -103
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/preprocessor/Preprocessor.d.ts +1 -1
- package/dist/preprocessor/Preprocessor.js +8 -8
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/preprocessor/Preprocessor.spec.js +49 -49
- package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +72 -72
- package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
- package/dist/roku-types/data.json +21891 -0
- package/dist/roku-types/index.d.ts +6776 -0
- package/dist/roku-types/index.js +11 -0
- package/dist/roku-types/index.js.map +1 -0
- package/dist/types/ArrayType.d.ts +8 -5
- package/dist/types/ArrayType.js +52 -12
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +72 -11
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/BooleanType.d.ts +4 -2
- package/dist/types/BooleanType.js +9 -4
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +5 -3
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +20 -5
- package/dist/types/BscType.js +24 -0
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/CustomType.d.ts +8 -6
- package/dist/types/CustomType.js +20 -11
- package/dist/types/CustomType.js.map +1 -1
- package/dist/types/DoubleType.d.ts +2 -0
- package/dist/types/DoubleType.js +14 -9
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +5 -3
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +2 -0
- package/dist/types/DynamicType.js +6 -2
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/DynamicType.spec.js +2 -2
- package/dist/types/DynamicType.spec.js.map +1 -1
- package/dist/types/EnumType.d.ts +22 -0
- package/dist/types/EnumType.js +55 -0
- package/dist/types/EnumType.js.map +1 -0
- package/dist/types/FloatType.d.ts +2 -0
- package/dist/types/FloatType.js +14 -9
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -2
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +7 -31
- package/dist/types/FunctionType.js +11 -57
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/IntegerType.d.ts +2 -0
- package/dist/types/IntegerType.js +14 -9
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +5 -3
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +13 -4
- package/dist/types/InterfaceType.js +48 -8
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.d.ts +1 -0
- package/dist/types/InterfaceType.spec.js +194 -0
- package/dist/types/InterfaceType.spec.js.map +1 -0
- package/dist/types/InvalidType.d.ts +4 -2
- package/dist/types/InvalidType.js +10 -5
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +4 -2
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LazyType.d.ts +8 -7
- package/dist/types/LazyType.js +22 -10
- package/dist/types/LazyType.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +2 -0
- package/dist/types/LongIntegerType.js +14 -9
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +4 -2
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/ObjectType.d.ts +8 -4
- package/dist/types/ObjectType.js +9 -4
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ObjectType.spec.js +2 -2
- package/dist/types/ObjectType.spec.js.map +1 -1
- package/dist/types/StringType.d.ts +4 -2
- package/dist/types/StringType.js +9 -4
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +4 -2
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +28 -0
- package/dist/types/TypedFunctionType.js +88 -0
- package/dist/types/TypedFunctionType.js.map +1 -0
- package/dist/types/TypedFunctionType.spec.d.ts +1 -0
- package/dist/types/TypedFunctionType.spec.js +37 -0
- package/dist/types/TypedFunctionType.spec.js.map +1 -0
- package/dist/types/UninitializedType.js +3 -3
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/VoidType.d.ts +4 -2
- package/dist/types/VoidType.js +8 -4
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/VoidType.spec.js +2 -2
- package/dist/types/VoidType.spec.js.map +1 -1
- package/dist/types/helpers.d.ts +42 -0
- package/dist/types/helpers.js +118 -0
- package/dist/types/helpers.js.map +1 -0
- package/dist/util.d.ts +91 -21
- package/dist/util.js +364 -114
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +19 -2
- package/dist/validators/ClassValidator.js +164 -103
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +30 -19
- package/dist/astUtils/index.d.ts +0 -7
- package/dist/astUtils/index.js +0 -26
- package/dist/astUtils/index.js.map +0 -1
- package/dist/lexer/index.d.ts +0 -3
- package/dist/lexer/index.js +0 -17
- package/dist/lexer/index.js.map +0 -1
- package/dist/parser/index.d.ts +0 -3
- package/dist/parser/index.js +0 -16
- package/dist/parser/index.js.map +0 -1
- package/dist/preprocessor/index.d.ts +0 -3
- package/dist/preprocessor/index.js +0 -16
- package/dist/preprocessor/index.js.map +0 -1
- package/dist/types/FunctionType.spec.js +0 -23
- package/dist/types/FunctionType.spec.js.map +0 -1
|
@@ -2,33 +2,41 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const chai_1 = require("chai");
|
|
4
4
|
const sinonImport = require("sinon");
|
|
5
|
-
const path = require("path");
|
|
6
5
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
7
6
|
const Program_1 = require("../Program");
|
|
8
7
|
const BooleanType_1 = require("../types/BooleanType");
|
|
9
8
|
const DynamicType_1 = require("../types/DynamicType");
|
|
10
|
-
const
|
|
9
|
+
const TypedFunctionType_1 = require("../types/TypedFunctionType");
|
|
11
10
|
const IntegerType_1 = require("../types/IntegerType");
|
|
12
11
|
const StringType_1 = require("../types/StringType");
|
|
13
12
|
const BrsFile_1 = require("./BrsFile");
|
|
14
13
|
const source_map_1 = require("source-map");
|
|
15
|
-
const
|
|
14
|
+
const Lexer_1 = require("../lexer/Lexer");
|
|
15
|
+
const TokenKind_1 = require("../lexer/TokenKind");
|
|
16
16
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
17
17
|
const util_1 = require("../util");
|
|
18
18
|
const PluginInterface_1 = require("../PluginInterface");
|
|
19
19
|
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
20
20
|
const Parser_1 = require("../parser/Parser");
|
|
21
21
|
const Logger_1 = require("../Logger");
|
|
22
|
+
const Statement_1 = require("../parser/Statement");
|
|
23
|
+
const creators_1 = require("../astUtils/creators");
|
|
24
|
+
const fsExtra = require("fs-extra");
|
|
25
|
+
const ArrayType_1 = require("../types/ArrayType");
|
|
26
|
+
const FloatType_1 = require("../types/FloatType");
|
|
27
|
+
const ObjectType_1 = require("../types/ObjectType");
|
|
22
28
|
const VoidType_1 = require("../types/VoidType");
|
|
23
29
|
let sinon = sinonImport.createSandbox();
|
|
24
30
|
describe('BrsFile', () => {
|
|
25
|
-
let
|
|
31
|
+
let tempDir = (0, util_1.standardizePath) `${process.cwd()}/.tmp`;
|
|
32
|
+
let rootDir = (0, util_1.standardizePath) `${tempDir}/rootDir`;
|
|
26
33
|
let program;
|
|
27
|
-
let srcPath = util_1.standardizePath `${rootDir}/source/main.brs`;
|
|
34
|
+
let srcPath = (0, util_1.standardizePath) `${rootDir}/source/main.brs`;
|
|
28
35
|
let destPath = 'source/main.brs';
|
|
29
36
|
let file;
|
|
30
|
-
let testTranspile = testHelpers_spec_1.getTestTranspile(() => [program, rootDir]);
|
|
37
|
+
let testTranspile = (0, testHelpers_spec_1.getTestTranspile)(() => [program, rootDir]);
|
|
31
38
|
beforeEach(() => {
|
|
39
|
+
fsExtra.emptyDirSync(tempDir);
|
|
32
40
|
program = new Program_1.Program({ rootDir: rootDir, sourceMap: true });
|
|
33
41
|
file = new BrsFile_1.BrsFile(srcPath, destPath, program);
|
|
34
42
|
});
|
|
@@ -36,21 +44,56 @@ describe('BrsFile', () => {
|
|
|
36
44
|
sinon.restore();
|
|
37
45
|
program.dispose();
|
|
38
46
|
});
|
|
47
|
+
describe('allowBrighterScriptInBrightScript', () => {
|
|
48
|
+
it('is false by default', () => {
|
|
49
|
+
program.setFile('source/main.brs', `
|
|
50
|
+
namespace CustomApp
|
|
51
|
+
end namespace
|
|
52
|
+
`);
|
|
53
|
+
program.validate();
|
|
54
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('namespace'))]);
|
|
55
|
+
});
|
|
56
|
+
it('allows bs features in brs', () => {
|
|
57
|
+
program.options.allowBrighterScriptInBrightScript = true;
|
|
58
|
+
program.setFile('source/main.brs', `
|
|
59
|
+
namespace CustomApp
|
|
60
|
+
end namespace
|
|
61
|
+
`);
|
|
62
|
+
program.validate();
|
|
63
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
39
66
|
it('supports the third parameter in CreateObject', () => {
|
|
40
|
-
|
|
41
|
-
program.addOrReplaceFile('source/main.brs', `
|
|
67
|
+
program.setFile('source/main.brs', `
|
|
42
68
|
sub main()
|
|
43
69
|
regexp = CreateObject("roRegex", "[a-z]+", "i")
|
|
44
70
|
end sub
|
|
45
71
|
`);
|
|
46
72
|
program.validate();
|
|
47
|
-
|
|
73
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
74
|
+
});
|
|
75
|
+
it('supports the 6 params in CreateObject for roRegion', () => {
|
|
76
|
+
program.setFile('source/main.brs', `
|
|
77
|
+
sub createRegion(bitmap as object)
|
|
78
|
+
region = CreateObject("roRegion", bitmap, 20, 40, 100, 200)
|
|
79
|
+
end sub
|
|
80
|
+
`);
|
|
81
|
+
program.validate();
|
|
82
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
48
83
|
});
|
|
49
84
|
it('sets needsTranspiled to true for .bs files', () => {
|
|
50
85
|
//BrightScript
|
|
51
|
-
chai_1.expect(new BrsFile_1.BrsFile(`${rootDir}/source/main.brs`, 'source/main.brs', program).needsTranspiled).to.be.false;
|
|
86
|
+
(0, chai_1.expect)(new BrsFile_1.BrsFile(`${rootDir}/source/main.brs`, 'source/main.brs', program).needsTranspiled).to.be.false;
|
|
52
87
|
//BrighterScript
|
|
53
|
-
chai_1.expect(new BrsFile_1.BrsFile(`${rootDir}/source/main.bs`, 'source/main.bs', program).needsTranspiled).to.be.true;
|
|
88
|
+
(0, chai_1.expect)(new BrsFile_1.BrsFile(`${rootDir}/source/main.bs`, 'source/main.bs', program).needsTranspiled).to.be.true;
|
|
89
|
+
});
|
|
90
|
+
it('computes new import statements after clearing parser references', () => {
|
|
91
|
+
const file = program.setFile('source/main.bs', ``);
|
|
92
|
+
(0, chai_1.expect)(file.ownScriptImports).to.be.empty;
|
|
93
|
+
file.parser.ast.statements.push(new Statement_1.ImportStatement((0, creators_1.createToken)(TokenKind_1.TokenKind.Import), (0, creators_1.createToken)(TokenKind_1.TokenKind.StringLiteral, 'pkg:/source/lib.brs')));
|
|
94
|
+
(0, chai_1.expect)(file.ownScriptImports).to.be.empty;
|
|
95
|
+
file.parser.invalidateReferences();
|
|
96
|
+
(0, chai_1.expect)(file.ownScriptImports.map(x => x.text)).to.eql(['pkg:/source/lib.brs']);
|
|
54
97
|
});
|
|
55
98
|
it('allows adding diagnostics', () => {
|
|
56
99
|
const expected = [{
|
|
@@ -59,8 +102,7 @@ describe('BrsFile', () => {
|
|
|
59
102
|
range: undefined
|
|
60
103
|
}];
|
|
61
104
|
file.addDiagnostics(expected);
|
|
62
|
-
|
|
63
|
-
chai_1.expect(actual).deep.equal(expected);
|
|
105
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, expected);
|
|
64
106
|
});
|
|
65
107
|
describe('getPartialVariableName', () => {
|
|
66
108
|
let entry = {
|
|
@@ -68,72 +110,72 @@ describe('BrsFile', () => {
|
|
|
68
110
|
dest: `source/lib.brs`
|
|
69
111
|
};
|
|
70
112
|
it('creates proper tokens', () => {
|
|
71
|
-
file = program.
|
|
72
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[7])).to.equal('ModuleA.ModuleB.ModuleC.');
|
|
73
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[6])).to.equal('ModuleA.ModuleB.ModuleC');
|
|
74
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[5])).to.equal('ModuleA.ModuleB.');
|
|
75
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[4])).to.equal('ModuleA.ModuleB');
|
|
76
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[3])).to.equal('ModuleA.');
|
|
77
|
-
chai_1.expect(file['getPartialVariableName'](file.parser.tokens[2])).to.equal('ModuleA');
|
|
113
|
+
file = program.setFile(entry, `call(ModuleA.ModuleB.ModuleC.`);
|
|
114
|
+
(0, chai_1.expect)(file['getPartialVariableName'](file.parser.tokens[7])).to.equal('ModuleA.ModuleB.ModuleC.');
|
|
115
|
+
(0, chai_1.expect)(file['getPartialVariableName'](file.parser.tokens[6])).to.equal('ModuleA.ModuleB.ModuleC');
|
|
116
|
+
(0, chai_1.expect)(file['getPartialVariableName'](file.parser.tokens[5])).to.equal('ModuleA.ModuleB.');
|
|
117
|
+
(0, chai_1.expect)(file['getPartialVariableName'](file.parser.tokens[4])).to.equal('ModuleA.ModuleB');
|
|
118
|
+
(0, chai_1.expect)(file['getPartialVariableName'](file.parser.tokens[3])).to.equal('ModuleA.');
|
|
119
|
+
(0, chai_1.expect)(file['getPartialVariableName'](file.parser.tokens[2])).to.equal('ModuleA');
|
|
78
120
|
});
|
|
79
121
|
});
|
|
80
122
|
describe('getScopesForFile', () => {
|
|
81
123
|
it('finds the scope for the file', () => {
|
|
82
124
|
var _a;
|
|
83
|
-
let file = program.
|
|
84
|
-
chai_1.expect((_a = program.getScopesForFile(file)[0]) === null || _a === void 0 ? void 0 : _a.name).to.equal('source');
|
|
125
|
+
let file = program.setFile('source/main.brs', ``);
|
|
126
|
+
(0, chai_1.expect)((_a = program.getScopesForFile(file)[0]) === null || _a === void 0 ? void 0 : _a.name).to.equal('source');
|
|
85
127
|
});
|
|
86
128
|
});
|
|
87
129
|
describe('getCompletions', () => {
|
|
88
130
|
it('does not crash for callfunc on a function call', () => {
|
|
89
|
-
const file = program.
|
|
131
|
+
const file = program.setFile('source/main.brs', `
|
|
90
132
|
sub main()
|
|
91
133
|
getManager()@.
|
|
92
134
|
end sub
|
|
93
135
|
`);
|
|
94
|
-
chai_1.expect(() => {
|
|
136
|
+
(0, chai_1.expect)(() => {
|
|
95
137
|
program.getCompletions(file.srcPath, util_1.default.createPosition(2, 34));
|
|
96
138
|
}).not.to.throw;
|
|
97
139
|
});
|
|
98
140
|
it('suggests pkg paths in strings that match that criteria', () => {
|
|
99
|
-
program.
|
|
141
|
+
program.setFile('source/main.brs', `
|
|
100
142
|
sub main()
|
|
101
143
|
print "pkg:"
|
|
102
144
|
end sub
|
|
103
145
|
`);
|
|
104
146
|
const result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
|
|
105
147
|
const names = result.map(x => x.label);
|
|
106
|
-
chai_1.expect(names.sort()).to.eql([
|
|
148
|
+
(0, chai_1.expect)(names.sort()).to.eql([
|
|
107
149
|
'pkg:/source/main.brs'
|
|
108
150
|
]);
|
|
109
151
|
});
|
|
110
152
|
it('suggests libpkg paths in strings that match that criteria', () => {
|
|
111
|
-
program.
|
|
153
|
+
program.setFile('source/main.brs', `
|
|
112
154
|
sub main()
|
|
113
155
|
print "libpkg:"
|
|
114
156
|
end sub
|
|
115
157
|
`);
|
|
116
158
|
const result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
|
|
117
159
|
const names = result.map(x => x.label);
|
|
118
|
-
chai_1.expect(names.sort()).to.eql([
|
|
160
|
+
(0, chai_1.expect)(names.sort()).to.eql([
|
|
119
161
|
'libpkg:/source/main.brs'
|
|
120
162
|
]);
|
|
121
163
|
});
|
|
122
164
|
it('suggests pkg paths in template strings', () => {
|
|
123
|
-
program.
|
|
165
|
+
program.setFile('source/main.brs', `
|
|
124
166
|
sub main()
|
|
125
167
|
print \`pkg:\`
|
|
126
168
|
end sub
|
|
127
169
|
`);
|
|
128
170
|
const result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
|
|
129
171
|
const names = result.map(x => x.label);
|
|
130
|
-
chai_1.expect(names.sort()).to.eql([
|
|
172
|
+
(0, chai_1.expect)(names.sort()).to.eql([
|
|
131
173
|
'pkg:/source/main.brs'
|
|
132
174
|
]);
|
|
133
175
|
});
|
|
134
176
|
it('waits for the file to be processed before collecting completions', () => {
|
|
135
177
|
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
136
|
-
program.
|
|
178
|
+
program.setFile('source/main.brs', `
|
|
137
179
|
sub Main()
|
|
138
180
|
print "hello"
|
|
139
181
|
Say
|
|
@@ -144,62 +186,132 @@ describe('BrsFile', () => {
|
|
|
144
186
|
`);
|
|
145
187
|
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 23));
|
|
146
188
|
let names = result.map(x => x.label);
|
|
147
|
-
chai_1.expect(names).to.includes('Main');
|
|
148
|
-
chai_1.expect(names).to.includes('SayHello');
|
|
189
|
+
(0, chai_1.expect)(names).to.includes('Main');
|
|
190
|
+
(0, chai_1.expect)(names).to.includes('SayHello');
|
|
191
|
+
});
|
|
192
|
+
it('includes every type of item at base level', () => {
|
|
193
|
+
program.setFile('source/main.bs', `
|
|
194
|
+
sub main()
|
|
195
|
+
print
|
|
196
|
+
end sub
|
|
197
|
+
sub speak()
|
|
198
|
+
end sub
|
|
199
|
+
namespace stuff
|
|
200
|
+
end namespace
|
|
201
|
+
class Person
|
|
202
|
+
end class
|
|
203
|
+
enum Direction
|
|
204
|
+
end enum
|
|
205
|
+
`);
|
|
206
|
+
(0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 26)), [{
|
|
207
|
+
label: 'main',
|
|
208
|
+
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
209
|
+
}, {
|
|
210
|
+
label: 'speak',
|
|
211
|
+
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
212
|
+
}, {
|
|
213
|
+
label: 'stuff',
|
|
214
|
+
kind: vscode_languageserver_1.CompletionItemKind.Module
|
|
215
|
+
}, {
|
|
216
|
+
label: 'Person',
|
|
217
|
+
kind: vscode_languageserver_1.CompletionItemKind.Class
|
|
218
|
+
}, {
|
|
219
|
+
label: 'Direction',
|
|
220
|
+
kind: vscode_languageserver_1.CompletionItemKind.Enum
|
|
221
|
+
}]);
|
|
222
|
+
});
|
|
223
|
+
describe('namespaces', () => {
|
|
224
|
+
it('gets full namespace completions at any point through the leading identifier', () => {
|
|
225
|
+
program.setFile('source/main.bs', `
|
|
226
|
+
sub main()
|
|
227
|
+
foo.bar
|
|
228
|
+
end sub
|
|
229
|
+
|
|
230
|
+
namespace foo.bar
|
|
231
|
+
end namespace
|
|
232
|
+
|
|
233
|
+
class Person
|
|
234
|
+
end class
|
|
235
|
+
`);
|
|
236
|
+
const result = program.getCompletions(`${rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 24)).map(x => x.label);
|
|
237
|
+
(0, chai_1.expect)(result).includes('main');
|
|
238
|
+
(0, chai_1.expect)(result).includes('foo');
|
|
239
|
+
(0, chai_1.expect)(result).includes('Person');
|
|
240
|
+
});
|
|
241
|
+
it('gets namespace completions', () => {
|
|
242
|
+
program.setFile('source/main.bs', `
|
|
243
|
+
namespace foo.bar
|
|
244
|
+
function sayHello()
|
|
245
|
+
end function
|
|
246
|
+
end namespace
|
|
247
|
+
|
|
248
|
+
sub Main()
|
|
249
|
+
print "hello"
|
|
250
|
+
foo.ba
|
|
251
|
+
foo.bar.
|
|
252
|
+
end sub
|
|
253
|
+
`);
|
|
254
|
+
let result = program.getCompletions(`${rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(8, 30));
|
|
255
|
+
let names = result.map(x => x.label);
|
|
256
|
+
(0, chai_1.expect)(names).to.includes('bar');
|
|
257
|
+
result = program.getCompletions(`${rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(9, 32));
|
|
258
|
+
names = result.map(x => x.label);
|
|
259
|
+
(0, chai_1.expect)(names).to.includes('sayHello');
|
|
260
|
+
});
|
|
149
261
|
});
|
|
150
262
|
it('always includes `m`', () => {
|
|
151
263
|
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
152
|
-
program.
|
|
264
|
+
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
153
265
|
sub Main()
|
|
154
266
|
|
|
155
267
|
end sub
|
|
156
268
|
`);
|
|
157
269
|
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
158
270
|
let names = result.map(x => x.label);
|
|
159
|
-
chai_1.expect(names).to.contain('m');
|
|
271
|
+
(0, chai_1.expect)(names).to.contain('m');
|
|
160
272
|
});
|
|
161
273
|
it('does not fail for missing previousToken', () => {
|
|
162
274
|
//add a single character to the file, and get completions after it
|
|
163
|
-
program.
|
|
164
|
-
chai_1.expect(() => {
|
|
275
|
+
program.setFile('source/main.brs', `i`);
|
|
276
|
+
(0, chai_1.expect)(() => {
|
|
165
277
|
program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(0, 1)).map(x => x.label);
|
|
166
278
|
}).not.to.throw;
|
|
167
279
|
});
|
|
168
280
|
it('includes all keywords`', () => {
|
|
169
281
|
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
170
|
-
program.
|
|
282
|
+
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
171
283
|
sub Main()
|
|
172
284
|
|
|
173
285
|
end sub
|
|
174
286
|
`);
|
|
175
|
-
let keywords = Object.keys(
|
|
287
|
+
let keywords = Object.keys(TokenKind_1.Keywords).filter(x => !x.includes(' '));
|
|
176
288
|
//inside the function
|
|
177
289
|
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
178
290
|
let names = result.map(x => x.label);
|
|
179
291
|
for (let keyword of keywords) {
|
|
180
|
-
chai_1.expect(names).to.include(keyword);
|
|
292
|
+
(0, chai_1.expect)(names).to.include(keyword);
|
|
181
293
|
}
|
|
182
294
|
//outside the function
|
|
183
295
|
result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(4, 8));
|
|
184
296
|
names = result.map(x => x.label);
|
|
185
297
|
for (let keyword of keywords) {
|
|
186
|
-
chai_1.expect(names).to.include(keyword);
|
|
298
|
+
(0, chai_1.expect)(names).to.include(keyword);
|
|
187
299
|
}
|
|
188
300
|
});
|
|
189
301
|
it('does not provide completions within a comment', () => {
|
|
190
302
|
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
191
|
-
program.
|
|
303
|
+
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
192
304
|
sub Main()
|
|
193
305
|
'some comment
|
|
194
306
|
end sub
|
|
195
307
|
`);
|
|
196
308
|
//inside the function
|
|
197
309
|
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 33));
|
|
198
|
-
chai_1.expect(result).to.be.lengthOf(0);
|
|
310
|
+
(0, chai_1.expect)(result).to.be.lengthOf(0);
|
|
199
311
|
});
|
|
200
312
|
it('does not provide duplicate entries for variables', () => {
|
|
201
313
|
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
202
|
-
program.
|
|
314
|
+
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
203
315
|
sub Main()
|
|
204
316
|
name = "bob"
|
|
205
317
|
age = 12
|
|
@@ -210,67 +322,91 @@ describe('BrsFile', () => {
|
|
|
210
322
|
let count = result.reduce((total, x) => {
|
|
211
323
|
return x.label === 'name' ? total + 1 : total;
|
|
212
324
|
}, 0);
|
|
213
|
-
chai_1.expect(count).to.equal(1);
|
|
325
|
+
(0, chai_1.expect)(count).to.equal(1);
|
|
214
326
|
});
|
|
215
327
|
it('does not include `as` and `string` text options when used in function params', () => {
|
|
216
328
|
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
217
|
-
program.
|
|
329
|
+
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
218
330
|
sub Main(name as string)
|
|
219
331
|
|
|
220
332
|
end sub
|
|
221
333
|
`);
|
|
222
334
|
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
223
|
-
chai_1.expect(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('as');
|
|
224
|
-
chai_1.expect(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('string');
|
|
335
|
+
(0, chai_1.expect)(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('as');
|
|
336
|
+
(0, chai_1.expect)(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('string');
|
|
225
337
|
});
|
|
226
338
|
it('does not provide intellisense results when inside a comment', () => {
|
|
227
339
|
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
228
|
-
program.
|
|
340
|
+
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
229
341
|
sub Main(name as string)
|
|
230
342
|
'this is a comment
|
|
231
343
|
end sub
|
|
232
344
|
`);
|
|
233
345
|
let results = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 30));
|
|
234
|
-
chai_1.expect(results).to.be.empty;
|
|
346
|
+
(0, chai_1.expect)(results).to.be.empty;
|
|
235
347
|
});
|
|
236
348
|
it('does provide intellisence for labels only after a goto keyword', () => {
|
|
237
349
|
var _a;
|
|
238
350
|
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
239
|
-
program.
|
|
351
|
+
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
240
352
|
sub Main(name as string)
|
|
241
353
|
something:
|
|
242
354
|
goto \nend sub
|
|
243
355
|
`);
|
|
244
356
|
let results = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 25));
|
|
245
|
-
chai_1.expect(results.length).to.equal(1);
|
|
246
|
-
chai_1.expect((_a = results[0]) === null || _a === void 0 ? void 0 : _a.label).to.equal('something');
|
|
357
|
+
(0, chai_1.expect)(results.length).to.equal(1);
|
|
358
|
+
(0, chai_1.expect)((_a = results[0]) === null || _a === void 0 ? void 0 : _a.label).to.equal('something');
|
|
359
|
+
});
|
|
360
|
+
it('includes properties of objects', () => {
|
|
361
|
+
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
362
|
+
program.setFile('source/main.brs', `
|
|
363
|
+
sub Main()
|
|
364
|
+
myObj = {name:"Bob", age: 34, height:6.0}
|
|
365
|
+
myObj.
|
|
366
|
+
end sub
|
|
367
|
+
`);
|
|
368
|
+
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 26));
|
|
369
|
+
let names = result.map(x => x.label);
|
|
370
|
+
(0, chai_1.expect)(names).to.contain('name');
|
|
371
|
+
(0, chai_1.expect)(names).to.contain('age');
|
|
372
|
+
(0, chai_1.expect)(names).to.contain('height');
|
|
373
|
+
});
|
|
374
|
+
it('includes properties of m', () => {
|
|
375
|
+
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
376
|
+
program.setFile('source/main.brs', `
|
|
377
|
+
sub Main()
|
|
378
|
+
m.someField= "hello"
|
|
379
|
+
m.
|
|
380
|
+
end sub
|
|
381
|
+
`);
|
|
382
|
+
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 22));
|
|
383
|
+
let names = result.map(x => x.label);
|
|
384
|
+
(0, chai_1.expect)(names).to.contain('someField');
|
|
247
385
|
});
|
|
248
386
|
});
|
|
249
387
|
describe('comment flags', () => {
|
|
250
388
|
describe('bs:disable-next-line', () => {
|
|
251
389
|
it('disables critical diagnostic issues', () => {
|
|
252
|
-
|
|
253
|
-
program.addOrReplaceFile('source/main.brs', `
|
|
390
|
+
program.setFile('source/main.brs', `
|
|
254
391
|
sub main()
|
|
255
392
|
Dim requestData
|
|
256
393
|
end sub
|
|
257
394
|
`);
|
|
258
395
|
//should have an error
|
|
259
396
|
program.validate();
|
|
260
|
-
|
|
261
|
-
program.
|
|
397
|
+
(0, testHelpers_spec_1.expectHasDiagnostics)(program);
|
|
398
|
+
program.setFile('source/main.brs', `
|
|
262
399
|
sub main()
|
|
263
400
|
'bs:disable-next-line
|
|
264
401
|
Dim requestData
|
|
265
402
|
end sub
|
|
266
403
|
`);
|
|
267
|
-
//should have an error
|
|
404
|
+
//should not have an error
|
|
268
405
|
program.validate();
|
|
269
|
-
|
|
406
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
270
407
|
});
|
|
271
408
|
it('works with leading whitespace', () => {
|
|
272
|
-
|
|
273
|
-
program.addOrReplaceFile('source/main.brs', `
|
|
409
|
+
program.setFile('source/main.brs', `
|
|
274
410
|
sub main()
|
|
275
411
|
' bs:disable-next-line
|
|
276
412
|
=asdf=sadf=
|
|
@@ -278,89 +414,96 @@ describe('BrsFile', () => {
|
|
|
278
414
|
`);
|
|
279
415
|
//should have an error
|
|
280
416
|
program.validate();
|
|
281
|
-
|
|
417
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
282
418
|
});
|
|
283
419
|
it('works for all', () => {
|
|
284
|
-
|
|
285
|
-
let file = program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
420
|
+
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
286
421
|
sub Main()
|
|
287
422
|
'bs:disable-next-line
|
|
288
423
|
name = "bob
|
|
289
424
|
end sub
|
|
290
425
|
`);
|
|
291
|
-
chai_1.expect(file.commentFlags[0]).to.exist;
|
|
292
|
-
chai_1.expect(file.commentFlags[0]).to.deep.include({
|
|
426
|
+
(0, chai_1.expect)(file.commentFlags[0]).to.exist;
|
|
427
|
+
(0, chai_1.expect)(file.commentFlags[0]).to.deep.include({
|
|
293
428
|
codes: null,
|
|
294
429
|
range: vscode_languageserver_1.Range.create(2, 24, 2, 45),
|
|
295
430
|
affectedRange: util_1.default.createRange(3, 0, 3, Number.MAX_SAFE_INTEGER)
|
|
296
431
|
});
|
|
297
432
|
program.validate();
|
|
298
433
|
//the "unterminated string" error should be filtered out
|
|
299
|
-
|
|
434
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
300
435
|
});
|
|
301
436
|
it('works for specific codes', () => {
|
|
302
|
-
|
|
303
|
-
let file = program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
437
|
+
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
304
438
|
sub Main()
|
|
305
439
|
'bs:disable-next-line: 1083, 1001
|
|
306
440
|
name = "bob
|
|
307
441
|
end sub
|
|
308
442
|
`);
|
|
309
|
-
chai_1.expect(file.commentFlags[0]).to.exist;
|
|
310
|
-
chai_1.expect(file.commentFlags[0]).to.deep.include({
|
|
443
|
+
(0, chai_1.expect)(file.commentFlags[0]).to.exist;
|
|
444
|
+
(0, chai_1.expect)(file.commentFlags[0]).to.deep.include({
|
|
311
445
|
codes: [1083, 1001],
|
|
312
446
|
range: vscode_languageserver_1.Range.create(2, 24, 2, 57),
|
|
313
447
|
affectedRange: util_1.default.createRange(3, 0, 3, Number.MAX_SAFE_INTEGER)
|
|
314
448
|
});
|
|
315
449
|
//the "unterminated string" error should be filtered out
|
|
316
|
-
|
|
450
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
317
451
|
});
|
|
318
|
-
it('
|
|
319
|
-
|
|
320
|
-
let file = program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
452
|
+
it('recognizes non-numeric codes', () => {
|
|
453
|
+
let file = program.setFile('source/main.brs', `
|
|
321
454
|
sub Main()
|
|
322
455
|
'bs:disable-next-line: LINT9999
|
|
323
456
|
name = "bob
|
|
324
457
|
end sub
|
|
325
|
-
|
|
326
|
-
chai_1.expect(file.commentFlags[0]).to.
|
|
327
|
-
|
|
458
|
+
`);
|
|
459
|
+
(0, chai_1.expect)(file.commentFlags[0]).to.exist;
|
|
460
|
+
(0, testHelpers_spec_1.expectHasDiagnostics)(program);
|
|
461
|
+
});
|
|
462
|
+
it('supports disabling non-numeric error codes', () => {
|
|
463
|
+
const program = new Program_1.Program({});
|
|
464
|
+
const file = program.setFile('source/main.brs', `
|
|
465
|
+
sub main()
|
|
466
|
+
something = true 'bs:disable-line: LINT1005
|
|
467
|
+
end sub
|
|
468
|
+
`);
|
|
469
|
+
file.addDiagnostics([{
|
|
470
|
+
code: 'LINT1005',
|
|
471
|
+
file: file,
|
|
472
|
+
message: 'Something is not right',
|
|
473
|
+
range: util_1.default.createRange(2, 16, 2, 26)
|
|
474
|
+
}]);
|
|
475
|
+
const scope = program.getScopesForFile(file)[0];
|
|
476
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(scope);
|
|
328
477
|
});
|
|
329
478
|
it('adds diagnostics for unknown numeric diagnostic codes', () => {
|
|
330
|
-
program.
|
|
479
|
+
program.setFile({ src: `${rootDir} / source / main.brs`, dest: 'source/main.brs' }, `
|
|
331
480
|
sub main()
|
|
332
481
|
print "hi" 'bs:disable-line: 123456 999999 aaaab
|
|
333
482
|
end sub
|
|
334
|
-
|
|
483
|
+
`);
|
|
335
484
|
program.validate();
|
|
336
|
-
|
|
337
|
-
chai_1.expect(program.getDiagnostics()[0]).to.deep.include({
|
|
338
|
-
range: vscode_languageserver_1.Range.create(2, 53, 2, 59)
|
|
339
|
-
});
|
|
340
|
-
chai_1.expect(program.getDiagnostics()[1]).to.deep.include({
|
|
341
|
-
range: vscode_languageserver_1.Range.create(2, 60, 2, 66)
|
|
342
|
-
});
|
|
485
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unknownDiagnosticCode(123456)), { range: vscode_languageserver_1.Range.create(2, 53, 2, 59) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unknownDiagnosticCode(999999)), { range: vscode_languageserver_1.Range.create(2, 60, 2, 66) })]);
|
|
343
486
|
});
|
|
344
487
|
});
|
|
345
488
|
describe('bs:disable-line', () => {
|
|
346
489
|
it('works for all', () => {
|
|
347
|
-
let file = program.
|
|
490
|
+
let file = program.setFile({ src: `${rootDir} / source / main.brs`, dest: 'source/main.brs' }, `
|
|
348
491
|
sub Main()
|
|
349
492
|
z::;;%%%%%% 'bs:disable-line
|
|
350
493
|
end sub
|
|
351
494
|
`);
|
|
352
|
-
chai_1.expect(file.commentFlags[0]).to.exist;
|
|
353
|
-
chai_1.expect(file.commentFlags[0]).to.deep.include({
|
|
495
|
+
(0, chai_1.expect)(file.commentFlags[0]).to.exist;
|
|
496
|
+
(0, chai_1.expect)(file.commentFlags[0]).to.deep.include({
|
|
354
497
|
codes: null,
|
|
355
498
|
range: vscode_languageserver_1.Range.create(2, 36, 2, 52),
|
|
356
499
|
affectedRange: vscode_languageserver_1.Range.create(2, 0, 2, 36)
|
|
357
500
|
});
|
|
358
501
|
program.validate();
|
|
359
502
|
//the "unterminated string" error should be filtered out
|
|
360
|
-
|
|
503
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
361
504
|
});
|
|
362
505
|
it('works for specific codes', () => {
|
|
363
|
-
program.
|
|
506
|
+
program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
364
507
|
sub main()
|
|
365
508
|
'should not have any errors
|
|
366
509
|
DoSomething(1) 'bs:disable-line:1002
|
|
@@ -371,42 +514,78 @@ describe('BrsFile', () => {
|
|
|
371
514
|
end sub
|
|
372
515
|
`);
|
|
373
516
|
program.validate();
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
});
|
|
517
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [{
|
|
518
|
+
range: vscode_languageserver_1.Range.create(5, 24, 5, 35)
|
|
519
|
+
}]);
|
|
378
520
|
});
|
|
379
521
|
it('handles the erraneous `stop` keyword', () => {
|
|
380
522
|
//the current version of BRS causes parse errors after the `parse` keyword, showing error in comments
|
|
381
523
|
//the program should ignore all diagnostics found in brs:* comment lines EXCEPT
|
|
382
524
|
//for the diagnostics about using unknown error codes
|
|
383
|
-
program.
|
|
525
|
+
program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
384
526
|
sub main()
|
|
385
527
|
stop 'bs:disable-line
|
|
386
528
|
print "need a valid line to fix stop error"
|
|
387
529
|
end sub
|
|
388
|
-
|
|
530
|
+
`);
|
|
389
531
|
program.validate();
|
|
390
|
-
|
|
532
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
391
533
|
});
|
|
392
534
|
});
|
|
393
535
|
});
|
|
394
536
|
describe('parse', () => {
|
|
537
|
+
it('allows class as parameter type', () => {
|
|
538
|
+
program.setFile(`source/main.bs`, `
|
|
539
|
+
class Person
|
|
540
|
+
name as string
|
|
541
|
+
end class
|
|
542
|
+
|
|
543
|
+
sub PrintPerson(p as Person)
|
|
544
|
+
end sub
|
|
545
|
+
`);
|
|
546
|
+
program.validate();
|
|
547
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
548
|
+
});
|
|
549
|
+
it('allows interface as parameter type', () => {
|
|
550
|
+
program.setFile(`source/main.bs`, `
|
|
551
|
+
interface Person
|
|
552
|
+
name as string
|
|
553
|
+
end interface
|
|
554
|
+
|
|
555
|
+
sub PrintPerson(p as Person)
|
|
556
|
+
end sub
|
|
557
|
+
`);
|
|
558
|
+
program.validate();
|
|
559
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
560
|
+
});
|
|
561
|
+
it('allows enum as parameter type', () => {
|
|
562
|
+
program.setFile(`source/main.bs`, `
|
|
563
|
+
enum Direction
|
|
564
|
+
up
|
|
565
|
+
down
|
|
566
|
+
end enum
|
|
567
|
+
|
|
568
|
+
sub PrintDirection(d as Direction)
|
|
569
|
+
end sub
|
|
570
|
+
`);
|
|
571
|
+
program.validate();
|
|
572
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
573
|
+
});
|
|
395
574
|
it('supports iife in assignment', () => {
|
|
396
|
-
program.
|
|
575
|
+
program.setFile('source/main.brs', `
|
|
397
576
|
sub main()
|
|
398
|
-
|
|
577
|
+
result = sub()
|
|
399
578
|
end sub()
|
|
400
|
-
|
|
579
|
+
result = (sub()
|
|
401
580
|
end sub)()
|
|
402
581
|
end sub
|
|
403
582
|
`);
|
|
404
|
-
testHelpers_spec_1.expectZeroDiagnostics(program);
|
|
583
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
405
584
|
});
|
|
406
585
|
it('uses the proper parse mode based on file extension', () => {
|
|
407
586
|
function testParseMode(destPath, expectedParseMode) {
|
|
408
|
-
const file = program.
|
|
409
|
-
chai_1.expect(file.parseMode).to.equal(expectedParseMode);
|
|
587
|
+
const file = program.setFile(destPath, '');
|
|
588
|
+
(0, chai_1.expect)(file.parseMode).to.equal(expectedParseMode);
|
|
410
589
|
}
|
|
411
590
|
testParseMode('source/main.brs', Parser_1.ParseMode.BrightScript);
|
|
412
591
|
testParseMode('source/main.spec.brs', Parser_1.ParseMode.BrightScript);
|
|
@@ -416,26 +595,26 @@ describe('BrsFile', () => {
|
|
|
416
595
|
testParseMode('source/main.spec.bs', Parser_1.ParseMode.BrighterScript);
|
|
417
596
|
});
|
|
418
597
|
it('supports labels and goto statements', () => {
|
|
419
|
-
let file = program.
|
|
598
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
420
599
|
sub Main()
|
|
421
600
|
'multiple goto statements on one line
|
|
422
|
-
goto myLabel
|
|
601
|
+
goto myLabel: goto myLabel
|
|
423
602
|
myLabel:
|
|
424
603
|
end sub
|
|
425
604
|
`);
|
|
426
|
-
|
|
605
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
427
606
|
});
|
|
428
607
|
it('supports empty print statements', () => {
|
|
429
|
-
let file = program.
|
|
608
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
430
609
|
sub main()
|
|
431
|
-
|
|
610
|
+
print
|
|
432
611
|
end sub
|
|
433
612
|
`);
|
|
434
|
-
|
|
613
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
435
614
|
});
|
|
436
615
|
describe('conditional compile', () => {
|
|
437
616
|
it('works for upper case keywords', () => {
|
|
438
|
-
let file = program.
|
|
617
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
439
618
|
sub main()
|
|
440
619
|
#CONST someFlag = true
|
|
441
620
|
#IF someFlag
|
|
@@ -447,10 +626,10 @@ describe('BrsFile', () => {
|
|
|
447
626
|
#ENDIF
|
|
448
627
|
end sub
|
|
449
628
|
`);
|
|
450
|
-
|
|
629
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
451
630
|
});
|
|
452
631
|
it('supports single-word #elseif and #endif', () => {
|
|
453
|
-
let file = program.
|
|
632
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
454
633
|
sub main()
|
|
455
634
|
#const someFlag = true
|
|
456
635
|
#if someFlag
|
|
@@ -460,10 +639,10 @@ describe('BrsFile', () => {
|
|
|
460
639
|
#endif
|
|
461
640
|
end sub
|
|
462
641
|
`);
|
|
463
|
-
|
|
642
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
464
643
|
});
|
|
465
644
|
it('supports multi-word #else if and #end if', () => {
|
|
466
|
-
let file = program.
|
|
645
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
467
646
|
sub main()
|
|
468
647
|
#const someFlag = true
|
|
469
648
|
#if someFlag
|
|
@@ -473,84 +652,93 @@ describe('BrsFile', () => {
|
|
|
473
652
|
#end if
|
|
474
653
|
end sub
|
|
475
654
|
`);
|
|
476
|
-
|
|
655
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
477
656
|
});
|
|
478
657
|
it('does not choke on invalid code inside a false conditional compile', () => {
|
|
479
|
-
let file = program.
|
|
658
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
480
659
|
sub main()
|
|
481
660
|
#if false
|
|
482
|
-
non-commented code here should not cause parse errors
|
|
661
|
+
non - commented code here should not cause parse errors
|
|
483
662
|
#end if
|
|
484
663
|
end sub
|
|
485
664
|
`);
|
|
486
|
-
|
|
665
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
487
666
|
});
|
|
488
667
|
it('detects syntax error in #if', () => {
|
|
489
|
-
let file = program.
|
|
668
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
490
669
|
sub main()
|
|
491
670
|
#if true1
|
|
492
671
|
print "true"
|
|
493
672
|
#end if
|
|
494
673
|
end sub
|
|
495
674
|
`);
|
|
496
|
-
|
|
675
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, [
|
|
676
|
+
DiagnosticMessages_1.DiagnosticMessages.referencedConstDoesNotExist()
|
|
677
|
+
]);
|
|
497
678
|
});
|
|
498
679
|
it('detects syntax error in #const', () => {
|
|
499
|
-
let file = program.
|
|
680
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
500
681
|
sub main()
|
|
501
682
|
#if %
|
|
502
683
|
print "true"
|
|
503
684
|
#end if
|
|
504
685
|
end sub
|
|
505
686
|
`);
|
|
506
|
-
|
|
687
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, [
|
|
688
|
+
DiagnosticMessages_1.DiagnosticMessages.unexpectedCharacter('%'),
|
|
689
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidHashIfValue()
|
|
690
|
+
]);
|
|
507
691
|
});
|
|
508
692
|
it('detects #const name using reserved word', () => {
|
|
509
|
-
let file = program.
|
|
693
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
510
694
|
sub main()
|
|
511
695
|
#const function = true
|
|
512
696
|
end sub
|
|
513
697
|
`);
|
|
514
|
-
|
|
698
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, [
|
|
699
|
+
DiagnosticMessages_1.DiagnosticMessages.constNameCannotBeReservedWord(),
|
|
700
|
+
DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('#const')
|
|
701
|
+
]);
|
|
515
702
|
});
|
|
516
703
|
it('detects syntax error in #const', () => {
|
|
517
|
-
let file = program.
|
|
704
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
518
705
|
sub main()
|
|
519
706
|
#const someConst = 123
|
|
520
707
|
end sub
|
|
521
708
|
`);
|
|
522
|
-
|
|
709
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, [
|
|
710
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidHashConstValue()
|
|
711
|
+
]);
|
|
523
712
|
});
|
|
524
713
|
});
|
|
525
714
|
it('supports stop statement', () => {
|
|
526
|
-
let file = program.
|
|
715
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
527
716
|
sub main()
|
|
528
|
-
|
|
717
|
+
stop
|
|
529
718
|
end sub
|
|
530
719
|
`);
|
|
531
|
-
|
|
720
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
532
721
|
});
|
|
533
722
|
it('supports single-line if statements', () => {
|
|
534
|
-
let file = program.
|
|
723
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
535
724
|
sub main()
|
|
536
725
|
if 1 < 2: return true: end if
|
|
537
726
|
if 1 < 2: return true
|
|
538
727
|
end if
|
|
539
728
|
if false : print "true" : end if
|
|
540
729
|
if true: print "8 worked": else if true: print "not run": else: print "not run": end if
|
|
541
|
-
if true then
|
|
730
|
+
if true then: test = sub() : print "yes" : end sub: end if
|
|
542
731
|
end sub
|
|
543
732
|
`);
|
|
544
|
-
|
|
733
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
545
734
|
});
|
|
546
735
|
it('supports line_num as global variable', () => {
|
|
547
|
-
var _a;
|
|
548
736
|
file.parse(`
|
|
549
737
|
sub Main()
|
|
550
738
|
print LINE_NUM
|
|
551
739
|
end sub
|
|
552
740
|
`);
|
|
553
|
-
|
|
741
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
554
742
|
});
|
|
555
743
|
it('supports many keywords as object property names', () => {
|
|
556
744
|
file.parse(`
|
|
@@ -616,7 +804,7 @@ describe('BrsFile', () => {
|
|
|
616
804
|
person.new = true
|
|
617
805
|
end sub
|
|
618
806
|
`);
|
|
619
|
-
|
|
807
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
620
808
|
});
|
|
621
809
|
it('does not error on numeric literal type designators', () => {
|
|
622
810
|
file.parse(`
|
|
@@ -624,13 +812,13 @@ describe('BrsFile', () => {
|
|
|
624
812
|
print &he2
|
|
625
813
|
print 1.2E+2
|
|
626
814
|
print 2!
|
|
627
|
-
print 12D-12
|
|
815
|
+
print 12D - 12
|
|
628
816
|
print 2.3#
|
|
629
817
|
print &hFEDCBA9876543210&
|
|
630
818
|
print 9876543210&
|
|
631
819
|
end sub
|
|
632
820
|
`);
|
|
633
|
-
|
|
821
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
634
822
|
});
|
|
635
823
|
it('does not error when encountering sub with return type', () => {
|
|
636
824
|
file.parse(`
|
|
@@ -638,7 +826,7 @@ describe('BrsFile', () => {
|
|
|
638
826
|
return
|
|
639
827
|
end sub
|
|
640
828
|
`);
|
|
641
|
-
|
|
829
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
642
830
|
});
|
|
643
831
|
it('does not lose function statements when mismatched end sub', () => {
|
|
644
832
|
file.parse(`
|
|
@@ -650,7 +838,7 @@ describe('BrsFile', () => {
|
|
|
650
838
|
print "hello world"
|
|
651
839
|
end sub
|
|
652
840
|
`);
|
|
653
|
-
chai_1.expect(file.parser.references.functionStatements).to.be.lengthOf(2);
|
|
841
|
+
(0, chai_1.expect)(file.parser.references.functionStatements).to.be.lengthOf(2);
|
|
654
842
|
});
|
|
655
843
|
it('does not lose sub scope when mismatched end function', () => {
|
|
656
844
|
file.parse(`
|
|
@@ -662,7 +850,7 @@ describe('BrsFile', () => {
|
|
|
662
850
|
print "hello world"
|
|
663
851
|
end sub
|
|
664
852
|
`);
|
|
665
|
-
chai_1.expect(file.parser.references.functionStatements).to.be.lengthOf(2);
|
|
853
|
+
(0, chai_1.expect)(file.parser.references.functionStatements).to.be.lengthOf(2);
|
|
666
854
|
});
|
|
667
855
|
it('does not error with boolean in RHS of set statement', () => {
|
|
668
856
|
file.parse(`
|
|
@@ -673,7 +861,7 @@ describe('BrsFile', () => {
|
|
|
673
861
|
foo.bar = true and false or 3 > 4
|
|
674
862
|
end sub
|
|
675
863
|
`);
|
|
676
|
-
|
|
864
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
677
865
|
});
|
|
678
866
|
it('does not error with boolean in RHS of set statement', () => {
|
|
679
867
|
file.parse(`
|
|
@@ -686,57 +874,57 @@ describe('BrsFile', () => {
|
|
|
686
874
|
m.isTrue = m.isTrue = m.isTrue
|
|
687
875
|
end sub
|
|
688
876
|
`);
|
|
689
|
-
|
|
877
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
690
878
|
});
|
|
691
879
|
it('supports variable names ending with type designators', () => {
|
|
692
880
|
file.parse(`
|
|
693
881
|
sub main()
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
882
|
+
name$ = "bob"
|
|
883
|
+
age% = 1
|
|
884
|
+
height! = 5.5
|
|
885
|
+
salary# = 9.87654321
|
|
886
|
+
someHex& = 13
|
|
699
887
|
end sub
|
|
700
888
|
`);
|
|
701
|
-
|
|
889
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
702
890
|
});
|
|
703
891
|
it('supports multiple spaces between two-word keywords', () => {
|
|
704
892
|
file.parse(`
|
|
705
893
|
sub main()
|
|
706
894
|
if true then
|
|
707
895
|
print "true"
|
|
708
|
-
else
|
|
896
|
+
else if true then
|
|
709
897
|
print "also true"
|
|
710
898
|
end if
|
|
711
899
|
end sub
|
|
712
900
|
`);
|
|
713
|
-
|
|
901
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
714
902
|
});
|
|
715
903
|
it('does not error with `stop` as object key', () => {
|
|
716
904
|
file.parse(`
|
|
717
905
|
function GetObject()
|
|
718
906
|
obj = {
|
|
719
|
-
|
|
907
|
+
stop: function () as void
|
|
720
908
|
|
|
721
|
-
|
|
909
|
+
end function
|
|
722
910
|
}
|
|
723
911
|
return obj
|
|
724
912
|
end function
|
|
725
913
|
`);
|
|
726
|
-
|
|
914
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
727
915
|
});
|
|
728
916
|
it('does not error with `run` as object key', () => {
|
|
729
917
|
file.parse(`
|
|
730
918
|
function GetObject()
|
|
731
919
|
obj = {
|
|
732
|
-
run: function() as void
|
|
920
|
+
run: function () as void
|
|
733
921
|
|
|
734
922
|
end function
|
|
735
|
-
|
|
923
|
+
}
|
|
736
924
|
return obj
|
|
737
925
|
end function
|
|
738
926
|
`);
|
|
739
|
-
|
|
927
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
740
928
|
});
|
|
741
929
|
it('supports assignment operators', () => {
|
|
742
930
|
file.parse(`
|
|
@@ -753,28 +941,28 @@ describe('BrsFile', () => {
|
|
|
753
941
|
print x
|
|
754
942
|
end function
|
|
755
943
|
`);
|
|
756
|
-
|
|
944
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
757
945
|
});
|
|
758
946
|
it('supports `then` as object property', () => {
|
|
759
947
|
file.parse(`
|
|
760
948
|
function Main()
|
|
761
949
|
promise = {
|
|
762
950
|
then: sub()
|
|
763
|
-
|
|
951
|
+
end sub
|
|
764
952
|
}
|
|
765
953
|
promise.then()
|
|
766
954
|
end function
|
|
767
955
|
`);
|
|
768
|
-
|
|
956
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
769
957
|
});
|
|
770
958
|
it('supports function as parameter type', () => {
|
|
771
959
|
file.parse(`
|
|
772
960
|
sub Main()
|
|
773
|
-
doWork = function(callback as function)
|
|
961
|
+
doWork = function (callback as function)
|
|
774
962
|
end function
|
|
775
963
|
end sub
|
|
776
964
|
`);
|
|
777
|
-
|
|
965
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
778
966
|
});
|
|
779
967
|
it('supports increment operator', () => {
|
|
780
968
|
file.parse(`
|
|
@@ -783,8 +971,7 @@ describe('BrsFile', () => {
|
|
|
783
971
|
x++
|
|
784
972
|
end function
|
|
785
973
|
`);
|
|
786
|
-
|
|
787
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
974
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
788
975
|
});
|
|
789
976
|
it('supports decrement operator', () => {
|
|
790
977
|
file.parse(`
|
|
@@ -793,8 +980,7 @@ describe('BrsFile', () => {
|
|
|
793
980
|
x--
|
|
794
981
|
end function
|
|
795
982
|
`);
|
|
796
|
-
|
|
797
|
-
chai_1.expect(file.getDiagnostics()).to.be.lengthOf(0);
|
|
983
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
798
984
|
});
|
|
799
985
|
it('supports writing numbers with decimal but no trailing digit', () => {
|
|
800
986
|
file.parse(`
|
|
@@ -803,7 +989,7 @@ describe('BrsFile', () => {
|
|
|
803
989
|
print x
|
|
804
990
|
end function
|
|
805
991
|
`);
|
|
806
|
-
|
|
992
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
807
993
|
});
|
|
808
994
|
it('supports assignment operators against object properties', () => {
|
|
809
995
|
file.parse(`
|
|
@@ -825,7 +1011,7 @@ describe('BrsFile', () => {
|
|
|
825
1011
|
print m.age
|
|
826
1012
|
end function
|
|
827
1013
|
`);
|
|
828
|
-
|
|
1014
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
829
1015
|
});
|
|
830
1016
|
//skipped until `brs` supports this
|
|
831
1017
|
it('supports bitshift assignment operators', () => {
|
|
@@ -837,7 +1023,7 @@ describe('BrsFile', () => {
|
|
|
837
1023
|
print x
|
|
838
1024
|
end function
|
|
839
1025
|
`);
|
|
840
|
-
|
|
1026
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
841
1027
|
});
|
|
842
1028
|
//skipped until `brs` supports this
|
|
843
1029
|
it('supports bitshift assignment operators on objects', () => {
|
|
@@ -849,7 +1035,7 @@ describe('BrsFile', () => {
|
|
|
849
1035
|
print m.x
|
|
850
1036
|
end function
|
|
851
1037
|
`);
|
|
852
|
-
|
|
1038
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
853
1039
|
});
|
|
854
1040
|
it('supports leading and trailing periods for numeric literals', () => {
|
|
855
1041
|
file.parse(`
|
|
@@ -860,7 +1046,7 @@ describe('BrsFile', () => {
|
|
|
860
1046
|
print pointOne
|
|
861
1047
|
end function
|
|
862
1048
|
`);
|
|
863
|
-
|
|
1049
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
864
1050
|
});
|
|
865
1051
|
it('supports bitshift assignment operators on object properties accessed by array syntax', () => {
|
|
866
1052
|
file.parse(`
|
|
@@ -871,7 +1057,7 @@ describe('BrsFile', () => {
|
|
|
871
1057
|
print m.x
|
|
872
1058
|
end function
|
|
873
1059
|
`);
|
|
874
|
-
|
|
1060
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
875
1061
|
});
|
|
876
1062
|
it('supports weird period AA accessor', () => {
|
|
877
1063
|
file.parse(`
|
|
@@ -880,67 +1066,71 @@ describe('BrsFile', () => {
|
|
|
880
1066
|
print m.["_uuid"]
|
|
881
1067
|
end function
|
|
882
1068
|
`);
|
|
883
|
-
|
|
1069
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
884
1070
|
});
|
|
885
1071
|
it('adds error for library statements NOT at top of file', () => {
|
|
886
|
-
|
|
1072
|
+
program.setFile('source/file.brs', ``);
|
|
1073
|
+
program.setFile('source/main.bs', `
|
|
887
1074
|
sub main()
|
|
888
1075
|
end sub
|
|
889
1076
|
import "file.brs"
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
1077
|
+
`);
|
|
1078
|
+
program.validate();
|
|
1079
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1080
|
+
DiagnosticMessages_1.DiagnosticMessages.importStatementMustBeDeclaredAtTopOfFile()
|
|
893
1081
|
]);
|
|
894
1082
|
});
|
|
895
1083
|
it('supports library imports', () => {
|
|
896
|
-
|
|
1084
|
+
program.setFile('source/main.brs', `
|
|
897
1085
|
Library "v30/bslCore.brs"
|
|
898
1086
|
`);
|
|
899
|
-
|
|
1087
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
900
1088
|
});
|
|
901
1089
|
it('adds error for library statements NOT at top of file', () => {
|
|
902
|
-
|
|
1090
|
+
program.setFile('source/main.brs', `
|
|
903
1091
|
sub main()
|
|
904
1092
|
end sub
|
|
905
1093
|
Library "v30/bslCore.brs"
|
|
906
1094
|
`);
|
|
907
|
-
|
|
908
|
-
|
|
1095
|
+
program.validate();
|
|
1096
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1097
|
+
DiagnosticMessages_1.DiagnosticMessages.libraryStatementMustBeDeclaredAtTopOfFile()
|
|
909
1098
|
]);
|
|
910
1099
|
});
|
|
911
1100
|
it('adds error for library statements inside of function body', () => {
|
|
912
|
-
|
|
1101
|
+
program.setFile('source/main.brs', `
|
|
913
1102
|
sub main()
|
|
914
1103
|
Library "v30/bslCore.brs"
|
|
915
1104
|
end sub
|
|
916
1105
|
`);
|
|
917
|
-
|
|
918
|
-
|
|
1106
|
+
program.validate();
|
|
1107
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1108
|
+
DiagnosticMessages_1.DiagnosticMessages.libraryStatementMustBeDeclaredAtTopOfFile()
|
|
919
1109
|
]);
|
|
920
1110
|
});
|
|
921
1111
|
it('supports colons as separators in associative array properties', () => {
|
|
922
1112
|
file.parse(`
|
|
923
1113
|
sub Main()
|
|
924
|
-
obj = {x:0 : y: 1}
|
|
1114
|
+
obj = { x: 0 : y: 1 }
|
|
925
1115
|
end sub
|
|
926
1116
|
`);
|
|
927
|
-
|
|
1117
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
928
1118
|
});
|
|
929
1119
|
it('succeeds when finding variables with "sub" in them', () => {
|
|
930
|
-
let file = program.
|
|
1120
|
+
let file = program.setFile('source/main.brs', `
|
|
931
1121
|
function DoSomething()
|
|
932
1122
|
return value.subType()
|
|
933
1123
|
end function
|
|
934
1124
|
`);
|
|
935
|
-
chai_1.expect(file.callables[0]).to.deep.include({
|
|
1125
|
+
(0, chai_1.expect)(file.callables[0]).to.deep.include({
|
|
936
1126
|
file: file,
|
|
937
1127
|
nameRange: vscode_languageserver_1.Range.create(1, 25, 1, 36)
|
|
938
1128
|
});
|
|
939
1129
|
});
|
|
940
1130
|
it('succeeds when finding variables with the word "function" in them', () => {
|
|
941
1131
|
file.parse(`
|
|
942
|
-
|
|
943
|
-
|
|
1132
|
+
function Test()
|
|
1133
|
+
typeCheckFunction = RBS_CMN_GetFunction(invalid, methodName)
|
|
944
1134
|
end function
|
|
945
1135
|
`);
|
|
946
1136
|
});
|
|
@@ -951,14 +1141,14 @@ describe('BrsFile', () => {
|
|
|
951
1141
|
print "A"
|
|
952
1142
|
end function
|
|
953
1143
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1144
|
+
function DoB()
|
|
1145
|
+
print "B"
|
|
1146
|
+
end function
|
|
957
1147
|
`);
|
|
958
|
-
chai_1.expect(file.callables[0].name).to.equal('DoA');
|
|
959
|
-
chai_1.expect(file.callables[0].nameRange).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 28));
|
|
960
|
-
chai_1.expect(file.callables[1].name).to.equal('DoB');
|
|
961
|
-
chai_1.expect(file.callables[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5,
|
|
1148
|
+
(0, chai_1.expect)(file.callables[0].name).to.equal('DoA');
|
|
1149
|
+
(0, chai_1.expect)(file.callables[0].nameRange).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 28));
|
|
1150
|
+
(0, chai_1.expect)(file.callables[1].name).to.equal('DoB');
|
|
1151
|
+
(0, chai_1.expect)(file.callables[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 25, 5, 28));
|
|
962
1152
|
});
|
|
963
1153
|
it('throws an error if the file has already been parsed', () => {
|
|
964
1154
|
let file = new BrsFile_1.BrsFile('abspath', 'relpath', program);
|
|
@@ -982,11 +1172,11 @@ describe('BrsFile', () => {
|
|
|
982
1172
|
print "A"
|
|
983
1173
|
end function
|
|
984
1174
|
`);
|
|
985
|
-
chai_1.expect(file.callables.length).to.equal(2);
|
|
986
|
-
chai_1.expect(file.callables[0].name).to.equal('DoA');
|
|
987
|
-
chai_1.expect(file.callables[0].nameRange.start.line).to.equal(1);
|
|
988
|
-
chai_1.expect(file.callables[1].name).to.equal('DoA');
|
|
989
|
-
chai_1.expect(file.callables[1].nameRange.start.line).to.equal(5);
|
|
1175
|
+
(0, chai_1.expect)(file.callables.length).to.equal(2);
|
|
1176
|
+
(0, chai_1.expect)(file.callables[0].name).to.equal('DoA');
|
|
1177
|
+
(0, chai_1.expect)(file.callables[0].nameRange.start.line).to.equal(1);
|
|
1178
|
+
(0, chai_1.expect)(file.callables[1].name).to.equal('DoA');
|
|
1179
|
+
(0, chai_1.expect)(file.callables[1].nameRange.start.line).to.equal(5);
|
|
990
1180
|
});
|
|
991
1181
|
it('finds function call line and column numbers', () => {
|
|
992
1182
|
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
@@ -998,11 +1188,11 @@ describe('BrsFile', () => {
|
|
|
998
1188
|
DoC()
|
|
999
1189
|
end function
|
|
1000
1190
|
`);
|
|
1001
|
-
chai_1.expect(file.functionCalls.length).to.equal(2);
|
|
1002
|
-
chai_1.expect(file.functionCalls[0].range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 28));
|
|
1003
|
-
chai_1.expect(file.functionCalls[0].nameRange).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 23));
|
|
1004
|
-
chai_1.expect(file.functionCalls[1].range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 25));
|
|
1005
|
-
chai_1.expect(file.functionCalls[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 23));
|
|
1191
|
+
(0, chai_1.expect)(file.functionCalls.length).to.equal(2);
|
|
1192
|
+
(0, chai_1.expect)(file.functionCalls[0].range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 28));
|
|
1193
|
+
(0, chai_1.expect)(file.functionCalls[0].nameRange).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 23));
|
|
1194
|
+
(0, chai_1.expect)(file.functionCalls[1].range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 25));
|
|
1195
|
+
(0, chai_1.expect)(file.functionCalls[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 23));
|
|
1006
1196
|
});
|
|
1007
1197
|
it('sanitizes brs errors', () => {
|
|
1008
1198
|
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
@@ -1010,11 +1200,9 @@ describe('BrsFile', () => {
|
|
|
1010
1200
|
function DoSomething
|
|
1011
1201
|
end function
|
|
1012
1202
|
`);
|
|
1013
|
-
|
|
1014
|
-
chai_1.expect(file.getDiagnostics()[0]).to.
|
|
1015
|
-
|
|
1016
|
-
});
|
|
1017
|
-
chai_1.expect(file.getDiagnostics()[0].range.start.line).to.equal(1);
|
|
1203
|
+
(0, testHelpers_spec_1.expectHasDiagnostics)(file);
|
|
1204
|
+
(0, chai_1.expect)(file.getDiagnostics()[0].file).to.equal(file);
|
|
1205
|
+
(0, chai_1.expect)(file.getDiagnostics()[0].range.start.line).to.equal(1);
|
|
1018
1206
|
});
|
|
1019
1207
|
it('supports using the `next` keyword in a for loop', () => {
|
|
1020
1208
|
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
@@ -1025,7 +1213,7 @@ describe('BrsFile', () => {
|
|
|
1025
1213
|
next
|
|
1026
1214
|
end sub
|
|
1027
1215
|
`);
|
|
1028
|
-
|
|
1216
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
1029
1217
|
});
|
|
1030
1218
|
//test is not working yet, but will be enabled when brs supports this syntax
|
|
1031
1219
|
it('supports assigning functions to objects', () => {
|
|
@@ -1038,7 +1226,7 @@ describe('BrsFile', () => {
|
|
|
1038
1226
|
end sub
|
|
1039
1227
|
end function
|
|
1040
1228
|
`);
|
|
1041
|
-
|
|
1229
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
1042
1230
|
});
|
|
1043
1231
|
});
|
|
1044
1232
|
describe('findCallables', () => {
|
|
@@ -1050,7 +1238,7 @@ describe('BrsFile', () => {
|
|
|
1050
1238
|
end sub
|
|
1051
1239
|
`);
|
|
1052
1240
|
let callable = file.callables[0];
|
|
1053
|
-
chai_1.expect(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 3, 23));
|
|
1241
|
+
(0, chai_1.expect)(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 3, 23));
|
|
1054
1242
|
});
|
|
1055
1243
|
it('finds correct body range even with inner function', () => {
|
|
1056
1244
|
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
@@ -1063,7 +1251,7 @@ describe('BrsFile', () => {
|
|
|
1063
1251
|
end sub
|
|
1064
1252
|
`);
|
|
1065
1253
|
let callable = file.callables[0];
|
|
1066
|
-
chai_1.expect(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 6, 23));
|
|
1254
|
+
(0, chai_1.expect)(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 6, 23));
|
|
1067
1255
|
});
|
|
1068
1256
|
it('finds callable parameters', () => {
|
|
1069
1257
|
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
@@ -1073,24 +1261,24 @@ describe('BrsFile', () => {
|
|
|
1073
1261
|
end function
|
|
1074
1262
|
`);
|
|
1075
1263
|
let callable = file.callables[0];
|
|
1076
|
-
chai_1.expect(callable.params[0]).to.deep.include({
|
|
1264
|
+
(0, chai_1.expect)(callable.params[0]).to.deep.include({
|
|
1077
1265
|
name: 'a',
|
|
1078
1266
|
isOptional: false,
|
|
1079
1267
|
isRestArgument: false
|
|
1080
1268
|
});
|
|
1081
|
-
chai_1.expect(callable.params[0].type).instanceof(DynamicType_1.DynamicType);
|
|
1082
|
-
chai_1.expect(callable.params[1]).to.deep.include({
|
|
1269
|
+
(0, chai_1.expect)(callable.params[0].type).instanceof(DynamicType_1.DynamicType);
|
|
1270
|
+
(0, chai_1.expect)(callable.params[1]).to.deep.include({
|
|
1083
1271
|
name: 'b',
|
|
1084
1272
|
isOptional: false,
|
|
1085
1273
|
isRestArgument: false
|
|
1086
1274
|
});
|
|
1087
|
-
chai_1.expect(callable.params[1].type).instanceof(DynamicType_1.DynamicType);
|
|
1088
|
-
chai_1.expect(callable.params[2]).to.deep.include({
|
|
1275
|
+
(0, chai_1.expect)(callable.params[1].type).instanceof(DynamicType_1.DynamicType);
|
|
1276
|
+
(0, chai_1.expect)(callable.params[2]).to.deep.include({
|
|
1089
1277
|
name: 'c',
|
|
1090
1278
|
isOptional: false,
|
|
1091
1279
|
isRestArgument: false
|
|
1092
1280
|
});
|
|
1093
|
-
chai_1.expect(callable.params[2].type).instanceof(DynamicType_1.DynamicType);
|
|
1281
|
+
(0, chai_1.expect)(callable.params[2].type).instanceof(DynamicType_1.DynamicType);
|
|
1094
1282
|
});
|
|
1095
1283
|
it('finds optional parameters', () => {
|
|
1096
1284
|
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
@@ -1100,12 +1288,12 @@ describe('BrsFile', () => {
|
|
|
1100
1288
|
end function
|
|
1101
1289
|
`);
|
|
1102
1290
|
let callable = file.callables[0];
|
|
1103
|
-
chai_1.expect(callable.params[0]).to.deep.include({
|
|
1291
|
+
(0, chai_1.expect)(callable.params[0]).to.deep.include({
|
|
1104
1292
|
name: 'a',
|
|
1105
1293
|
isOptional: true,
|
|
1106
1294
|
isRestArgument: false
|
|
1107
1295
|
});
|
|
1108
|
-
chai_1.expect(callable.params[0].type).instanceof(IntegerType_1.IntegerType);
|
|
1296
|
+
(0, chai_1.expect)(callable.params[0].type).instanceof(IntegerType_1.IntegerType);
|
|
1109
1297
|
});
|
|
1110
1298
|
it('finds parameter types', () => {
|
|
1111
1299
|
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
@@ -1115,24 +1303,24 @@ describe('BrsFile', () => {
|
|
|
1115
1303
|
end function
|
|
1116
1304
|
`);
|
|
1117
1305
|
let callable = file.callables[0];
|
|
1118
|
-
chai_1.expect(callable.params[0]).to.deep.include({
|
|
1306
|
+
(0, chai_1.expect)(callable.params[0]).to.deep.include({
|
|
1119
1307
|
name: 'a',
|
|
1120
1308
|
isOptional: false,
|
|
1121
1309
|
isRestArgument: false
|
|
1122
1310
|
});
|
|
1123
|
-
chai_1.expect(callable.params[0].type).instanceof(DynamicType_1.DynamicType);
|
|
1124
|
-
chai_1.expect(callable.params[1]).to.deep.include({
|
|
1311
|
+
(0, chai_1.expect)(callable.params[0].type).instanceof(DynamicType_1.DynamicType);
|
|
1312
|
+
(0, chai_1.expect)(callable.params[1]).to.deep.include({
|
|
1125
1313
|
name: 'b',
|
|
1126
1314
|
isOptional: false,
|
|
1127
1315
|
isRestArgument: false
|
|
1128
1316
|
});
|
|
1129
|
-
chai_1.expect(callable.params[1].type).instanceof(IntegerType_1.IntegerType);
|
|
1130
|
-
chai_1.expect(callable.params[2]).to.deep.include({
|
|
1317
|
+
(0, chai_1.expect)(callable.params[1].type).instanceof(IntegerType_1.IntegerType);
|
|
1318
|
+
(0, chai_1.expect)(callable.params[2]).to.deep.include({
|
|
1131
1319
|
name: 'c',
|
|
1132
1320
|
isOptional: false,
|
|
1133
1321
|
isRestArgument: false
|
|
1134
1322
|
});
|
|
1135
|
-
chai_1.expect(callable.params[2].type).instanceof(StringType_1.StringType);
|
|
1323
|
+
(0, chai_1.expect)(callable.params[2].type).instanceof(StringType_1.StringType);
|
|
1136
1324
|
});
|
|
1137
1325
|
});
|
|
1138
1326
|
describe('findCallableInvocations', () => {
|
|
@@ -1143,8 +1331,12 @@ describe('BrsFile', () => {
|
|
|
1143
1331
|
DoSomething("name", 12, true)
|
|
1144
1332
|
end function
|
|
1145
1333
|
`);
|
|
1146
|
-
chai_1.expect(file.functionCalls.length).to.equal(1);
|
|
1147
|
-
|
|
1334
|
+
(0, chai_1.expect)(file.functionCalls.length).to.equal(1);
|
|
1335
|
+
const argsMap = file.functionCalls[0].args.map(arg => {
|
|
1336
|
+
// disregard arg.expression, etc.
|
|
1337
|
+
return { type: arg.type, range: arg.range, text: arg.text };
|
|
1338
|
+
});
|
|
1339
|
+
(0, chai_1.expect)(argsMap).to.eql([{
|
|
1148
1340
|
type: new StringType_1.StringType(),
|
|
1149
1341
|
range: util_1.default.createRange(2, 32, 2, 38),
|
|
1150
1342
|
text: '"name"'
|
|
@@ -1159,8 +1351,7 @@ describe('BrsFile', () => {
|
|
|
1159
1351
|
}]);
|
|
1160
1352
|
});
|
|
1161
1353
|
it('finds function calls nested inside statements', () => {
|
|
1162
|
-
|
|
1163
|
-
program.addOrReplaceFile(`source/main.brs`, `
|
|
1354
|
+
program.setFile(`source/main.brs`, `
|
|
1164
1355
|
sub main()
|
|
1165
1356
|
if true then
|
|
1166
1357
|
DoesNotExist(1, 2)
|
|
@@ -1168,7 +1359,9 @@ describe('BrsFile', () => {
|
|
|
1168
1359
|
end sub
|
|
1169
1360
|
`);
|
|
1170
1361
|
program.validate();
|
|
1171
|
-
|
|
1362
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1363
|
+
DiagnosticMessages_1.DiagnosticMessages.callToUnknownFunction('DoesNotExist', 'source')
|
|
1364
|
+
]);
|
|
1172
1365
|
});
|
|
1173
1366
|
it('finds arguments with variable values', () => {
|
|
1174
1367
|
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
@@ -1180,17 +1373,17 @@ describe('BrsFile', () => {
|
|
|
1180
1373
|
DoSomething(count, name, isAlive)
|
|
1181
1374
|
end function
|
|
1182
1375
|
`);
|
|
1183
|
-
chai_1.expect(file.functionCalls.length).to.equal(1);
|
|
1184
|
-
chai_1.expect(file.functionCalls[0].args[0]).deep.include({
|
|
1185
|
-
type: new
|
|
1376
|
+
(0, chai_1.expect)(file.functionCalls.length).to.equal(1);
|
|
1377
|
+
(0, chai_1.expect)(file.functionCalls[0].args[0]).deep.include({
|
|
1378
|
+
type: new IntegerType_1.IntegerType(),
|
|
1186
1379
|
text: 'count'
|
|
1187
1380
|
});
|
|
1188
|
-
chai_1.expect(file.functionCalls[0].args[1]).deep.include({
|
|
1189
|
-
type: new
|
|
1381
|
+
(0, chai_1.expect)(file.functionCalls[0].args[1]).deep.include({
|
|
1382
|
+
type: new StringType_1.StringType(),
|
|
1190
1383
|
text: 'name'
|
|
1191
1384
|
});
|
|
1192
|
-
chai_1.expect(file.functionCalls[0].args[2]).deep.include({
|
|
1193
|
-
type: new
|
|
1385
|
+
(0, chai_1.expect)(file.functionCalls[0].args[2]).deep.include({
|
|
1386
|
+
type: new BooleanType_1.BooleanType(),
|
|
1194
1387
|
text: 'isAlive'
|
|
1195
1388
|
});
|
|
1196
1389
|
});
|
|
@@ -1200,20 +1393,20 @@ describe('BrsFile', () => {
|
|
|
1200
1393
|
it('skips top-level statements', () => {
|
|
1201
1394
|
let file = new BrsFile_1.BrsFile('absolute', 'relative', program);
|
|
1202
1395
|
file.parse('name = "Bob"');
|
|
1203
|
-
chai_1.expect(file.callables.length).to.equal(0);
|
|
1396
|
+
(0, chai_1.expect)(file.callables.length).to.equal(0);
|
|
1204
1397
|
});
|
|
1205
1398
|
it('finds return type', () => {
|
|
1206
|
-
let file = program.
|
|
1399
|
+
let file = program.setFile('source/main.brs', `
|
|
1207
1400
|
function DoSomething() as string
|
|
1208
1401
|
end function
|
|
1209
1402
|
`);
|
|
1210
|
-
chai_1.expect(file.callables[0]).to.deep.include({
|
|
1403
|
+
(0, chai_1.expect)(file.callables[0]).to.deep.include({
|
|
1211
1404
|
file: file,
|
|
1212
1405
|
nameRange: vscode_languageserver_1.Range.create(1, 25, 1, 36),
|
|
1213
1406
|
name: 'DoSomething',
|
|
1214
1407
|
params: []
|
|
1215
1408
|
});
|
|
1216
|
-
chai_1.expect(file.callables[0].type.returnType).instanceof(StringType_1.StringType);
|
|
1409
|
+
(0, chai_1.expect)(file.callables[0].type.returnType).instanceof(StringType_1.StringType);
|
|
1217
1410
|
});
|
|
1218
1411
|
});
|
|
1219
1412
|
describe('function local variable handling', () => {
|
|
@@ -1223,7 +1416,7 @@ describe('BrsFile', () => {
|
|
|
1223
1416
|
name = 'bob"
|
|
1224
1417
|
end sub
|
|
1225
1418
|
`);
|
|
1226
|
-
chai_1.expect(file.parser.references.functionStatements[0].range).to.eql(vscode_languageserver_1.Range.create(1, 16, 3, 23));
|
|
1419
|
+
(0, chai_1.expect)(file.parser.references.functionStatements[0].range).to.eql(vscode_languageserver_1.Range.create(1, 16, 3, 23));
|
|
1227
1420
|
});
|
|
1228
1421
|
it('creates scopes for parent and child functions', () => {
|
|
1229
1422
|
file.parse(`
|
|
@@ -1237,7 +1430,7 @@ describe('BrsFile', () => {
|
|
|
1237
1430
|
end sub)
|
|
1238
1431
|
end sub
|
|
1239
1432
|
`);
|
|
1240
|
-
chai_1.expect(file.parser.references.functionExpressions).to.be.length(3);
|
|
1433
|
+
(0, chai_1.expect)(file.parser.references.functionExpressions).to.be.length(3);
|
|
1241
1434
|
});
|
|
1242
1435
|
it('finds variables declared in function expressions', () => {
|
|
1243
1436
|
file.parse(`
|
|
@@ -1251,13 +1444,13 @@ describe('BrsFile', () => {
|
|
|
1251
1444
|
end sub)
|
|
1252
1445
|
end sub
|
|
1253
1446
|
`);
|
|
1254
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1255
|
-
['sayHi', new
|
|
1447
|
+
(0, testHelpers_spec_1.expectSymbolTableEquals)(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1448
|
+
['sayHi', new TypedFunctionType_1.TypedFunctionType(new VoidType_1.VoidType(), true), util_1.default.createRange(2, 20, 2, 25)]
|
|
1256
1449
|
]);
|
|
1257
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[1].symbolTable, [
|
|
1450
|
+
(0, testHelpers_spec_1.expectSymbolTableEquals)(file.parser.references.functionExpressions[1].symbolTable, [
|
|
1258
1451
|
['age', new IntegerType_1.IntegerType(), util_1.default.createRange(3, 24, 3, 27)]
|
|
1259
1452
|
]);
|
|
1260
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[2].symbolTable, [
|
|
1453
|
+
(0, testHelpers_spec_1.expectSymbolTableEquals)(file.parser.references.functionExpressions[2].symbolTable, [
|
|
1261
1454
|
['name', new StringType_1.StringType(), util_1.default.createRange(7, 24, 7, 28)]
|
|
1262
1455
|
]);
|
|
1263
1456
|
});
|
|
@@ -1269,12 +1462,12 @@ describe('BrsFile', () => {
|
|
|
1269
1462
|
end if
|
|
1270
1463
|
end sub
|
|
1271
1464
|
`);
|
|
1272
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1465
|
+
(0, testHelpers_spec_1.expectSymbolTableEquals)(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1273
1466
|
['theLength', new IntegerType_1.IntegerType(), util_1.default.createRange(3, 24, 3, 33)]
|
|
1274
1467
|
]);
|
|
1275
1468
|
});
|
|
1276
1469
|
it('finds value from global return', () => {
|
|
1277
|
-
let file = program.
|
|
1470
|
+
let file = program.setFile('source/main.brs', `
|
|
1278
1471
|
sub Main()
|
|
1279
1472
|
myName = GetName()
|
|
1280
1473
|
end sub
|
|
@@ -1283,20 +1476,20 @@ describe('BrsFile', () => {
|
|
|
1283
1476
|
return "bob"
|
|
1284
1477
|
end function
|
|
1285
1478
|
`);
|
|
1286
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1479
|
+
(0, testHelpers_spec_1.expectSymbolTableEquals)(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1287
1480
|
['myName', new StringType_1.StringType(), util_1.default.createRange(2, 19, 2, 25)]
|
|
1288
1481
|
]);
|
|
1289
1482
|
});
|
|
1290
1483
|
it('finds variable type from other variable', () => {
|
|
1291
1484
|
file.parse(`
|
|
1292
1485
|
sub Main()
|
|
1293
|
-
|
|
1294
|
-
|
|
1486
|
+
name = "bob"
|
|
1487
|
+
nameCopy = name
|
|
1295
1488
|
end sub
|
|
1296
1489
|
`);
|
|
1297
|
-
testHelpers_spec_1.expectSymbolTableEquals(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1298
|
-
['name', new StringType_1.StringType(), util_1.default.createRange(2,
|
|
1299
|
-
['nameCopy', new StringType_1.StringType(), util_1.default.createRange(3,
|
|
1490
|
+
(0, testHelpers_spec_1.expectSymbolTableEquals)(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1491
|
+
['name', new StringType_1.StringType(), util_1.default.createRange(2, 20, 2, 24)],
|
|
1492
|
+
['nameCopy', new StringType_1.StringType(), util_1.default.createRange(3, 20, 3, 28)]
|
|
1300
1493
|
]);
|
|
1301
1494
|
});
|
|
1302
1495
|
it('sets proper range for functions', () => {
|
|
@@ -1307,8 +1500,7 @@ describe('BrsFile', () => {
|
|
|
1307
1500
|
end function
|
|
1308
1501
|
end sub
|
|
1309
1502
|
`);
|
|
1310
|
-
chai_1.expect(file.parser.references.functionExpressions).to.
|
|
1311
|
-
chai_1.expect(file.parser.references.functionExpressions.map(x => x.range)).to.eql([
|
|
1503
|
+
(0, chai_1.expect)(file.parser.references.functionExpressions.map(x => x.range)).to.eql([
|
|
1312
1504
|
util_1.default.createRange(1, 16, 5, 23),
|
|
1313
1505
|
util_1.default.createRange(2, 30, 4, 32)
|
|
1314
1506
|
]);
|
|
@@ -1316,37 +1508,37 @@ describe('BrsFile', () => {
|
|
|
1316
1508
|
});
|
|
1317
1509
|
describe('getHover', () => {
|
|
1318
1510
|
it('works for param types', () => {
|
|
1319
|
-
let file = program.
|
|
1511
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
1320
1512
|
sub DoSomething(name as string)
|
|
1321
1513
|
name = 1
|
|
1322
|
-
sayMyName = function(name as string)
|
|
1514
|
+
sayMyName = function (name as string)
|
|
1323
1515
|
end function
|
|
1324
1516
|
end sub
|
|
1325
1517
|
`);
|
|
1326
1518
|
//hover over the `name = 1` line
|
|
1327
1519
|
let hover = file.getHover(vscode_languageserver_1.Position.create(2, 24));
|
|
1328
|
-
chai_1.expect(hover).to.exist;
|
|
1329
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 24));
|
|
1520
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1521
|
+
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 24));
|
|
1330
1522
|
//hover over the `name` parameter declaration
|
|
1331
1523
|
hover = file.getHover(vscode_languageserver_1.Position.create(1, 34));
|
|
1332
|
-
chai_1.expect(hover).to.exist;
|
|
1333
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 32, 1, 36));
|
|
1524
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1525
|
+
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 32, 1, 36));
|
|
1334
1526
|
});
|
|
1335
1527
|
//ignore this for now...it's not a huge deal
|
|
1336
1528
|
it('does not match on keywords or data types', () => {
|
|
1337
|
-
let file = program.
|
|
1529
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
1338
1530
|
sub Main(name as string)
|
|
1339
1531
|
end sub
|
|
1340
|
-
sub as()
|
|
1532
|
+
sub as ()
|
|
1341
1533
|
end sub
|
|
1342
1534
|
`);
|
|
1343
|
-
//hover over the `as`
|
|
1344
|
-
chai_1.expect(file.getHover(vscode_languageserver_1.Position.create(1, 31))).not.to.exist;
|
|
1535
|
+
//hover over the `as `
|
|
1536
|
+
(0, chai_1.expect)(file.getHover(vscode_languageserver_1.Position.create(1, 31))).not.to.exist;
|
|
1345
1537
|
//hover over the `string`
|
|
1346
|
-
chai_1.expect(file.getHover(vscode_languageserver_1.Position.create(1, 36))).not.to.exist;
|
|
1538
|
+
(0, chai_1.expect)(file.getHover(vscode_languageserver_1.Position.create(1, 36))).not.to.exist;
|
|
1347
1539
|
});
|
|
1348
1540
|
it('finds declared function', () => {
|
|
1349
|
-
let file = program.
|
|
1541
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
1350
1542
|
function Main(count = 1)
|
|
1351
1543
|
firstName = "bob"
|
|
1352
1544
|
age = 21
|
|
@@ -1354,12 +1546,35 @@ describe('BrsFile', () => {
|
|
|
1354
1546
|
end function
|
|
1355
1547
|
`);
|
|
1356
1548
|
let hover = file.getHover(vscode_languageserver_1.Position.create(1, 28));
|
|
1357
|
-
chai_1.expect(hover).to.exist;
|
|
1358
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 29));
|
|
1359
|
-
chai_1.expect(hover.contents).to.equal(
|
|
1549
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1550
|
+
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 29));
|
|
1551
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1552
|
+
'```brightscript',
|
|
1553
|
+
'function Main(count? as integer) as dynamic',
|
|
1554
|
+
'```'
|
|
1555
|
+
].join('\n'));
|
|
1556
|
+
});
|
|
1557
|
+
it('finds declared namespace function', () => {
|
|
1558
|
+
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1559
|
+
namespace mySpace
|
|
1560
|
+
function Main(count = 1)
|
|
1561
|
+
firstName = "bob"
|
|
1562
|
+
age = 21
|
|
1563
|
+
shoeSize = 10
|
|
1564
|
+
end function
|
|
1565
|
+
end namespace
|
|
1566
|
+
`);
|
|
1567
|
+
let hover = file.getHover(vscode_languageserver_1.Position.create(2, 28));
|
|
1568
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1569
|
+
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 25, 2, 29));
|
|
1570
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1571
|
+
'```brightscript',
|
|
1572
|
+
'function Main(count? as integer) as dynamic',
|
|
1573
|
+
'```'
|
|
1574
|
+
].join('\n'));
|
|
1360
1575
|
});
|
|
1361
1576
|
it('finds variable function hover in same scope', () => {
|
|
1362
|
-
let file = program.
|
|
1577
|
+
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1363
1578
|
sub Main()
|
|
1364
1579
|
sayMyName = sub(name as string)
|
|
1365
1580
|
end sub
|
|
@@ -1368,11 +1583,39 @@ describe('BrsFile', () => {
|
|
|
1368
1583
|
end sub
|
|
1369
1584
|
`);
|
|
1370
1585
|
let hover = file.getHover(vscode_languageserver_1.Position.create(5, 24));
|
|
1371
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 29));
|
|
1372
|
-
chai_1.expect(hover.contents).to.equal(
|
|
1586
|
+
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 29));
|
|
1587
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1588
|
+
'```brightscript',
|
|
1589
|
+
'sub (name as string) as void',
|
|
1590
|
+
'```'
|
|
1591
|
+
].join('\n'));
|
|
1592
|
+
});
|
|
1593
|
+
it('does not crash when hovering on built-in functions', async () => {
|
|
1594
|
+
let file = program.setFile('source/main.brs', `
|
|
1595
|
+
function doUcase(text)
|
|
1596
|
+
return ucase(text)
|
|
1597
|
+
end function
|
|
1598
|
+
`);
|
|
1599
|
+
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 30))).contents).to.equal([
|
|
1600
|
+
'```brightscript',
|
|
1601
|
+
'function UCase(s as string) as string',
|
|
1602
|
+
'```'
|
|
1603
|
+
].join('\n'));
|
|
1604
|
+
});
|
|
1605
|
+
it('does not crash when hovering on object method call', async () => {
|
|
1606
|
+
let file = program.setFile('source/main.brs', `
|
|
1607
|
+
function getInstr(url, text)
|
|
1608
|
+
return url.instr(text)
|
|
1609
|
+
end function
|
|
1610
|
+
`);
|
|
1611
|
+
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 35))).contents).to.equal([
|
|
1612
|
+
'```brightscript',
|
|
1613
|
+
'instr as dynamic',
|
|
1614
|
+
'```'
|
|
1615
|
+
].join('\n'));
|
|
1373
1616
|
});
|
|
1374
1617
|
it('finds function hover in file scope', () => {
|
|
1375
|
-
let file = program.
|
|
1618
|
+
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1376
1619
|
sub Main()
|
|
1377
1620
|
sayMyName()
|
|
1378
1621
|
end sub
|
|
@@ -1382,82 +1625,177 @@ describe('BrsFile', () => {
|
|
|
1382
1625
|
end sub
|
|
1383
1626
|
`);
|
|
1384
1627
|
let hover = file.getHover(vscode_languageserver_1.Position.create(2, 25));
|
|
1385
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1386
|
-
chai_1.expect(hover.contents).to.equal(
|
|
1628
|
+
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1629
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1630
|
+
'```brightscript',
|
|
1631
|
+
'sub sayMyName() as void',
|
|
1632
|
+
'```'
|
|
1633
|
+
].join('\n'));
|
|
1634
|
+
});
|
|
1635
|
+
it('finds namespace function hover in file scope', () => {
|
|
1636
|
+
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1637
|
+
namespace mySpace
|
|
1638
|
+
sub Main()
|
|
1639
|
+
sayMyName()
|
|
1640
|
+
end sub
|
|
1641
|
+
|
|
1642
|
+
sub sayMyName()
|
|
1643
|
+
|
|
1644
|
+
end sub
|
|
1645
|
+
end namespace
|
|
1646
|
+
`);
|
|
1647
|
+
let hover = file.getHover(vscode_languageserver_1.Position.create(3, 25));
|
|
1648
|
+
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(3, 20, 3, 29));
|
|
1649
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1650
|
+
'```brightscript',
|
|
1651
|
+
'sub sayMyName() as void',
|
|
1652
|
+
'```'
|
|
1653
|
+
].join('\n'));
|
|
1387
1654
|
});
|
|
1388
1655
|
it('finds function hover in scope', () => {
|
|
1389
1656
|
let rootDir = process.cwd();
|
|
1390
1657
|
program = new Program_1.Program({
|
|
1391
1658
|
rootDir: rootDir
|
|
1392
1659
|
});
|
|
1393
|
-
let mainFile = program.
|
|
1660
|
+
let mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1394
1661
|
sub Main()
|
|
1395
1662
|
sayMyName()
|
|
1396
1663
|
end sub
|
|
1397
1664
|
`);
|
|
1398
|
-
program.
|
|
1665
|
+
program.setFile({ src: `${rootDir}/source/lib.brs`, dest: 'source/lib.brs' }, `
|
|
1399
1666
|
sub sayMyName(name as string)
|
|
1400
1667
|
|
|
1401
1668
|
end sub
|
|
1402
1669
|
`);
|
|
1403
1670
|
let hover = mainFile.getHover(vscode_languageserver_1.Position.create(2, 25));
|
|
1404
|
-
chai_1.expect(hover).to.exist;
|
|
1405
|
-
chai_1.expect(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1406
|
-
chai_1.expect(hover.contents).to.equal(
|
|
1671
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1672
|
+
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1673
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1674
|
+
'```brightscript',
|
|
1675
|
+
'sub sayMyName(name as string) as void',
|
|
1676
|
+
'```'
|
|
1677
|
+
].join('\n'));
|
|
1678
|
+
});
|
|
1679
|
+
it('finds namespace function hover in scope', () => {
|
|
1680
|
+
let rootDir = process.cwd();
|
|
1681
|
+
program = new Program_1.Program({
|
|
1682
|
+
rootDir: rootDir
|
|
1683
|
+
});
|
|
1684
|
+
let mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1685
|
+
sub Main()
|
|
1686
|
+
mySpace.sayMyName()
|
|
1687
|
+
end sub
|
|
1688
|
+
`);
|
|
1689
|
+
program.setFile({ src: `${rootDir}/source/lib.brs`, dest: 'source/lib.brs' }, `
|
|
1690
|
+
namespace mySpace
|
|
1691
|
+
sub sayMyName(name as string)
|
|
1692
|
+
end sub
|
|
1693
|
+
end namespace
|
|
1694
|
+
`);
|
|
1695
|
+
let hover = mainFile.getHover(vscode_languageserver_1.Position.create(2, 34));
|
|
1696
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1697
|
+
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 28, 2, 37));
|
|
1698
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1699
|
+
'```brightscript',
|
|
1700
|
+
'sub sayMyName(name as string) as void',
|
|
1701
|
+
'```'
|
|
1702
|
+
].join('\n'));
|
|
1703
|
+
});
|
|
1704
|
+
it('includes markdown comments in hover.', async () => {
|
|
1705
|
+
let rootDir = process.cwd();
|
|
1706
|
+
program = new Program_1.Program({
|
|
1707
|
+
rootDir: rootDir
|
|
1708
|
+
});
|
|
1709
|
+
const file = program.setFile('source/lib.brs', `
|
|
1710
|
+
'
|
|
1711
|
+
' The main function
|
|
1712
|
+
'
|
|
1713
|
+
sub main()
|
|
1714
|
+
log("hello")
|
|
1715
|
+
end sub
|
|
1716
|
+
|
|
1717
|
+
'
|
|
1718
|
+
' Prints a message to the log.
|
|
1719
|
+
' Works with *markdown* **content**
|
|
1720
|
+
'
|
|
1721
|
+
sub log(message as string)
|
|
1722
|
+
print message
|
|
1723
|
+
end sub
|
|
1724
|
+
`);
|
|
1725
|
+
//hover over log("hello")
|
|
1726
|
+
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(5, 22))).contents).to.equal([
|
|
1727
|
+
'```brightscript',
|
|
1728
|
+
'sub log(message as string) as void',
|
|
1729
|
+
'```',
|
|
1730
|
+
'***',
|
|
1731
|
+
'',
|
|
1732
|
+
' Prints a message to the log.',
|
|
1733
|
+
' Works with *markdown* **content**',
|
|
1734
|
+
''
|
|
1735
|
+
].join('\n'));
|
|
1736
|
+
//hover over sub ma|in()
|
|
1737
|
+
(0, chai_1.expect)((0, testHelpers_spec_1.trim)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(4, 22))).contents.toString())).to.equal((0, testHelpers_spec_1.trim) `
|
|
1738
|
+
\`\`\`brightscript
|
|
1739
|
+
sub main() as void
|
|
1740
|
+
\`\`\`
|
|
1741
|
+
***
|
|
1742
|
+
|
|
1743
|
+
The main function
|
|
1744
|
+
`);
|
|
1407
1745
|
});
|
|
1408
1746
|
it('handles mixed case `then` partions of conditionals', () => {
|
|
1409
|
-
let mainFile = program.
|
|
1747
|
+
let mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1410
1748
|
sub Main()
|
|
1411
1749
|
if true then
|
|
1412
1750
|
print "works"
|
|
1413
1751
|
end if
|
|
1414
1752
|
end sub
|
|
1415
1753
|
`);
|
|
1416
|
-
|
|
1417
|
-
mainFile = program.
|
|
1754
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1755
|
+
mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1418
1756
|
sub Main()
|
|
1419
1757
|
if true Then
|
|
1420
1758
|
print "works"
|
|
1421
1759
|
end if
|
|
1422
1760
|
end sub
|
|
1423
1761
|
`);
|
|
1424
|
-
|
|
1425
|
-
mainFile = program.
|
|
1762
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1763
|
+
mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1426
1764
|
sub Main()
|
|
1427
1765
|
if true THEN
|
|
1428
1766
|
print "works"
|
|
1429
1767
|
end if
|
|
1430
1768
|
end sub
|
|
1431
1769
|
`);
|
|
1432
|
-
|
|
1770
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1433
1771
|
});
|
|
1434
1772
|
it('displays the context from multiple scopes', () => {
|
|
1435
|
-
let commonFile = program.
|
|
1773
|
+
let commonFile = program.setFile('source/common.brs', `
|
|
1436
1774
|
sub displayPi()
|
|
1437
1775
|
pi = getPi()
|
|
1438
1776
|
print pi
|
|
1439
1777
|
end sub
|
|
1440
1778
|
`);
|
|
1441
|
-
let scope1File = program.
|
|
1779
|
+
let scope1File = program.setFile('components/comp1/scope1.brs', `
|
|
1442
1780
|
function getPi() as string
|
|
1443
1781
|
return "apple"
|
|
1444
1782
|
end function
|
|
1445
1783
|
`);
|
|
1446
|
-
chai_1.expect(scope1File.getDiagnostics()).to.be.lengthOf(0);
|
|
1447
|
-
program.
|
|
1784
|
+
(0, chai_1.expect)(scope1File.getDiagnostics()).to.be.lengthOf(0);
|
|
1785
|
+
program.setFile('components/comp1/comp1.xml', (0, testHelpers_spec_1.trim) `
|
|
1448
1786
|
<?xml version="1.0" encoding="utf-8" ?>
|
|
1449
1787
|
<component name="Component1" extends="Group">
|
|
1450
1788
|
<script type="text/brightscript" uri="scope1.brs" />
|
|
1451
1789
|
<script type="text/brightscript" uri="pkg:/source/common.brs" />
|
|
1452
1790
|
</component>
|
|
1453
1791
|
`);
|
|
1454
|
-
let scope2File = program.
|
|
1792
|
+
let scope2File = program.setFile('components/comp2/scope2.brs', `
|
|
1455
1793
|
function getPi() as float
|
|
1456
1794
|
return 3.14
|
|
1457
1795
|
end function
|
|
1458
1796
|
`);
|
|
1459
|
-
chai_1.expect(scope2File.getDiagnostics()).to.be.lengthOf(0);
|
|
1460
|
-
program.
|
|
1797
|
+
(0, chai_1.expect)(scope2File.getDiagnostics()).to.be.lengthOf(0);
|
|
1798
|
+
program.setFile('components/comp2/comp2.xml', (0, testHelpers_spec_1.trim) `
|
|
1461
1799
|
<?xml version="1.0" encoding="utf-8" ?>
|
|
1462
1800
|
<component name="Component2" extends="Group">
|
|
1463
1801
|
<script type="text/brightscript" uri="scope2.brs" />
|
|
@@ -1466,15 +1804,128 @@ describe('BrsFile', () => {
|
|
|
1466
1804
|
`);
|
|
1467
1805
|
program.validate();
|
|
1468
1806
|
let funcCallHover = commonFile.getHover(vscode_languageserver_1.Position.create(2, 27));
|
|
1469
|
-
chai_1.expect(funcCallHover).to.
|
|
1470
|
-
|
|
1807
|
+
(0, chai_1.expect)(funcCallHover === null || funcCallHover === void 0 ? void 0 : funcCallHover.contents).to.equal([
|
|
1808
|
+
'```brightscript',
|
|
1809
|
+
'function getPi() as string | function getPi() as float | getPi as uninitialized',
|
|
1810
|
+
'```'
|
|
1811
|
+
].join('\n'));
|
|
1471
1812
|
let variableHover = commonFile.getHover(vscode_languageserver_1.Position.create(3, 27));
|
|
1472
|
-
chai_1.expect(variableHover).to.
|
|
1473
|
-
|
|
1813
|
+
(0, chai_1.expect)(variableHover === null || variableHover === void 0 ? void 0 : variableHover.contents).to.equal([
|
|
1814
|
+
'```brightscript',
|
|
1815
|
+
'pi as string | pi as float | pi as uninitialized',
|
|
1816
|
+
'```'
|
|
1817
|
+
].join('\n'));
|
|
1818
|
+
});
|
|
1819
|
+
it('finds function with custom types as parameters and return types', () => {
|
|
1820
|
+
let file = program.setFile('source/main.bs', `
|
|
1821
|
+
sub main()
|
|
1822
|
+
k = new MyKlass()
|
|
1823
|
+
processMyKlass(k)
|
|
1824
|
+
end sub
|
|
1825
|
+
|
|
1826
|
+
function processMyKlass(data as MyKlass) as MyKlass
|
|
1827
|
+
return data
|
|
1828
|
+
end function
|
|
1829
|
+
|
|
1830
|
+
class MyKlass
|
|
1831
|
+
end class
|
|
1832
|
+
`);
|
|
1833
|
+
let hover = file.getHover(vscode_languageserver_1.Position.create(3, 29));
|
|
1834
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1835
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1836
|
+
'```brightscript',
|
|
1837
|
+
'function processMyKlass(data as MyKlass) as MyKlass',
|
|
1838
|
+
'```'
|
|
1839
|
+
].join('\n'));
|
|
1840
|
+
});
|
|
1841
|
+
it('finds function with arrays as parameters and return types', () => {
|
|
1842
|
+
let file = program.setFile('source/main.bs', `
|
|
1843
|
+
sub main()
|
|
1844
|
+
k = new MyKlass()
|
|
1845
|
+
processData([k])
|
|
1846
|
+
end sub
|
|
1847
|
+
|
|
1848
|
+
function processData(data as MyKlass[]) as MyKlass[]
|
|
1849
|
+
return data
|
|
1850
|
+
end function
|
|
1851
|
+
|
|
1852
|
+
class MyKlass
|
|
1853
|
+
end class
|
|
1854
|
+
`);
|
|
1855
|
+
let hover = file.getHover(vscode_languageserver_1.Position.create(3, 29));
|
|
1856
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1857
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1858
|
+
'```brightscript',
|
|
1859
|
+
'function processData(data as MyKlass[]) as MyKlass[]',
|
|
1860
|
+
'```'
|
|
1861
|
+
].join('\n'));
|
|
1862
|
+
});
|
|
1863
|
+
it('display literal enum members', () => {
|
|
1864
|
+
let file = program.setFile('source/main.bs', `
|
|
1865
|
+
enum MyEnum
|
|
1866
|
+
foo
|
|
1867
|
+
bar
|
|
1868
|
+
end enum
|
|
1869
|
+
|
|
1870
|
+
sub main()
|
|
1871
|
+
value = MyEnum.foo
|
|
1872
|
+
print value
|
|
1873
|
+
end sub
|
|
1874
|
+
`);
|
|
1875
|
+
let hover = file.getHover(vscode_languageserver_1.Position.create(7, 38)); // 'myEnum.foo' in value assignnmnt
|
|
1876
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1877
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1878
|
+
'```brightscript',
|
|
1879
|
+
'MyEnum.foo as MyEnum',
|
|
1880
|
+
'```'
|
|
1881
|
+
].join('\n'));
|
|
1882
|
+
});
|
|
1883
|
+
it('finds enum values from assignments', () => {
|
|
1884
|
+
let file = program.setFile('source/main.bs', `
|
|
1885
|
+
enum MyEnum
|
|
1886
|
+
foo
|
|
1887
|
+
bar
|
|
1888
|
+
end enum
|
|
1889
|
+
|
|
1890
|
+
sub main()
|
|
1891
|
+
value = MyEnum.foo
|
|
1892
|
+
print value
|
|
1893
|
+
end sub
|
|
1894
|
+
`);
|
|
1895
|
+
let hover = file.getHover(vscode_languageserver_1.Position.create(8, 30)); // 'value' in print statement
|
|
1896
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1897
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1898
|
+
'```brightscript',
|
|
1899
|
+
'value as MyEnum',
|
|
1900
|
+
'```'
|
|
1901
|
+
].join('\n'));
|
|
1902
|
+
});
|
|
1903
|
+
it('finds enum values as parameters', () => {
|
|
1904
|
+
let file = program.setFile('source/main.bs', `
|
|
1905
|
+
enum MyEnum
|
|
1906
|
+
foo
|
|
1907
|
+
bar
|
|
1908
|
+
end enum
|
|
1909
|
+
|
|
1910
|
+
sub printEnum(enumParamVal as MyEnum)
|
|
1911
|
+
print enumParamVal
|
|
1912
|
+
end sub
|
|
1913
|
+
|
|
1914
|
+
sub main()
|
|
1915
|
+
printEnum(MyEnum.foo)
|
|
1916
|
+
end sub
|
|
1917
|
+
`);
|
|
1918
|
+
let hover = file.getHover(vscode_languageserver_1.Position.create(7, 30)); // 'enumParamVal' in print statement
|
|
1919
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1920
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1921
|
+
'```brightscript',
|
|
1922
|
+
'enumParamVal as MyEnum',
|
|
1923
|
+
'```'
|
|
1924
|
+
].join('\n'));
|
|
1474
1925
|
});
|
|
1475
1926
|
});
|
|
1476
1927
|
it('does not throw when encountering incomplete import statement', () => {
|
|
1477
|
-
program.
|
|
1928
|
+
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1478
1929
|
import
|
|
1479
1930
|
sub main()
|
|
1480
1931
|
end sub
|
|
@@ -1483,6 +1934,135 @@ describe('BrsFile', () => {
|
|
|
1483
1934
|
//this test will throw an exception if something went wrong
|
|
1484
1935
|
});
|
|
1485
1936
|
describe('transpile', () => {
|
|
1937
|
+
it('excludes trailing commas in array literals', () => {
|
|
1938
|
+
testTranspile(`
|
|
1939
|
+
sub main()
|
|
1940
|
+
arr = [
|
|
1941
|
+
1,
|
|
1942
|
+
2,
|
|
1943
|
+
3
|
|
1944
|
+
]
|
|
1945
|
+
obj = {
|
|
1946
|
+
one: 1,
|
|
1947
|
+
two: 2,
|
|
1948
|
+
three: 3
|
|
1949
|
+
}
|
|
1950
|
+
end sub
|
|
1951
|
+
`, `
|
|
1952
|
+
sub main()
|
|
1953
|
+
arr = [
|
|
1954
|
+
1
|
|
1955
|
+
2
|
|
1956
|
+
3
|
|
1957
|
+
]
|
|
1958
|
+
obj = {
|
|
1959
|
+
one: 1
|
|
1960
|
+
two: 2
|
|
1961
|
+
three: 3
|
|
1962
|
+
}
|
|
1963
|
+
end sub
|
|
1964
|
+
`);
|
|
1965
|
+
});
|
|
1966
|
+
it('transpiles if statement keywords as provided', () => {
|
|
1967
|
+
const code = `
|
|
1968
|
+
If True Then
|
|
1969
|
+
Print True
|
|
1970
|
+
Else If True Then
|
|
1971
|
+
print True
|
|
1972
|
+
Else If False Then
|
|
1973
|
+
Print False
|
|
1974
|
+
Else
|
|
1975
|
+
Print False
|
|
1976
|
+
End If
|
|
1977
|
+
`;
|
|
1978
|
+
testTranspile(code);
|
|
1979
|
+
testTranspile(code.toLowerCase());
|
|
1980
|
+
testTranspile(code.toUpperCase());
|
|
1981
|
+
});
|
|
1982
|
+
it('does not transpile `then` tokens', () => {
|
|
1983
|
+
const code = `
|
|
1984
|
+
if true
|
|
1985
|
+
print true
|
|
1986
|
+
else if true
|
|
1987
|
+
print false
|
|
1988
|
+
end if
|
|
1989
|
+
`;
|
|
1990
|
+
testTranspile(code);
|
|
1991
|
+
});
|
|
1992
|
+
it('honors spacing between multi-word tokens', () => {
|
|
1993
|
+
testTranspile(`
|
|
1994
|
+
if true
|
|
1995
|
+
print true
|
|
1996
|
+
elseif true
|
|
1997
|
+
print false
|
|
1998
|
+
endif
|
|
1999
|
+
`);
|
|
2000
|
+
});
|
|
2001
|
+
it('handles when only some of the statements have `then`', () => {
|
|
2002
|
+
testTranspile(`
|
|
2003
|
+
if true
|
|
2004
|
+
else if true then
|
|
2005
|
+
else if true
|
|
2006
|
+
else if true then
|
|
2007
|
+
if true then
|
|
2008
|
+
return true
|
|
2009
|
+
end if
|
|
2010
|
+
end if
|
|
2011
|
+
`);
|
|
2012
|
+
});
|
|
2013
|
+
it('retains casing of parameter types', () => {
|
|
2014
|
+
function test(type) {
|
|
2015
|
+
testTranspile(`
|
|
2016
|
+
sub one(a as ${type}, b as ${type.toUpperCase()}, c as ${type.toLowerCase()})
|
|
2017
|
+
end sub
|
|
2018
|
+
`);
|
|
2019
|
+
}
|
|
2020
|
+
test('Boolean');
|
|
2021
|
+
test('Double');
|
|
2022
|
+
test('Dynamic');
|
|
2023
|
+
test('Float');
|
|
2024
|
+
test('Integer');
|
|
2025
|
+
test('LongInteger');
|
|
2026
|
+
test('Object');
|
|
2027
|
+
test('String');
|
|
2028
|
+
});
|
|
2029
|
+
it('retains casing of return types', () => {
|
|
2030
|
+
function test(type) {
|
|
2031
|
+
testTranspile(`
|
|
2032
|
+
sub one() as ${type}
|
|
2033
|
+
end sub
|
|
2034
|
+
|
|
2035
|
+
sub two() as ${type.toLowerCase()}
|
|
2036
|
+
end sub
|
|
2037
|
+
|
|
2038
|
+
sub three() as ${type.toUpperCase()}
|
|
2039
|
+
end sub
|
|
2040
|
+
`);
|
|
2041
|
+
}
|
|
2042
|
+
test('Boolean');
|
|
2043
|
+
test('Double');
|
|
2044
|
+
test('Dynamic');
|
|
2045
|
+
test('Float');
|
|
2046
|
+
test('Integer');
|
|
2047
|
+
test('LongInteger');
|
|
2048
|
+
test('Object');
|
|
2049
|
+
test('String');
|
|
2050
|
+
test('Void');
|
|
2051
|
+
});
|
|
2052
|
+
it('retains casing of literal types', () => {
|
|
2053
|
+
function test(type) {
|
|
2054
|
+
testTranspile(`
|
|
2055
|
+
sub main()
|
|
2056
|
+
thing = ${type}
|
|
2057
|
+
thing = ${type.toLowerCase()}
|
|
2058
|
+
thing = ${type.toUpperCase()}
|
|
2059
|
+
end sub
|
|
2060
|
+
`);
|
|
2061
|
+
}
|
|
2062
|
+
test('Invalid');
|
|
2063
|
+
test('True');
|
|
2064
|
+
test('False');
|
|
2065
|
+
});
|
|
1486
2066
|
describe('throwStatement', () => {
|
|
1487
2067
|
it('transpiles properly', () => {
|
|
1488
2068
|
testTranspile(`
|
|
@@ -1621,7 +2201,7 @@ describe('BrsFile', () => {
|
|
|
1621
2201
|
`, `
|
|
1622
2202
|
function Vertibrates_Birds_GetAllBirds()
|
|
1623
2203
|
return [
|
|
1624
|
-
Vertibrates_Birds_GetDuck()
|
|
2204
|
+
Vertibrates_Birds_GetDuck()
|
|
1625
2205
|
Vertibrates_Birds_GetGoose()
|
|
1626
2206
|
]
|
|
1627
2207
|
end function
|
|
@@ -1731,29 +2311,6 @@ describe('BrsFile', () => {
|
|
|
1731
2311
|
end sub
|
|
1732
2312
|
`, null, 'trim');
|
|
1733
2313
|
});
|
|
1734
|
-
it('adds `then` when missing', () => {
|
|
1735
|
-
testTranspile(`
|
|
1736
|
-
sub a()
|
|
1737
|
-
if true
|
|
1738
|
-
print "true"
|
|
1739
|
-
else if true
|
|
1740
|
-
print "true"
|
|
1741
|
-
else
|
|
1742
|
-
print "true"
|
|
1743
|
-
end if
|
|
1744
|
-
end sub
|
|
1745
|
-
`, `
|
|
1746
|
-
sub a()
|
|
1747
|
-
if true then
|
|
1748
|
-
print "true"
|
|
1749
|
-
else if true then
|
|
1750
|
-
print "true"
|
|
1751
|
-
else
|
|
1752
|
-
print "true"
|
|
1753
|
-
end if
|
|
1754
|
-
end sub
|
|
1755
|
-
`, 'trim');
|
|
1756
|
-
});
|
|
1757
2314
|
it('does not add leading or trailing newlines', () => {
|
|
1758
2315
|
testTranspile(`function abc()\nend function`, undefined, 'none');
|
|
1759
2316
|
});
|
|
@@ -1770,18 +2327,18 @@ describe('BrsFile', () => {
|
|
|
1770
2327
|
return consumer.generatedPositionFor({
|
|
1771
2328
|
line: 3,
|
|
1772
2329
|
column: 0,
|
|
1773
|
-
source: util_1.standardizePath `${rootDir}/source/main.bs`,
|
|
2330
|
+
source: (0, util_1.standardizePath) `${rootDir}/source/main.bs`,
|
|
1774
2331
|
bias: source_map_1.SourceMapConsumer.LEAST_UPPER_BOUND
|
|
1775
2332
|
});
|
|
1776
2333
|
});
|
|
1777
|
-
chai_1.expect(location.line).to.eql(2);
|
|
1778
|
-
chai_1.expect(location.column).eql(4);
|
|
2334
|
+
(0, chai_1.expect)(location.line).to.eql(2);
|
|
2335
|
+
(0, chai_1.expect)(location.column).eql(4);
|
|
1779
2336
|
});
|
|
1780
2337
|
it('computes correct locations for sourcemap', async () => {
|
|
1781
2338
|
let source = `function abc(name)\n firstName = name\nend function`;
|
|
1782
|
-
let tokens =
|
|
2339
|
+
let tokens = Lexer_1.Lexer.scan(source).tokens
|
|
1783
2340
|
//remove newlines and EOF
|
|
1784
|
-
.filter(x => x.kind !==
|
|
2341
|
+
.filter(x => x.kind !== TokenKind_1.TokenKind.Eof && x.kind !== TokenKind_1.TokenKind.Newline);
|
|
1785
2342
|
program.options.sourceMap = true;
|
|
1786
2343
|
let result = testTranspile(source, source, 'none');
|
|
1787
2344
|
//load the source map
|
|
@@ -1803,7 +2360,7 @@ describe('BrsFile', () => {
|
|
|
1803
2360
|
originalPosition.line - 1, originalPosition.column)
|
|
1804
2361
|
};
|
|
1805
2362
|
});
|
|
1806
|
-
chai_1.expect(sourcemapResult).to.eql(tokenResult);
|
|
2363
|
+
(0, chai_1.expect)(sourcemapResult).to.eql(tokenResult);
|
|
1807
2364
|
});
|
|
1808
2365
|
});
|
|
1809
2366
|
it('handles empty if block', () => {
|
|
@@ -1890,20 +2447,20 @@ describe('BrsFile', () => {
|
|
|
1890
2447
|
testTranspile(`
|
|
1891
2448
|
sub doSomething()
|
|
1892
2449
|
person = {
|
|
1893
|
-
age: 12
|
|
2450
|
+
age: 12 'comment
|
|
1894
2451
|
name: "child"
|
|
1895
2452
|
}
|
|
1896
2453
|
person = {
|
|
1897
|
-
age: 12
|
|
2454
|
+
age: 12 'comment
|
|
1898
2455
|
name: "child" 'comment
|
|
1899
2456
|
}
|
|
1900
2457
|
person = {
|
|
1901
|
-
age: 12
|
|
2458
|
+
age: 12 'comment
|
|
1902
2459
|
name: "child"
|
|
1903
2460
|
'comment
|
|
1904
2461
|
}
|
|
1905
2462
|
person = {
|
|
1906
|
-
age: 12
|
|
2463
|
+
age: 12 'comment
|
|
1907
2464
|
name: "child" 'comment
|
|
1908
2465
|
'comment
|
|
1909
2466
|
}
|
|
@@ -1918,8 +2475,8 @@ describe('BrsFile', () => {
|
|
|
1918
2475
|
'a function that does something
|
|
1919
2476
|
function doSomething(age as integer, name = "bob") 'comment
|
|
1920
2477
|
person = { 'comment
|
|
1921
|
-
name: "parent"
|
|
1922
|
-
"age": 12
|
|
2478
|
+
name: "parent" 'comment
|
|
2479
|
+
"age": 12
|
|
1923
2480
|
'comment as whole line
|
|
1924
2481
|
child: { 'comment
|
|
1925
2482
|
name: "child" 'comment
|
|
@@ -1955,8 +2512,8 @@ describe('BrsFile', () => {
|
|
|
1955
2512
|
stop 'comment
|
|
1956
2513
|
indexes = [ 'comment
|
|
1957
2514
|
'comment on its own line
|
|
1958
|
-
1
|
|
1959
|
-
2
|
|
2515
|
+
1 'comment
|
|
2516
|
+
2 'comment
|
|
1960
2517
|
3 'comment
|
|
1961
2518
|
] 'comment
|
|
1962
2519
|
firstIndex = indexes[0] 'comment
|
|
@@ -1997,25 +2554,25 @@ describe('BrsFile', () => {
|
|
|
1997
2554
|
`);
|
|
1998
2555
|
});
|
|
1999
2556
|
it('simple mapped files include a reference to the source map', () => {
|
|
2000
|
-
let file = program.
|
|
2557
|
+
let file = program.setFile('source/logger.brs', (0, testHelpers_spec_1.trim) `
|
|
2001
2558
|
sub logInfo()
|
|
2002
2559
|
end sub
|
|
2003
2560
|
`);
|
|
2004
2561
|
file.needsTranspiled = false;
|
|
2005
2562
|
const { code } = file.transpile();
|
|
2006
|
-
chai_1.expect(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
|
|
2563
|
+
(0, chai_1.expect)(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
|
|
2007
2564
|
});
|
|
2008
2565
|
it('AST generated files include a reference to the source map', () => {
|
|
2009
|
-
let file = program.
|
|
2566
|
+
let file = program.setFile('source/logger.brs', (0, testHelpers_spec_1.trim) `
|
|
2010
2567
|
sub logInfo()
|
|
2011
2568
|
end sub
|
|
2012
2569
|
`);
|
|
2013
2570
|
file.needsTranspiled = true;
|
|
2014
2571
|
const { code } = file.transpile();
|
|
2015
|
-
chai_1.expect(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
|
|
2572
|
+
(0, chai_1.expect)(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
|
|
2016
2573
|
});
|
|
2017
2574
|
it('replaces custom types in parameter types and return types', () => {
|
|
2018
|
-
program.
|
|
2575
|
+
program.setFile('source/SomeKlass.bs', `
|
|
2019
2576
|
class SomeKlass
|
|
2020
2577
|
end class
|
|
2021
2578
|
`);
|
|
@@ -2039,14 +2596,13 @@ describe('BrsFile', () => {
|
|
|
2039
2596
|
describe('callfunc operator', () => {
|
|
2040
2597
|
describe('transpile', () => {
|
|
2041
2598
|
it('does not produce diagnostics', () => {
|
|
2042
|
-
|
|
2043
|
-
program.addOrReplaceFile('source/main.bs', `
|
|
2599
|
+
program.setFile('source/main.bs', `
|
|
2044
2600
|
sub main()
|
|
2045
2601
|
someObject@.someFunction(paramObject.value)
|
|
2046
2602
|
end sub
|
|
2047
2603
|
`);
|
|
2048
2604
|
program.validate();
|
|
2049
|
-
|
|
2605
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2050
2606
|
});
|
|
2051
2607
|
it('sets invalid on empty callfunc', () => {
|
|
2052
2608
|
testTranspile(`
|
|
@@ -2086,116 +2642,116 @@ describe('BrsFile', () => {
|
|
|
2086
2642
|
name: 'transform callback',
|
|
2087
2643
|
afterFileParse: onParsed
|
|
2088
2644
|
});
|
|
2089
|
-
file = program.
|
|
2645
|
+
file = program.setFile({ src: `absolute_path/file${ext}`, dest: `relative_path/file${ext}` }, `
|
|
2090
2646
|
sub Sum()
|
|
2091
2647
|
print "hello world"
|
|
2092
2648
|
end sub
|
|
2093
2649
|
`);
|
|
2094
|
-
chai_1.expect(file.extension).to.equal(ext);
|
|
2650
|
+
(0, chai_1.expect)(file.extension).to.equal(ext);
|
|
2095
2651
|
return file;
|
|
2096
2652
|
}
|
|
2097
2653
|
it('called for BRS file', () => {
|
|
2098
2654
|
const onParsed = sinon.spy();
|
|
2099
2655
|
parseFileWithCallback('.brs', onParsed);
|
|
2100
|
-
chai_1.expect(onParsed.callCount).to.equal(1);
|
|
2656
|
+
(0, chai_1.expect)(onParsed.callCount).to.equal(1);
|
|
2101
2657
|
});
|
|
2102
2658
|
it('called for BS file', () => {
|
|
2103
2659
|
const onParsed = sinon.spy();
|
|
2104
2660
|
parseFileWithCallback('.bs', onParsed);
|
|
2105
|
-
chai_1.expect(onParsed.callCount).to.equal(1);
|
|
2661
|
+
(0, chai_1.expect)(onParsed.callCount).to.equal(1);
|
|
2106
2662
|
});
|
|
2107
2663
|
});
|
|
2108
2664
|
describe('typedefKey', () => {
|
|
2109
2665
|
it('works for .brs files', () => {
|
|
2110
|
-
chai_1.expect(util_1.standardizePath((program.
|
|
2666
|
+
(0, chai_1.expect)((0, util_1.standardizePath)((program.setFile('source/main.brs', '')).typedefSrcPath)).to.equal((0, util_1.standardizePath) `${rootDir.toLowerCase()}/source/main.d.bs`);
|
|
2111
2667
|
});
|
|
2112
2668
|
it('returns undefined for files that should not have a typedef', () => {
|
|
2113
|
-
chai_1.expect((program.
|
|
2114
|
-
chai_1.expect((program.
|
|
2115
|
-
const xmlFile = program.
|
|
2116
|
-
chai_1.expect(xmlFile.typedefSrcPath).to.be.undefined;
|
|
2669
|
+
(0, chai_1.expect)((program.setFile('source/main.bs', '')).typedefSrcPath).to.be.undefined;
|
|
2670
|
+
(0, chai_1.expect)((program.setFile('source/main.d.bs', '')).typedefSrcPath).to.be.undefined;
|
|
2671
|
+
const xmlFile = program.setFile('components/comp.xml', '');
|
|
2672
|
+
(0, chai_1.expect)(xmlFile.typedefSrcPath).to.be.undefined;
|
|
2117
2673
|
});
|
|
2118
2674
|
});
|
|
2119
2675
|
describe('type definitions', () => {
|
|
2120
2676
|
it('only exposes defined functions even if source has more', () => {
|
|
2121
2677
|
//parse the .brs file first so it doesn't know about the typedef
|
|
2122
|
-
program.
|
|
2678
|
+
program.setFile('source/main.brs', `
|
|
2123
2679
|
sub main()
|
|
2124
2680
|
end sub
|
|
2125
2681
|
sub speak()
|
|
2126
2682
|
end sub
|
|
2127
2683
|
`);
|
|
2128
|
-
program.
|
|
2684
|
+
program.setFile('source/main.d.bs', `
|
|
2129
2685
|
sub main()
|
|
2130
2686
|
end sub
|
|
2131
2687
|
`);
|
|
2132
2688
|
const sourceScope = program.getScopeByName('source');
|
|
2133
2689
|
const functionNames = sourceScope.getAllCallables().map(x => x.callable.name);
|
|
2134
|
-
chai_1.expect(functionNames).to.include('main');
|
|
2135
|
-
chai_1.expect(functionNames).not.to.include('speak');
|
|
2690
|
+
(0, chai_1.expect)(functionNames).to.include('main');
|
|
2691
|
+
(0, chai_1.expect)(functionNames).not.to.include('speak');
|
|
2136
2692
|
});
|
|
2137
2693
|
it('reacts to typedef file changes', () => {
|
|
2138
|
-
let file = program.
|
|
2694
|
+
let file = program.setFile('source/main.brs', `
|
|
2139
2695
|
sub main()
|
|
2140
2696
|
end sub
|
|
2141
2697
|
sub speak()
|
|
2142
2698
|
end sub
|
|
2143
2699
|
`);
|
|
2144
|
-
chai_1.expect(file.hasTypedef).to.be.false;
|
|
2145
|
-
chai_1.expect(file.typedefFile).not.to.exist;
|
|
2146
|
-
program.
|
|
2700
|
+
(0, chai_1.expect)(file.hasTypedef).to.be.false;
|
|
2701
|
+
(0, chai_1.expect)(file.typedefFile).not.to.exist;
|
|
2702
|
+
program.setFile('source/main.d.bs', `
|
|
2147
2703
|
sub main()
|
|
2148
2704
|
end sub
|
|
2149
2705
|
`);
|
|
2150
|
-
chai_1.expect(file.hasTypedef).to.be.true;
|
|
2151
|
-
chai_1.expect(file.typedefFile).to.exist;
|
|
2706
|
+
(0, chai_1.expect)(file.hasTypedef).to.be.true;
|
|
2707
|
+
(0, chai_1.expect)(file.typedefFile).to.exist;
|
|
2152
2708
|
//add replace file, does it still find the typedef
|
|
2153
|
-
file = program.
|
|
2709
|
+
file = program.setFile('source/main.brs', `
|
|
2154
2710
|
sub main()
|
|
2155
2711
|
end sub
|
|
2156
2712
|
sub speak()
|
|
2157
2713
|
end sub
|
|
2158
2714
|
`);
|
|
2159
|
-
chai_1.expect(file.hasTypedef).to.be.true;
|
|
2160
|
-
chai_1.expect(file.typedefFile).to.exist;
|
|
2161
|
-
program.removeFile(util_1.standardizePath `${rootDir}/source/main.d.bs`);
|
|
2162
|
-
chai_1.expect(file.hasTypedef).to.be.false;
|
|
2163
|
-
chai_1.expect(file.typedefFile).not.to.exist;
|
|
2715
|
+
(0, chai_1.expect)(file.hasTypedef).to.be.true;
|
|
2716
|
+
(0, chai_1.expect)(file.typedefFile).to.exist;
|
|
2717
|
+
program.removeFile((0, util_1.standardizePath) `${rootDir}/source/main.d.bs`);
|
|
2718
|
+
(0, chai_1.expect)(file.hasTypedef).to.be.false;
|
|
2719
|
+
(0, chai_1.expect)(file.typedefFile).not.to.exist;
|
|
2164
2720
|
});
|
|
2165
2721
|
});
|
|
2166
2722
|
describe('typedef', () => {
|
|
2167
2723
|
it('sets typedef path properly', () => {
|
|
2168
|
-
chai_1.expect((program.
|
|
2169
|
-
chai_1.expect((program.
|
|
2170
|
-
chai_1.expect((program.
|
|
2724
|
+
(0, chai_1.expect)((program.setFile('source/main1.brs', '')).typedefSrcPath).to.equal((0, util_1.standardizePath) `${rootDir}/source/main1.d.bs`.toLowerCase());
|
|
2725
|
+
(0, chai_1.expect)((program.setFile('source/main2.d.bs', '')).typedefSrcPath).to.equal(undefined);
|
|
2726
|
+
(0, chai_1.expect)((program.setFile('source/main3.bs', '')).typedefSrcPath).to.equal(undefined);
|
|
2171
2727
|
//works for dest with `.brs` extension
|
|
2172
|
-
chai_1.expect((program.
|
|
2728
|
+
(0, chai_1.expect)((program.setFile({ src: 'source/main4.bs', dest: 'source/main4.brs' }, '')).typedefSrcPath).to.equal(undefined);
|
|
2173
2729
|
});
|
|
2174
2730
|
it('does not link when missing from program', () => {
|
|
2175
|
-
const file = program.
|
|
2176
|
-
chai_1.expect(file.typedefFile).not.to.exist;
|
|
2731
|
+
const file = program.setFile('source/main.brs', ``);
|
|
2732
|
+
(0, chai_1.expect)(file.typedefFile).not.to.exist;
|
|
2177
2733
|
});
|
|
2178
2734
|
it('links typedef when added BEFORE .brs file', () => {
|
|
2179
|
-
const typedef = program.
|
|
2180
|
-
const file = program.
|
|
2181
|
-
chai_1.expect(file.typedefFile).to.equal(typedef);
|
|
2735
|
+
const typedef = program.setFile('source/main.d.bs', ``);
|
|
2736
|
+
const file = program.setFile('source/main.brs', ``);
|
|
2737
|
+
(0, chai_1.expect)(file.typedefFile).to.equal(typedef);
|
|
2182
2738
|
});
|
|
2183
2739
|
it('links typedef when added AFTER .brs file', () => {
|
|
2184
|
-
const file = program.
|
|
2185
|
-
const typedef = program.
|
|
2186
|
-
chai_1.expect(file.typedefFile).to.eql(typedef);
|
|
2740
|
+
const file = program.setFile('source/main.brs', ``);
|
|
2741
|
+
const typedef = program.setFile('source/main.d.bs', ``);
|
|
2742
|
+
(0, chai_1.expect)(file.typedefFile).to.eql(typedef);
|
|
2187
2743
|
});
|
|
2188
2744
|
it('removes typedef link when typedef is removed', () => {
|
|
2189
|
-
const typedef = program.
|
|
2190
|
-
const file = program.
|
|
2745
|
+
const typedef = program.setFile('source/main.d.bs', ``);
|
|
2746
|
+
const file = program.setFile('source/main.brs', ``);
|
|
2191
2747
|
program.removeFile(typedef.srcPath);
|
|
2192
|
-
chai_1.expect(file.typedefFile).to.be.undefined;
|
|
2748
|
+
(0, chai_1.expect)(file.typedefFile).to.be.undefined;
|
|
2193
2749
|
});
|
|
2194
2750
|
});
|
|
2195
2751
|
describe('getTypedef', () => {
|
|
2196
2752
|
function testTypedef(original, expected) {
|
|
2197
|
-
let file = program.
|
|
2198
|
-
chai_1.expect(file.getTypedef()).to.eql(expected);
|
|
2753
|
+
let file = program.setFile('source/main.brs', original);
|
|
2754
|
+
(0, chai_1.expect)(file.getTypedef().trimEnd()).to.eql(expected);
|
|
2199
2755
|
}
|
|
2200
2756
|
it('includes namespace on extend class names', () => {
|
|
2201
2757
|
testTypedef(`
|
|
@@ -2204,11 +2760,16 @@ describe('BrsFile', () => {
|
|
|
2204
2760
|
end class
|
|
2205
2761
|
class Duck extends Bird
|
|
2206
2762
|
end class
|
|
2207
|
-
end namespace
|
|
2763
|
+
end namespace
|
|
2764
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2208
2765
|
namespace AnimalKingdom
|
|
2209
2766
|
class Bird
|
|
2767
|
+
sub new()
|
|
2768
|
+
end sub
|
|
2210
2769
|
end class
|
|
2211
2770
|
class Duck extends AnimalKingdom.Bird
|
|
2771
|
+
sub new()
|
|
2772
|
+
end sub
|
|
2212
2773
|
end class
|
|
2213
2774
|
end namespace
|
|
2214
2775
|
`);
|
|
@@ -2218,7 +2779,7 @@ describe('BrsFile', () => {
|
|
|
2218
2779
|
sub main(param1 as string)
|
|
2219
2780
|
print "main"
|
|
2220
2781
|
end sub
|
|
2221
|
-
`, testHelpers_spec_1.trim `
|
|
2782
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2222
2783
|
sub main(param1 as string)
|
|
2223
2784
|
end sub
|
|
2224
2785
|
`);
|
|
@@ -2241,13 +2802,15 @@ describe('BrsFile', () => {
|
|
|
2241
2802
|
end function
|
|
2242
2803
|
end class
|
|
2243
2804
|
end namespace
|
|
2244
|
-
`, testHelpers_spec_1.trim `
|
|
2805
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2245
2806
|
namespace test
|
|
2246
2807
|
@an
|
|
2247
2808
|
@anFunc("value")
|
|
2248
2809
|
function getDuck()
|
|
2249
2810
|
end function
|
|
2250
2811
|
class Duck
|
|
2812
|
+
sub new()
|
|
2813
|
+
end sub
|
|
2251
2814
|
@anMember
|
|
2252
2815
|
@anMember("field")
|
|
2253
2816
|
private thing as dynamic
|
|
@@ -2262,7 +2825,7 @@ describe('BrsFile', () => {
|
|
|
2262
2825
|
it('includes import statements', () => {
|
|
2263
2826
|
testTypedef(`
|
|
2264
2827
|
import "pkg:/source/lib.brs"
|
|
2265
|
-
`, testHelpers_spec_1.trim `
|
|
2828
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2266
2829
|
import "pkg:/source/lib.brs"
|
|
2267
2830
|
`);
|
|
2268
2831
|
});
|
|
@@ -2276,7 +2839,7 @@ describe('BrsFile', () => {
|
|
|
2276
2839
|
sub logInfo()
|
|
2277
2840
|
end sub
|
|
2278
2841
|
end namespace
|
|
2279
|
-
`, testHelpers_spec_1.trim `
|
|
2842
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2280
2843
|
namespace Name
|
|
2281
2844
|
sub logInfo()
|
|
2282
2845
|
end sub
|
|
@@ -2305,8 +2868,10 @@ describe('BrsFile', () => {
|
|
|
2305
2868
|
end sub
|
|
2306
2869
|
end class
|
|
2307
2870
|
end namespace
|
|
2308
|
-
`, testHelpers_spec_1.trim `
|
|
2871
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2309
2872
|
class Person
|
|
2873
|
+
sub new()
|
|
2874
|
+
end sub
|
|
2310
2875
|
public name as string
|
|
2311
2876
|
public age as integer
|
|
2312
2877
|
public sub getAge() as integer
|
|
@@ -2314,6 +2879,8 @@ describe('BrsFile', () => {
|
|
|
2314
2879
|
end class
|
|
2315
2880
|
namespace NameA.NameB
|
|
2316
2881
|
class Person
|
|
2882
|
+
sub new()
|
|
2883
|
+
end sub
|
|
2317
2884
|
public name as string
|
|
2318
2885
|
public age as integer
|
|
2319
2886
|
public sub getAge() as integer
|
|
@@ -2322,14 +2889,27 @@ describe('BrsFile', () => {
|
|
|
2322
2889
|
end namespace
|
|
2323
2890
|
`);
|
|
2324
2891
|
});
|
|
2892
|
+
it('creates constructor properly', () => {
|
|
2893
|
+
testTypedef(`
|
|
2894
|
+
class Parent
|
|
2895
|
+
end class
|
|
2896
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2897
|
+
class Parent
|
|
2898
|
+
sub new()
|
|
2899
|
+
end sub
|
|
2900
|
+
end class
|
|
2901
|
+
`);
|
|
2902
|
+
});
|
|
2325
2903
|
it('sets properties to dynamic when initialized to invalid', () => {
|
|
2326
2904
|
testTypedef(`
|
|
2327
2905
|
class Human
|
|
2328
2906
|
public firstName = invalid
|
|
2329
2907
|
public lastName as string = invalid
|
|
2330
2908
|
end class
|
|
2331
|
-
`, testHelpers_spec_1.trim `
|
|
2909
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2332
2910
|
class Human
|
|
2911
|
+
sub new()
|
|
2912
|
+
end sub
|
|
2333
2913
|
public firstName as dynamic
|
|
2334
2914
|
public lastName as string
|
|
2335
2915
|
end class
|
|
@@ -2347,7 +2927,7 @@ describe('BrsFile', () => {
|
|
|
2347
2927
|
super(name)
|
|
2348
2928
|
end sub
|
|
2349
2929
|
end class
|
|
2350
|
-
`, testHelpers_spec_1.trim `
|
|
2930
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2351
2931
|
class Human
|
|
2352
2932
|
sub new(name as string)
|
|
2353
2933
|
end sub
|
|
@@ -2374,8 +2954,10 @@ describe('BrsFile', () => {
|
|
|
2374
2954
|
return m.lastName
|
|
2375
2955
|
end function
|
|
2376
2956
|
end class
|
|
2377
|
-
`, testHelpers_spec_1.trim `
|
|
2957
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2378
2958
|
class Human
|
|
2959
|
+
sub new()
|
|
2960
|
+
end sub
|
|
2379
2961
|
public firstName as string
|
|
2380
2962
|
protected middleName as string
|
|
2381
2963
|
private lastName as string
|
|
@@ -2400,12 +2982,16 @@ describe('BrsFile', () => {
|
|
|
2400
2982
|
print "Hello Dog"
|
|
2401
2983
|
end sub
|
|
2402
2984
|
end class
|
|
2403
|
-
`, testHelpers_spec_1.trim `
|
|
2985
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2404
2986
|
class Animal
|
|
2987
|
+
sub new()
|
|
2988
|
+
end sub
|
|
2405
2989
|
public sub speak()
|
|
2406
2990
|
end sub
|
|
2407
2991
|
end class
|
|
2408
2992
|
class Dog extends Animal
|
|
2993
|
+
sub new()
|
|
2994
|
+
end sub
|
|
2409
2995
|
public override sub speak()
|
|
2410
2996
|
end sub
|
|
2411
2997
|
end class
|
|
@@ -2427,7 +3013,7 @@ describe('BrsFile', () => {
|
|
|
2427
3013
|
end sub
|
|
2428
3014
|
end class
|
|
2429
3015
|
end namespace
|
|
2430
|
-
`, testHelpers_spec_1.trim `
|
|
3016
|
+
`, (0, testHelpers_spec_1.trim) `
|
|
2431
3017
|
namespace NameA
|
|
2432
3018
|
class Human
|
|
2433
3019
|
sub new(name as string)
|
|
@@ -2445,7 +3031,7 @@ describe('BrsFile', () => {
|
|
|
2445
3031
|
});
|
|
2446
3032
|
describe('parser getter', () => {
|
|
2447
3033
|
it('recreates the parser when missing', () => {
|
|
2448
|
-
const file = program.
|
|
3034
|
+
const file = program.setFile('source/main.brs', `
|
|
2449
3035
|
sub main()
|
|
2450
3036
|
end sub
|
|
2451
3037
|
`);
|
|
@@ -2454,71 +3040,274 @@ describe('BrsFile', () => {
|
|
|
2454
3040
|
file['_parser'] = undefined;
|
|
2455
3041
|
//force the file to get a new instance of parser
|
|
2456
3042
|
const newParser = file.parser;
|
|
2457
|
-
chai_1.expect(newParser).to.exist.and.to.not.equal(parser);
|
|
3043
|
+
(0, chai_1.expect)(newParser).to.exist.and.to.not.equal(parser);
|
|
2458
3044
|
//reference shouldn't change in subsequent accesses
|
|
2459
|
-
chai_1.expect(file.parser).to.equal(newParser);
|
|
3045
|
+
(0, chai_1.expect)(file.parser).to.equal(newParser);
|
|
2460
3046
|
});
|
|
2461
3047
|
it('call parse when previously skipped', () => {
|
|
2462
|
-
program.
|
|
3048
|
+
program.setFile('source/main.d.bs', `'typedef
|
|
2463
3049
|
sub main()
|
|
2464
3050
|
end sub
|
|
2465
3051
|
`);
|
|
2466
|
-
const file = program.
|
|
3052
|
+
const file = program.setFile('source/main.brs', `'source
|
|
2467
3053
|
sub main()
|
|
2468
3054
|
end sub
|
|
2469
3055
|
`);
|
|
2470
3056
|
//no functions should be found since the parser was skipped
|
|
2471
|
-
chai_1.expect(file['_parser']).to.not.exist;
|
|
3057
|
+
(0, chai_1.expect)(file['_parser']).to.not.exist;
|
|
2472
3058
|
const stub = sinon.stub(file, 'parse').callThrough();
|
|
2473
3059
|
//`file.parser` is a getter, so that should force the parse to occur
|
|
2474
|
-
chai_1.expect(file.parser.references.functionStatements).to.be.lengthOf(1);
|
|
2475
|
-
chai_1.expect(stub.called).to.be.true;
|
|
3060
|
+
(0, chai_1.expect)(file.parser.references.functionStatements).to.be.lengthOf(1);
|
|
3061
|
+
(0, chai_1.expect)(stub.called).to.be.true;
|
|
2476
3062
|
//parse should have been called
|
|
2477
3063
|
});
|
|
2478
3064
|
});
|
|
2479
3065
|
describe('Plugins', () => {
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
3066
|
+
let pluginFileName;
|
|
3067
|
+
let idx = 1;
|
|
3068
|
+
beforeEach(() => {
|
|
3069
|
+
pluginFileName = `plugin-${idx++}.js`;
|
|
3070
|
+
fsExtra.outputFileSync((0, util_1.standardizePath) `${tempDir}/plugins/${pluginFileName}`, `
|
|
3071
|
+
function plugin() {
|
|
3072
|
+
return {
|
|
3073
|
+
name: 'lower-file-name',
|
|
3074
|
+
afterFileParse: (evt) => {
|
|
3075
|
+
evt.file._customProp = true;
|
|
3076
|
+
}
|
|
3077
|
+
};
|
|
3078
|
+
}
|
|
3079
|
+
exports.default = plugin;
|
|
3080
|
+
`);
|
|
3081
|
+
});
|
|
3082
|
+
it('can load an absolute plugin which receives callbacks', () => {
|
|
3083
|
+
program.plugins = new PluginInterface_1.default(util_1.default.loadPlugins(tempDir, [
|
|
3084
|
+
(0, util_1.standardizePath) `${tempDir}/plugins/${pluginFileName}`
|
|
3085
|
+
]), new Logger_1.Logger());
|
|
3086
|
+
const file = program.setFile('source/MAIN.brs', '');
|
|
3087
|
+
(0, chai_1.expect)(file._customProp).to.exist;
|
|
3088
|
+
});
|
|
3089
|
+
it('can load a relative plugin which receives callbacks', () => {
|
|
3090
|
+
program.plugins = new PluginInterface_1.default(util_1.default.loadPlugins(tempDir, [
|
|
3091
|
+
`./plugins/${pluginFileName}`
|
|
3092
|
+
]), new Logger_1.Logger());
|
|
3093
|
+
const file = program.setFile('source/MAIN.brs', '');
|
|
3094
|
+
(0, chai_1.expect)(file._customProp).to.exist;
|
|
3095
|
+
});
|
|
3096
|
+
});
|
|
3097
|
+
describe('getSymbolTypeFromToken', () => {
|
|
3098
|
+
function checkSymbolLookups(file, funcExpr, lookups) {
|
|
3099
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
3100
|
+
mainScope.linkSymbolTable();
|
|
3101
|
+
for (const lookup of lookups) {
|
|
3102
|
+
const position = vscode_languageserver_1.Position.create(lookup.line, lookup.col);
|
|
3103
|
+
const token = file.parser.getTokenAt(position);
|
|
3104
|
+
const symbol = file.getSymbolTypeFromToken(token, funcExpr, mainScope);
|
|
3105
|
+
const context = {
|
|
3106
|
+
file: file,
|
|
3107
|
+
scope: mainScope,
|
|
3108
|
+
position: position
|
|
3109
|
+
};
|
|
3110
|
+
(0, chai_1.expect)(symbol.expandedTokenText).to.equal(lookup.name);
|
|
3111
|
+
(0, chai_1.expect)(symbol.type.equals(lookup.type, context)).be.true;
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
it('gets simple types based on the containing function expression', () => {
|
|
3115
|
+
const file = program.setFile('source/main.bs', `
|
|
3116
|
+
sub doSomething(aInt as integer, aFloat as float, aStr as string, aBool as boolean, aObj as object)
|
|
3117
|
+
print aInt
|
|
3118
|
+
print aFloat
|
|
3119
|
+
print aStr
|
|
3120
|
+
print aBool
|
|
3121
|
+
print aObj
|
|
3122
|
+
end sub
|
|
3123
|
+
`);
|
|
3124
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
3125
|
+
const lookups = [
|
|
3126
|
+
{ line: 2, col: 28, name: 'aInt', type: new IntegerType_1.IntegerType() },
|
|
3127
|
+
{ line: 3, col: 28, name: 'aFloat', type: new FloatType_1.FloatType() },
|
|
3128
|
+
{ line: 4, col: 28, name: 'aStr', type: new StringType_1.StringType() },
|
|
3129
|
+
{ line: 5, col: 28, name: 'aBool', type: new BooleanType_1.BooleanType() },
|
|
3130
|
+
{ line: 6, col: 28, name: 'aObj', type: new ObjectType_1.ObjectType() }
|
|
3131
|
+
];
|
|
3132
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
3133
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
3134
|
+
});
|
|
3135
|
+
it('gets custom types based on the containing function expression', () => {
|
|
3136
|
+
const file = program.setFile('source/main.bs', `
|
|
3137
|
+
sub doSomething(klass as MyKlass)
|
|
3138
|
+
print klass
|
|
2487
3139
|
end sub
|
|
2488
3140
|
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
3141
|
+
class MyKlass
|
|
3142
|
+
end class
|
|
3143
|
+
`);
|
|
3144
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
3145
|
+
mainScope.linkSymbolTable();
|
|
3146
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
3147
|
+
const token = file.parser.getTokenAt(vscode_languageserver_1.Position.create(2, 28));
|
|
3148
|
+
const symbol = file.getSymbolTypeFromToken(token, funcExpr, mainScope);
|
|
3149
|
+
(0, chai_1.expect)(symbol.expandedTokenText).to.equal('klass');
|
|
3150
|
+
const classStmt = file.parser.references.classStatements[0];
|
|
3151
|
+
(0, chai_1.expect)(classStmt.name.text).to.equal('MyKlass');
|
|
3152
|
+
(0, chai_1.expect)(symbol.type.isAssignableTo(classStmt.getThisBscType())).be.true;
|
|
3153
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
3154
|
+
});
|
|
3155
|
+
it('gets types of properties of a klass', () => {
|
|
3156
|
+
const file = program.setFile('source/main.bs', `
|
|
3157
|
+
sub doSomething()
|
|
3158
|
+
klass = new MyKlass()
|
|
3159
|
+
print klass.name
|
|
3160
|
+
print klass.age
|
|
3161
|
+
' verify case insensitivity
|
|
3162
|
+
print KLASS.NAME
|
|
3163
|
+
print klass.AGE
|
|
2492
3164
|
end sub
|
|
2493
|
-
`, `
|
|
2494
|
-
sub main()
|
|
2495
|
-
sayHello(sub()
|
|
2496
|
-
\n end sub)
|
|
2497
|
-
\n end sub
|
|
2498
3165
|
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
3166
|
+
class MyKlass
|
|
3167
|
+
name as string
|
|
3168
|
+
age as integer
|
|
3169
|
+
end class
|
|
2502
3170
|
`);
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
]
|
|
2508
|
-
|
|
3171
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
3172
|
+
const lookups = [
|
|
3173
|
+
{ line: 3, col: 35, name: 'MyKlass.name', type: new StringType_1.StringType() },
|
|
3174
|
+
{ line: 4, col: 35, name: 'MyKlass.age', type: new IntegerType_1.IntegerType() }
|
|
3175
|
+
];
|
|
3176
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
3177
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2509
3178
|
});
|
|
2510
|
-
it('
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
3179
|
+
it('gets types of properties of an object', () => {
|
|
3180
|
+
const file = program.setFile('source/main.bs', `
|
|
3181
|
+
sub doSomething()
|
|
3182
|
+
obj = { name: "Joe", age: 37}
|
|
3183
|
+
print obj.name
|
|
3184
|
+
print obj.age
|
|
3185
|
+
end sub
|
|
3186
|
+
`);
|
|
3187
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
3188
|
+
const lookups = [
|
|
3189
|
+
{ line: 3, col: 32, name: 'obj.name', type: new StringType_1.StringType() },
|
|
3190
|
+
{ line: 4, col: 32, name: 'obj.age', type: new IntegerType_1.IntegerType() }
|
|
3191
|
+
];
|
|
3192
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
3193
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2515
3194
|
});
|
|
2516
|
-
it('
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
3195
|
+
it('gets return types of functions', () => {
|
|
3196
|
+
const file = program.setFile('source/main.bs', `
|
|
3197
|
+
sub doSomething()
|
|
3198
|
+
pi = makeKlass().getSelf().getPi()
|
|
3199
|
+
print pi
|
|
3200
|
+
end sub
|
|
3201
|
+
|
|
3202
|
+
function makeKlass() as MyKlass
|
|
3203
|
+
return new MyKlass()
|
|
3204
|
+
end function
|
|
3205
|
+
|
|
3206
|
+
class MyKlass
|
|
3207
|
+
function getPi() as float
|
|
3208
|
+
return 3.14
|
|
3209
|
+
end function
|
|
3210
|
+
|
|
3211
|
+
function getSelf() as MyKlass
|
|
3212
|
+
return m
|
|
3213
|
+
end function
|
|
3214
|
+
end class
|
|
3215
|
+
`);
|
|
3216
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
3217
|
+
mainScope.linkSymbolTable();
|
|
3218
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
3219
|
+
const klassMemberTable = file.parser.references.classStatements[0].memberTable;
|
|
3220
|
+
const lookups = [
|
|
3221
|
+
{ line: 2, col: 31, name: 'makeKlass', type: file.parser.references.functionExpressions[1].getFunctionType() },
|
|
3222
|
+
// The expanded text for this should probably be MyKlass.getSelf()
|
|
3223
|
+
{ line: 2, col: 41, name: 'MyKlass.MyKlass', type: klassMemberTable.getSymbol('getSelf')[0].type },
|
|
3224
|
+
{ line: 2, col: 51, name: 'MyKlass.getPi', type: klassMemberTable.getSymbol('getPi')[0].type },
|
|
3225
|
+
{ line: 3, col: 28, name: 'pi', type: new FloatType_1.FloatType() }
|
|
3226
|
+
];
|
|
3227
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
3228
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
3229
|
+
});
|
|
3230
|
+
it('gets types of elements of arrays', () => {
|
|
3231
|
+
const file = program.setFile('source/main.bs', `
|
|
3232
|
+
sub doSomething(words as string[], klasses as MyKlass[])
|
|
3233
|
+
myWord = words[0]
|
|
3234
|
+
pi = klasses[0].getPi()
|
|
3235
|
+
print myWord
|
|
3236
|
+
print pi
|
|
3237
|
+
end sub
|
|
3238
|
+
|
|
3239
|
+
class MyKlass
|
|
3240
|
+
function getPi() as float
|
|
3241
|
+
return 3.14
|
|
3242
|
+
end function
|
|
3243
|
+
end class
|
|
3244
|
+
`);
|
|
3245
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
3246
|
+
mainScope.linkSymbolTable();
|
|
3247
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
3248
|
+
const klassMemberTable = file.parser.references.classStatements[0].memberTable;
|
|
3249
|
+
const lookups = [
|
|
3250
|
+
{ line: 2, col: 34, name: 'words', type: new ArrayType_1.ArrayType(new StringType_1.StringType()) },
|
|
3251
|
+
{ line: 3, col: 41, name: 'MyKlass.getPi', type: klassMemberTable.getSymbol('getPi')[0].type },
|
|
3252
|
+
{ line: 4, col: 28, name: 'myWord', type: new StringType_1.StringType() },
|
|
3253
|
+
{ line: 5, col: 28, name: 'pi', type: new FloatType_1.FloatType() }
|
|
3254
|
+
];
|
|
3255
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
3256
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
3257
|
+
});
|
|
3258
|
+
it('gets types of elements of arrays via square bracket reference', () => {
|
|
3259
|
+
const file = program.setFile('source/main.bs', `
|
|
3260
|
+
function printFirst(numbers as float[]) as float
|
|
3261
|
+
firstFloat = numbers[0]
|
|
3262
|
+
print firstFloat
|
|
3263
|
+
return firstFloat
|
|
3264
|
+
end function
|
|
3265
|
+
`);
|
|
3266
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
3267
|
+
mainScope.linkSymbolTable();
|
|
3268
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
3269
|
+
const lookups = [
|
|
3270
|
+
{ line: 2, col: 26, name: 'firstFloat', type: new FloatType_1.FloatType() },
|
|
3271
|
+
{ line: 3, col: 32, name: 'firstFloat', type: new FloatType_1.FloatType() }
|
|
3272
|
+
];
|
|
3273
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
3274
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
3275
|
+
});
|
|
3276
|
+
it('gets types of elements of arrays after for each', () => {
|
|
3277
|
+
const file = program.setFile('source/main.bs', `
|
|
3278
|
+
function printAllReturnFirst(numbers as float[]) as float
|
|
3279
|
+
for each num in numbers
|
|
3280
|
+
print num
|
|
3281
|
+
end for
|
|
3282
|
+
|
|
3283
|
+
firstFloat = numbers[0]
|
|
3284
|
+
print firstFloat
|
|
3285
|
+
return firstFloat
|
|
3286
|
+
end function
|
|
3287
|
+
`);
|
|
3288
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
3289
|
+
mainScope.linkSymbolTable();
|
|
3290
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
3291
|
+
const lookups = [
|
|
3292
|
+
{ line: 6, col: 26, name: 'firstFloat', type: new FloatType_1.FloatType() },
|
|
3293
|
+
{ line: 7, col: 32, name: 'firstFloat', type: new FloatType_1.FloatType() }
|
|
3294
|
+
];
|
|
3295
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
3296
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2521
3297
|
});
|
|
2522
3298
|
});
|
|
3299
|
+
it('defaults to `dynamic` type for a complex expression', () => {
|
|
3300
|
+
const file = program.setFile('source/main.brs', `
|
|
3301
|
+
sub main()
|
|
3302
|
+
name = "cat"
|
|
3303
|
+
thing = m["key"](true)
|
|
3304
|
+
end sub
|
|
3305
|
+
`);
|
|
3306
|
+
program.validate();
|
|
3307
|
+
//sanity check
|
|
3308
|
+
(0, chai_1.expect)(file.parser.references.assignmentStatements[0].containingFunction.symbolTable.getSymbolType('name')).be.instanceof(StringType_1.StringType);
|
|
3309
|
+
//this complex expression should resolve to dynamic type when not known
|
|
3310
|
+
(0, chai_1.expect)(file.parser.references.assignmentStatements[0].containingFunction.symbolTable.getSymbolType('thing')).be.instanceof(DynamicType_1.DynamicType);
|
|
3311
|
+
});
|
|
2523
3312
|
});
|
|
2524
3313
|
//# sourceMappingURL=BrsFile.spec.js.map
|