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
package/dist/Scope.js
CHANGED
|
@@ -5,7 +5,7 @@ const vscode_languageserver_1 = require("vscode-languageserver");
|
|
|
5
5
|
const chalk_1 = require("chalk");
|
|
6
6
|
const DiagnosticMessages_1 = require("./DiagnosticMessages");
|
|
7
7
|
const ClassValidator_1 = require("./validators/ClassValidator");
|
|
8
|
-
const
|
|
8
|
+
const Parser_1 = require("./parser/Parser");
|
|
9
9
|
const util_1 = require("./util");
|
|
10
10
|
const globalCallables_1 = require("./globalCallables");
|
|
11
11
|
const Cache_1 = require("./Cache");
|
|
@@ -13,6 +13,10 @@ const vscode_uri_1 = require("vscode-uri");
|
|
|
13
13
|
const Logger_1 = require("./Logger");
|
|
14
14
|
const reflection_1 = require("./astUtils/reflection");
|
|
15
15
|
const SymbolTable_1 = require("./SymbolTable");
|
|
16
|
+
const BscType_1 = require("./types/BscType");
|
|
17
|
+
const DynamicType_1 = require("./types/DynamicType");
|
|
18
|
+
const ObjectType_1 = require("./types/ObjectType");
|
|
19
|
+
const UninitializedType_1 = require("./types/UninitializedType");
|
|
16
20
|
/**
|
|
17
21
|
* A class to keep track of all declarations within a given scope (like source scope, component scope)
|
|
18
22
|
*/
|
|
@@ -50,6 +54,41 @@ class Scope {
|
|
|
50
54
|
var _a;
|
|
51
55
|
return (_a = this.getClassFileLink(className, containingNamespace)) === null || _a === void 0 ? void 0 : _a.item;
|
|
52
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the interface with the specified name.
|
|
59
|
+
* @param ifaceName - The interface name, including the namespace of the interface if possible
|
|
60
|
+
* @param containingNamespace - The namespace used to resolve relative interface names. (i.e. the namespace around the current statement trying to find a interface)
|
|
61
|
+
*/
|
|
62
|
+
getInterface(ifaceName, containingNamespace) {
|
|
63
|
+
var _a;
|
|
64
|
+
return (_a = this.getInterfaceFileLink(ifaceName, containingNamespace)) === null || _a === void 0 ? void 0 : _a.item;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get either the class or interface, etc. with a given name
|
|
68
|
+
* @param name - The name, including the namespace of the interface if possible
|
|
69
|
+
* @param containingNamespace - The namespace used to resolve relative names. (i.e. the namespace around the current statement trying to find the interface or class)
|
|
70
|
+
*/
|
|
71
|
+
getNamedTypeStatement(name, containingNamespace) {
|
|
72
|
+
var _a;
|
|
73
|
+
return (_a = this.getNamedTypeFileLink(name, containingNamespace)) === null || _a === void 0 ? void 0 : _a.item;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A cache of a map of tokens -> TokenSymbolLookups, which are the result of getSymbolTypeFromToken()
|
|
77
|
+
* Sometimes the lookup of symbols may take a while if there are lazyTypes or multiple tokens in a chain
|
|
78
|
+
* By caching the result of this lookup, subsequent lookups of the same tokens are quicker
|
|
79
|
+
*/
|
|
80
|
+
get symbolCache() {
|
|
81
|
+
return this.cache.getOrAdd('symbolCache', () => new Map());
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get the enum with the specified name.
|
|
85
|
+
* @param enumName - The enum name, including the namespace if possible
|
|
86
|
+
* @param containingNamespace - The namespace used to resolve relative enum names. (i.e. the namespace around the current statement trying to find an enum)
|
|
87
|
+
*/
|
|
88
|
+
getEnum(enumName, containingNamespace) {
|
|
89
|
+
var _a;
|
|
90
|
+
return (_a = this.getEnumFileLink(enumName, containingNamespace)) === null || _a === void 0 ? void 0 : _a.item;
|
|
91
|
+
}
|
|
53
92
|
/**
|
|
54
93
|
* Get a class and its containing file by the class name
|
|
55
94
|
* @param className - The class name, including the namespace of the class if possible
|
|
@@ -66,13 +105,125 @@ class Scope {
|
|
|
66
105
|
return cls;
|
|
67
106
|
}
|
|
68
107
|
/**
|
|
108
|
+
* Get an interface and its containing file by the interface name
|
|
109
|
+
* @param ifaceName - The interface name, including the namespace of the interface if possible
|
|
110
|
+
* @param containingNamespace - The namespace used to resolve relative interface names. (i.e. the namespace around the current statement trying to find a interface)
|
|
111
|
+
*/
|
|
112
|
+
getInterfaceFileLink(ifaceName, containingNamespace) {
|
|
113
|
+
const lowerName = ifaceName === null || ifaceName === void 0 ? void 0 : ifaceName.toLowerCase();
|
|
114
|
+
const ifaceMap = this.getInterfaceMap();
|
|
115
|
+
let iface = ifaceMap.get(util_1.util.getFullyQualifiedClassName(lowerName, containingNamespace === null || containingNamespace === void 0 ? void 0 : containingNamespace.toLowerCase()));
|
|
116
|
+
//if we couldn't find the iface by its full namespaced name, look for a global class with that name
|
|
117
|
+
if (!iface) {
|
|
118
|
+
iface = ifaceMap.get(lowerName);
|
|
119
|
+
}
|
|
120
|
+
return iface;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get an Enum and its containing file by the Enum name
|
|
124
|
+
* @param enumName - The Enum name, including the namespace of the enum if possible
|
|
125
|
+
* @param containingNamespace - The namespace used to resolve relative enum names. (i.e. the namespace around the current statement trying to find a enum)
|
|
126
|
+
*/
|
|
127
|
+
getEnumFileLink(enumName, containingNamespace) {
|
|
128
|
+
const lowerName = enumName === null || enumName === void 0 ? void 0 : enumName.toLowerCase();
|
|
129
|
+
const enumMap = this.getEnumMap();
|
|
130
|
+
let enumeration = enumMap.get(util_1.util.getFullyQualifiedClassName(lowerName, containingNamespace === null || containingNamespace === void 0 ? void 0 : containingNamespace.toLowerCase()));
|
|
131
|
+
//if we couldn't find the enum by its full namespaced name, look for a global enum with that name
|
|
132
|
+
if (!enumeration) {
|
|
133
|
+
enumeration = enumMap.get(lowerName);
|
|
134
|
+
}
|
|
135
|
+
return enumeration;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get a Named Type (e.g. Class, Interface, Enum) and its containing file by the name
|
|
139
|
+
* @param name - The name of the type, including the namespace of the class/interface/enum, etc. if possible
|
|
140
|
+
* @param containingNamespace - The namespace used to resolve relative names. (i.e. the namespace around the current statement trying to find a class)
|
|
141
|
+
*/
|
|
142
|
+
getNamedTypeFileLink(name, containingNamespace) {
|
|
143
|
+
return this.getInheritableFileLink(name, containingNamespace) || this.getEnumFileLink(name, containingNamespace);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get a InheritableStatement and its containing file by the name of the interface or class
|
|
147
|
+
* @param name - The name of the interface or class, including the namespace of the class if possible
|
|
148
|
+
* @param containingNamespace - The namespace used to resolve relative names. (i.e. the namespace around the current statement trying to find a class)
|
|
149
|
+
*/
|
|
150
|
+
getInheritableFileLink(name, containingNamespace) {
|
|
151
|
+
return this.getClassFileLink(name, containingNamespace) || this.getInterfaceFileLink(name, containingNamespace);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Gets the parent class of the given class
|
|
155
|
+
* @param klass - The class to get the parent of, if possible
|
|
156
|
+
*/
|
|
157
|
+
getParentClass(klass) {
|
|
158
|
+
if (klass === null || klass === void 0 ? void 0 : klass.hasParent()) {
|
|
159
|
+
const lowerParentClassNames = klass.getPossibleFullParentNames().map(name => name.toLowerCase());
|
|
160
|
+
for (const lowerParentClassName of lowerParentClassNames) {
|
|
161
|
+
const foundParent = this.getClassMap().get(lowerParentClassName);
|
|
162
|
+
if (foundParent) {
|
|
163
|
+
return foundParent.item;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Gets the parent interface of the given interface
|
|
170
|
+
* @param iface - The interface to get the parent of, if possible
|
|
171
|
+
*/
|
|
172
|
+
getParentInterface(iface) {
|
|
173
|
+
if (iface === null || iface === void 0 ? void 0 : iface.hasParent()) {
|
|
174
|
+
const lowerParentClassNames = iface.getPossibleFullParentNames().map(name => name.toLowerCase());
|
|
175
|
+
for (const lowerParentClassName of lowerParentClassNames) {
|
|
176
|
+
const foundParent = this.getInterfaceMap().get(lowerParentClassName);
|
|
177
|
+
if (foundParent) {
|
|
178
|
+
return foundParent.item;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Gets the parent of an Interface or Class
|
|
185
|
+
* @param stmt - The class or interface to get the parent of, if possible
|
|
186
|
+
*/
|
|
187
|
+
getParentStatement(stmt) {
|
|
188
|
+
if ((0, reflection_1.isInterfaceStatement)(stmt)) {
|
|
189
|
+
return this.getParentInterface(stmt);
|
|
190
|
+
}
|
|
191
|
+
else if ((0, reflection_1.isClassStatement)(stmt)) {
|
|
192
|
+
return this.getParentClass(stmt);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
69
196
|
* Tests if a class exists with the specified name
|
|
70
197
|
* @param className - the all-lower-case namespace-included class name
|
|
71
|
-
* @param namespaceName -
|
|
198
|
+
* @param namespaceName - the current namespace name
|
|
72
199
|
*/
|
|
73
200
|
hasClass(className, namespaceName) {
|
|
74
201
|
return !!this.getClass(className, namespaceName);
|
|
75
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Tests if an interface exists with the specified name
|
|
205
|
+
* @param ifaceName - the all-lower-case namespace-included interface name
|
|
206
|
+
* @param namespaceName - the current namespace name
|
|
207
|
+
*/
|
|
208
|
+
hasInterface(ifaceName, namespaceName) {
|
|
209
|
+
return !!this.getInterface(ifaceName, namespaceName);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Tests if an enum exists with the specified name
|
|
213
|
+
* @param enumName - the all-lower-case namespace-included enum name
|
|
214
|
+
* @param namespaceName - the current namespace name
|
|
215
|
+
*/
|
|
216
|
+
hasEnum(enumName, namespaceName) {
|
|
217
|
+
return !!this.getEnum(enumName, namespaceName);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Tests if a class OR an interface, etc. exists with the specified name
|
|
221
|
+
* @param name - the all-lower-case namespace-included class or interface name
|
|
222
|
+
* @param namespaceName - the current namespace name
|
|
223
|
+
*/
|
|
224
|
+
hasNamedType(name, namespaceName) {
|
|
225
|
+
return !!this.getNamedTypeStatement(name, namespaceName);
|
|
226
|
+
}
|
|
76
227
|
/**
|
|
77
228
|
* A dictionary of all classes in this scope. This includes namespaced classes always with their full name.
|
|
78
229
|
* The key is stored in lower case
|
|
@@ -82,9 +233,9 @@ class Scope {
|
|
|
82
233
|
const map = new Map();
|
|
83
234
|
this.enumerateBrsFiles((file) => {
|
|
84
235
|
var _a;
|
|
85
|
-
if (reflection_1.isBrsFile(file)) {
|
|
236
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
86
237
|
for (let cls of file.parser.references.classStatements) {
|
|
87
|
-
const lowerClassName = (_a = cls.getName(
|
|
238
|
+
const lowerClassName = (_a = cls.getName(Parser_1.ParseMode.BrighterScript)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
88
239
|
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
89
240
|
if (lowerClassName) {
|
|
90
241
|
map.set(lowerClassName, { item: cls, file: file });
|
|
@@ -95,6 +246,70 @@ class Scope {
|
|
|
95
246
|
return map;
|
|
96
247
|
});
|
|
97
248
|
}
|
|
249
|
+
getAncestorTypeListByContext(thisType, context) {
|
|
250
|
+
var _a;
|
|
251
|
+
const funcExpr = (_a = context === null || context === void 0 ? void 0 : context.file) === null || _a === void 0 ? void 0 : _a.getFunctionExpressionAtPosition(context === null || context === void 0 ? void 0 : context.position);
|
|
252
|
+
if ((0, reflection_1.isCustomType)(thisType) || (0, reflection_1.isInterfaceType)(thisType)) {
|
|
253
|
+
return this.getAncestorTypeList(thisType.name, funcExpr);
|
|
254
|
+
}
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* A dictionary of all Interfaces in this scope. This includes namespaced Interfaces always with their full name.
|
|
259
|
+
* The key is stored in lower case
|
|
260
|
+
*/
|
|
261
|
+
getInterfaceMap() {
|
|
262
|
+
return this.cache.getOrAdd('interfaceMap', () => {
|
|
263
|
+
const map = new Map();
|
|
264
|
+
this.enumerateBrsFiles((file) => {
|
|
265
|
+
var _a;
|
|
266
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
267
|
+
for (let iface of file.parser.references.interfaceStatements) {
|
|
268
|
+
const lowerIfaceName = (_a = iface.getName(Parser_1.ParseMode.BrighterScript)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
269
|
+
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
270
|
+
if (lowerIfaceName) {
|
|
271
|
+
map.set(lowerIfaceName, { item: iface, file: file });
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
return map;
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
getAncestorTypeList(className, functionExpression) {
|
|
280
|
+
var _a, _b;
|
|
281
|
+
const lowerNamespaceName = (_a = functionExpression.namespaceName) === null || _a === void 0 ? void 0 : _a.getName().toLowerCase();
|
|
282
|
+
const ancestors = [];
|
|
283
|
+
let currentClassOrIFace = (_b = this.getInheritableFileLink(className, lowerNamespaceName)) === null || _b === void 0 ? void 0 : _b.item;
|
|
284
|
+
if (currentClassOrIFace) {
|
|
285
|
+
ancestors.push(currentClassOrIFace === null || currentClassOrIFace === void 0 ? void 0 : currentClassOrIFace.getThisBscType());
|
|
286
|
+
}
|
|
287
|
+
while (currentClassOrIFace === null || currentClassOrIFace === void 0 ? void 0 : currentClassOrIFace.hasParent()) {
|
|
288
|
+
currentClassOrIFace = this.getParentStatement(currentClassOrIFace);
|
|
289
|
+
ancestors.push(currentClassOrIFace === null || currentClassOrIFace === void 0 ? void 0 : currentClassOrIFace.getThisBscType());
|
|
290
|
+
}
|
|
291
|
+
// TODO TYPES: this should probably be cached
|
|
292
|
+
return ancestors;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* A dictionary of all enums in this scope. This includes namespaced enums always with their full name.
|
|
296
|
+
* The key is stored in lower case
|
|
297
|
+
*/
|
|
298
|
+
getEnumMap() {
|
|
299
|
+
return this.cache.getOrAdd('enumMap', () => {
|
|
300
|
+
const map = new Map();
|
|
301
|
+
this.enumerateBrsFiles((file) => {
|
|
302
|
+
for (let enumStmt of file.parser.references.enumStatements) {
|
|
303
|
+
const lowerEnumName = enumStmt.fullName.toLowerCase();
|
|
304
|
+
//only track enums with a defined name (i.e. exclude nameless malformed enums)
|
|
305
|
+
if (lowerEnumName) {
|
|
306
|
+
map.set(lowerEnumName, { item: enumStmt, file: file });
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
return map;
|
|
311
|
+
});
|
|
312
|
+
}
|
|
98
313
|
onDependenciesChanged(event) {
|
|
99
314
|
this.logDebug('invalidated because dependency graph said [', event.sourceKey, '] changed');
|
|
100
315
|
this.invalidate();
|
|
@@ -129,7 +344,7 @@ class Scope {
|
|
|
129
344
|
*/
|
|
130
345
|
getParentScope() {
|
|
131
346
|
let scope;
|
|
132
|
-
//use the global scope if we didn't find a
|
|
347
|
+
//use the global scope if we didn't find a scope and this is not the global scope
|
|
133
348
|
if (this.program.globalScope !== this) {
|
|
134
349
|
scope = this.program.globalScope;
|
|
135
350
|
}
|
|
@@ -158,7 +373,7 @@ class Scope {
|
|
|
158
373
|
*/
|
|
159
374
|
getFile(srcPath, normalizePath = true) {
|
|
160
375
|
if (normalizePath) {
|
|
161
|
-
srcPath = util_1.standardizePath `${srcPath}`;
|
|
376
|
+
srcPath = (0, util_1.standardizePath) `${srcPath}`;
|
|
162
377
|
}
|
|
163
378
|
let files = this.getAllFiles();
|
|
164
379
|
for (let file of files) {
|
|
@@ -241,14 +456,25 @@ class Scope {
|
|
|
241
456
|
* @param name
|
|
242
457
|
*/
|
|
243
458
|
getCallableByName(name) {
|
|
459
|
+
var _a;
|
|
244
460
|
let lowerName = name.toLowerCase();
|
|
245
461
|
let callables = this.getAllCallables();
|
|
246
462
|
for (let callable of callables) {
|
|
247
|
-
|
|
463
|
+
const callableName = callable.callable.getName(Parser_1.ParseMode.BrighterScript);
|
|
464
|
+
// Split by `.` and check the last term to consider namespaces.
|
|
465
|
+
if (callableName.toLowerCase() === lowerName || ((_a = callableName.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === lowerName) {
|
|
248
466
|
return callable.callable;
|
|
249
467
|
}
|
|
250
468
|
}
|
|
251
469
|
}
|
|
470
|
+
/**
|
|
471
|
+
* Get the global callable with the specified name.
|
|
472
|
+
* If there are overridden callables with the same name, the closest callable to this scope is returned
|
|
473
|
+
* @param name
|
|
474
|
+
*/
|
|
475
|
+
getGlobalCallableByName(name) {
|
|
476
|
+
return globalCallables_1.globalCallableMap.get(name.toLowerCase());
|
|
477
|
+
}
|
|
252
478
|
/**
|
|
253
479
|
* Iterate over Brs files not shadowed by typedefs
|
|
254
480
|
*/
|
|
@@ -256,7 +482,7 @@ class Scope {
|
|
|
256
482
|
const files = this.getAllFiles();
|
|
257
483
|
for (const file of files) {
|
|
258
484
|
//only brs files without a typedef
|
|
259
|
-
if (reflection_1.isBrsFile(file) && !file.hasTypedef) {
|
|
485
|
+
if ((0, reflection_1.isBrsFile)(file) && !file.hasTypedef) {
|
|
260
486
|
callback(file);
|
|
261
487
|
}
|
|
262
488
|
}
|
|
@@ -268,7 +494,7 @@ class Scope {
|
|
|
268
494
|
const files = this.getOwnFiles();
|
|
269
495
|
for (const file of files) {
|
|
270
496
|
//either XML components or files without a typedef
|
|
271
|
-
if (reflection_1.isXmlFile(file) || !file.hasTypedef) {
|
|
497
|
+
if ((0, reflection_1.isXmlFile)(file) || !file.hasTypedef) {
|
|
272
498
|
callback(file);
|
|
273
499
|
}
|
|
274
500
|
}
|
|
@@ -295,12 +521,11 @@ class Scope {
|
|
|
295
521
|
* Builds a tree of namespace objects
|
|
296
522
|
*/
|
|
297
523
|
buildNamespaceLookup() {
|
|
298
|
-
let namespaceLookup =
|
|
524
|
+
let namespaceLookup = new Map();
|
|
299
525
|
this.enumerateBrsFiles((file) => {
|
|
300
|
-
var _a;
|
|
301
526
|
for (let namespace of file.parser.references.namespaceStatements) {
|
|
302
527
|
//TODO should we handle non-brighterscript?
|
|
303
|
-
let name = namespace.nameExpression.getName(
|
|
528
|
+
let name = namespace.nameExpression.getName(Parser_1.ParseMode.BrighterScript);
|
|
304
529
|
let nameParts = name.split('.');
|
|
305
530
|
let loopName = null;
|
|
306
531
|
//ensure each namespace section is represented in the results
|
|
@@ -308,41 +533,47 @@ class Scope {
|
|
|
308
533
|
for (let part of nameParts) {
|
|
309
534
|
loopName = loopName === null ? part : `${loopName}.${part}`;
|
|
310
535
|
let lowerLoopName = loopName.toLowerCase();
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
536
|
+
if (!namespaceLookup.has(lowerLoopName)) {
|
|
537
|
+
namespaceLookup.set(lowerLoopName, {
|
|
538
|
+
file: file,
|
|
539
|
+
fullName: loopName,
|
|
540
|
+
nameRange: namespace.nameExpression.range,
|
|
541
|
+
lastPartName: part,
|
|
542
|
+
namespaces: new Map(),
|
|
543
|
+
classStatements: {},
|
|
544
|
+
functionStatements: {},
|
|
545
|
+
enumStatements: new Map(),
|
|
546
|
+
statements: [],
|
|
547
|
+
symbolTable: new SymbolTable_1.SymbolTable(this.symbolTable)
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
let ns = namespaceLookup.get(name.toLowerCase());
|
|
324
552
|
ns.statements.push(...namespace.body.statements);
|
|
325
553
|
for (let statement of namespace.body.statements) {
|
|
326
|
-
if (reflection_1.isClassStatement(statement)) {
|
|
554
|
+
if ((0, reflection_1.isClassStatement)(statement) && statement.name) {
|
|
327
555
|
ns.classStatements[statement.name.text.toLowerCase()] = statement;
|
|
328
556
|
}
|
|
329
|
-
else if (reflection_1.isFunctionStatement(statement)) {
|
|
557
|
+
else if ((0, reflection_1.isFunctionStatement)(statement) && statement.name) {
|
|
330
558
|
ns.functionStatements[statement.name.text.toLowerCase()] = statement;
|
|
331
559
|
}
|
|
560
|
+
else if ((0, reflection_1.isEnumStatement)(statement) && statement.fullName) {
|
|
561
|
+
ns.enumStatements.set(statement.fullName.toLowerCase(), statement);
|
|
562
|
+
}
|
|
332
563
|
}
|
|
333
564
|
// Merges all the symbol tables of the namespace statements into the new symbol table created above.
|
|
334
565
|
// Set those symbol tables to have this new merged table as a parent
|
|
335
566
|
ns.symbolTable.mergeSymbolTable(namespace.symbolTable);
|
|
336
567
|
}
|
|
337
568
|
//associate child namespaces with their parents
|
|
338
|
-
for (let
|
|
339
|
-
let ns = namespaceLookup[key];
|
|
569
|
+
for (let [, ns] of namespaceLookup) {
|
|
340
570
|
let parts = ns.fullName.split('.');
|
|
341
571
|
if (parts.length > 1) {
|
|
342
572
|
//remove the last part
|
|
343
573
|
parts.pop();
|
|
344
574
|
let parentName = parts.join('.');
|
|
345
|
-
namespaceLookup
|
|
575
|
+
const parent = namespaceLookup.get(parentName.toLowerCase());
|
|
576
|
+
parent.namespaces.set(ns.lastPartName.toLowerCase(), ns);
|
|
346
577
|
}
|
|
347
578
|
}
|
|
348
579
|
});
|
|
@@ -381,6 +612,10 @@ class Scope {
|
|
|
381
612
|
});
|
|
382
613
|
//get a list of all callables, indexed by their lower case names
|
|
383
614
|
let callableContainerMap = util_1.util.getCallableContainersByLowerName(callables);
|
|
615
|
+
this.program.plugins.emit('onScopeValidate', {
|
|
616
|
+
program: this.program,
|
|
617
|
+
scope: this
|
|
618
|
+
});
|
|
384
619
|
this._validate(callableContainerMap);
|
|
385
620
|
// unlink the symbol table so it can't be accessed from the wrong scope
|
|
386
621
|
this.unlinkSymbolTable();
|
|
@@ -391,17 +626,15 @@ class Scope {
|
|
|
391
626
|
this.diagnosticFindDuplicateFunctionDeclarations(callableContainerMap);
|
|
392
627
|
//detect missing and incorrect-case script imports
|
|
393
628
|
this.diagnosticValidateScriptImportPaths();
|
|
394
|
-
//enforce a series of checks on the bodies of class methods
|
|
395
|
-
this.validateClasses();
|
|
396
629
|
//do many per-file checks
|
|
397
630
|
this.enumerateBrsFiles((file) => {
|
|
398
|
-
|
|
399
|
-
this.
|
|
631
|
+
//enforce a series of checks on the bodies of class methods
|
|
632
|
+
this.validateClasses(file);
|
|
400
633
|
this.diagnosticDetectShadowedLocalVars(file, callableContainerMap);
|
|
401
634
|
this.diagnosticDetectFunctionCollisions(file);
|
|
402
635
|
this.detectVariableNamespaceCollisions(file);
|
|
403
636
|
this.diagnosticDetectInvalidFunctionExpressionTypes(file);
|
|
404
|
-
this.diagnosticDetectInvalidFunctionCalls(file);
|
|
637
|
+
this.diagnosticDetectInvalidFunctionCalls(file, callableContainerMap);
|
|
405
638
|
});
|
|
406
639
|
}
|
|
407
640
|
/**
|
|
@@ -412,21 +645,34 @@ class Scope {
|
|
|
412
645
|
//clear out various lookups (they'll get regenerated on demand the next time they're requested)
|
|
413
646
|
this.cache.clear();
|
|
414
647
|
this.clearSymbolTable();
|
|
648
|
+
this.symbolCache.clear();
|
|
415
649
|
}
|
|
416
650
|
get symbolTable() {
|
|
417
651
|
var _a, _b;
|
|
418
652
|
if (!this._symbolTable) {
|
|
419
653
|
this._symbolTable = new SymbolTable_1.SymbolTable((_a = this.getParentScope()) === null || _a === void 0 ? void 0 : _a.symbolTable);
|
|
654
|
+
this._symbolTable.addSymbol('m', null, new ObjectType_1.ObjectType('object', this.memberTable));
|
|
420
655
|
for (let file of this.getOwnFiles()) {
|
|
421
|
-
if (reflection_1.isBrsFile(file)) {
|
|
656
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
422
657
|
this._symbolTable.mergeSymbolTable((_b = file.parser) === null || _b === void 0 ? void 0 : _b.symbolTable);
|
|
423
658
|
}
|
|
424
659
|
}
|
|
425
660
|
}
|
|
426
661
|
return this._symbolTable;
|
|
427
662
|
}
|
|
663
|
+
get memberTable() {
|
|
664
|
+
var _a;
|
|
665
|
+
if (!this._memberTable) {
|
|
666
|
+
this._memberTable = new SymbolTable_1.SymbolTable((_a = this.getParentScope()) === null || _a === void 0 ? void 0 : _a.memberTable);
|
|
667
|
+
if (!this.getParentScope()) {
|
|
668
|
+
this._memberTable.addSymbol('global', null, new ObjectType_1.ObjectType());
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
return this._memberTable;
|
|
672
|
+
}
|
|
428
673
|
clearSymbolTable() {
|
|
429
674
|
this._symbolTable = null;
|
|
675
|
+
this._memberTable = null;
|
|
430
676
|
}
|
|
431
677
|
/**
|
|
432
678
|
* Builds the current symbol table for the scope, by merging the tables for all the files in this scope.
|
|
@@ -434,22 +680,54 @@ class Scope {
|
|
|
434
680
|
* This will only rebuilt if the symbol table has not been built before
|
|
435
681
|
*/
|
|
436
682
|
linkSymbolTable() {
|
|
437
|
-
var _a;
|
|
438
|
-
for (const file of this.
|
|
439
|
-
if (reflection_1.isBrsFile(file)) {
|
|
440
|
-
|
|
683
|
+
var _a, _b, _c;
|
|
684
|
+
for (const file of this.getAllFiles()) {
|
|
685
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
686
|
+
file.parser.symbolTable.setParent(this.symbolTable);
|
|
441
687
|
for (const namespace of file.parser.references.namespaceStatements) {
|
|
442
|
-
const namespaceNameLower = namespace.nameExpression.getName(
|
|
443
|
-
const namespaceSymbolTable = this.namespaceLookup
|
|
688
|
+
const namespaceNameLower = namespace.nameExpression.getName(Parser_1.ParseMode.BrighterScript).toLowerCase();
|
|
689
|
+
const namespaceSymbolTable = this.namespaceLookup.get(namespaceNameLower).symbolTable;
|
|
444
690
|
namespace.symbolTable.setParent(namespaceSymbolTable);
|
|
445
691
|
}
|
|
692
|
+
//TODO TYPES: build symbol tables for dotted set assignments using actual values
|
|
693
|
+
// Currently this is prone to call-stack issues.
|
|
694
|
+
// eg. m.key = "value"
|
|
695
|
+
for (const dotSetStmt of file.parser.references.dottedSetStatements) {
|
|
696
|
+
if ((0, reflection_1.isVariableExpression)(dotSetStmt.obj)) {
|
|
697
|
+
if (dotSetStmt.obj.getName(Parser_1.ParseMode.BrighterScript).toLowerCase() === 'm') {
|
|
698
|
+
this.memberTable.addSymbol(dotSetStmt.name.text, dotSetStmt.range, new DynamicType_1.DynamicType());
|
|
699
|
+
// TODO TYPES: get actual types: getBscTypeFromExpression(dotSetStmt.value, file.parser.references.getContainingFunctionExpression(dotSetStmt.name)));
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
else {
|
|
703
|
+
// TODO TYPES: What other types of expressions could these be?
|
|
704
|
+
}
|
|
705
|
+
}
|
|
446
706
|
}
|
|
447
707
|
}
|
|
708
|
+
// also link classes
|
|
709
|
+
const classMap = this.getClassMap();
|
|
710
|
+
for (const pair of classMap) {
|
|
711
|
+
const classStmt = (_a = pair[1]) === null || _a === void 0 ? void 0 : _a.item;
|
|
712
|
+
classStmt === null || classStmt === void 0 ? void 0 : classStmt.buildSymbolTable(this.getParentClass(classStmt));
|
|
713
|
+
}
|
|
714
|
+
// also link interfaces
|
|
715
|
+
const ifaceMap = this.getInterfaceMap();
|
|
716
|
+
for (const pair of ifaceMap) {
|
|
717
|
+
const ifaceStmt = (_b = pair[1]) === null || _b === void 0 ? void 0 : _b.item;
|
|
718
|
+
ifaceStmt === null || ifaceStmt === void 0 ? void 0 : ifaceStmt.buildSymbolTable(this.getParentInterface(ifaceStmt));
|
|
719
|
+
}
|
|
720
|
+
//also link enums
|
|
721
|
+
const enumMap = this.getEnumMap();
|
|
722
|
+
for (const pair of enumMap) {
|
|
723
|
+
const enumStmt = (_c = pair[1]) === null || _c === void 0 ? void 0 : _c.item;
|
|
724
|
+
enumStmt === null || enumStmt === void 0 ? void 0 : enumStmt.buildSymbolTable();
|
|
725
|
+
}
|
|
448
726
|
}
|
|
449
727
|
unlinkSymbolTable() {
|
|
450
728
|
var _a;
|
|
451
729
|
for (let file of this.getOwnFiles()) {
|
|
452
|
-
if (reflection_1.isBrsFile(file)) {
|
|
730
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
453
731
|
(_a = file.parser) === null || _a === void 0 ? void 0 : _a.symbolTable.setParent(null);
|
|
454
732
|
for (const namespace of file.parser.references.namespaceStatements) {
|
|
455
733
|
namespace.symbolTable.setParent(null);
|
|
@@ -462,7 +740,7 @@ class Scope {
|
|
|
462
740
|
for (let func of file.parser.references.functionExpressions) {
|
|
463
741
|
for (let param of func.parameters) {
|
|
464
742
|
let lowerParamName = param.name.text.toLowerCase();
|
|
465
|
-
let namespace = this.namespaceLookup
|
|
743
|
+
let namespace = this.namespaceLookup.get(lowerParamName);
|
|
466
744
|
//see if the param matches any starting namespace part
|
|
467
745
|
if (namespace) {
|
|
468
746
|
this.diagnostics.push(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.parameterMayNotHaveSameNameAsNamespace(param.name.text)), { range: param.name.range, relatedInformation: [{
|
|
@@ -474,7 +752,7 @@ class Scope {
|
|
|
474
752
|
}
|
|
475
753
|
for (let assignment of file.parser.references.assignmentStatements) {
|
|
476
754
|
let lowerAssignmentName = assignment.name.text.toLowerCase();
|
|
477
|
-
let namespace = this.namespaceLookup
|
|
755
|
+
let namespace = this.namespaceLookup.get(lowerAssignmentName);
|
|
478
756
|
//see if the param matches any starting namespace part
|
|
479
757
|
if (namespace) {
|
|
480
758
|
this.diagnostics.push(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.variableMayNotHaveSameNameAsNamespace(assignment.name.text)), { range: assignment.name.range, relatedInformation: [{
|
|
@@ -489,7 +767,7 @@ class Scope {
|
|
|
489
767
|
*/
|
|
490
768
|
diagnosticDetectFunctionCollisions(file) {
|
|
491
769
|
for (let func of file.callables) {
|
|
492
|
-
const funcName = func.getName(
|
|
770
|
+
const funcName = func.getName(Parser_1.ParseMode.BrighterScript);
|
|
493
771
|
const lowerFuncName = funcName === null || funcName === void 0 ? void 0 : funcName.toLowerCase();
|
|
494
772
|
if (lowerFuncName) {
|
|
495
773
|
//find function declarations with the same name as a stdlib function
|
|
@@ -507,48 +785,115 @@ class Scope {
|
|
|
507
785
|
* Find function parameters and function return types that are neither built-in types or known Class references
|
|
508
786
|
*/
|
|
509
787
|
diagnosticDetectInvalidFunctionExpressionTypes(file) {
|
|
510
|
-
var _a, _b;
|
|
788
|
+
var _a, _b, _c, _d;
|
|
511
789
|
for (let func of file.parser.references.functionExpressions) {
|
|
512
|
-
|
|
790
|
+
const returnType = (0, BscType_1.getTypeFromContext)(func.getReturnType(), { file: file, scope: this, position: (_a = func.range) === null || _a === void 0 ? void 0 : _a.start });
|
|
791
|
+
if (!returnType && func.returnType) {
|
|
513
792
|
// check if this custom type is in our class map
|
|
514
|
-
const returnTypeName = func.returnType.
|
|
515
|
-
const currentNamespaceName = (
|
|
516
|
-
if (!this.hasClass(returnTypeName, currentNamespaceName)) {
|
|
517
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.invalidFunctionReturnType(returnTypeName)), { range: func.
|
|
793
|
+
const returnTypeName = func.returnType.getText();
|
|
794
|
+
const currentNamespaceName = (_b = func.namespaceName) === null || _b === void 0 ? void 0 : _b.getName(Parser_1.ParseMode.BrighterScript);
|
|
795
|
+
if (!this.hasClass(returnTypeName, currentNamespaceName) && !this.hasInterface(returnTypeName) && !this.hasEnum(returnTypeName)) {
|
|
796
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.invalidFunctionReturnType(returnTypeName)), { range: func.returnType.range, file: file }));
|
|
518
797
|
}
|
|
519
798
|
}
|
|
520
799
|
for (let param of func.parameters) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
800
|
+
const typeContext = { file: file, scope: this, position: (_c = param.range) === null || _c === void 0 ? void 0 : _c.start };
|
|
801
|
+
let paramType = (0, BscType_1.getTypeFromContext)(param.getType(), typeContext);
|
|
802
|
+
while ((0, reflection_1.isArrayType)(paramType)) {
|
|
803
|
+
paramType = (0, BscType_1.getTypeFromContext)(paramType.getDefaultType(typeContext), typeContext);
|
|
804
|
+
}
|
|
805
|
+
if (!paramType && param.type) {
|
|
806
|
+
const paramTypeName = param.type.getText();
|
|
807
|
+
const currentNamespaceName = (_d = func.namespaceName) === null || _d === void 0 ? void 0 : _d.getName(Parser_1.ParseMode.BrighterScript);
|
|
808
|
+
if (!this.hasClass(paramTypeName, currentNamespaceName) && !this.hasInterface(paramTypeName) && !this.hasEnum(paramTypeName)) {
|
|
809
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(param.name.text, paramTypeName)), { range: param.type.range, file: file }));
|
|
526
810
|
}
|
|
527
811
|
}
|
|
528
812
|
}
|
|
529
813
|
}
|
|
530
814
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
815
|
+
/**
|
|
816
|
+
* Find functions with either the wrong type of parameters, or the wrong number of parameters
|
|
817
|
+
*/
|
|
818
|
+
diagnosticDetectInvalidFunctionCalls(file, callableContainersByLowerName) {
|
|
819
|
+
var _a, _b, _c, _d;
|
|
820
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
821
|
+
for (let expCall of file.functionCalls) {
|
|
822
|
+
const symbolTypeInfo = file.getSymbolTypeFromToken(expCall.name, expCall.functionExpression, this);
|
|
823
|
+
let funcType = symbolTypeInfo.type;
|
|
824
|
+
if (!(0, reflection_1.isTypedFunctionType)(funcType) && !(0, reflection_1.isDynamicType)(funcType)) {
|
|
825
|
+
// We don't know if this is a function. Try seeing if it is a global
|
|
826
|
+
const callableContainer = util_1.util.getCallableContainerByFunctionCall(callableContainersByLowerName, expCall);
|
|
827
|
+
if (callableContainer) {
|
|
828
|
+
// We found a global callable with correct number of params - use that
|
|
829
|
+
funcType = (_a = callableContainer.callable) === null || _a === void 0 ? void 0 : _a.type;
|
|
830
|
+
}
|
|
831
|
+
else {
|
|
832
|
+
const allowedParamCount = util_1.util.getMinMaxParamCountByFunctionCall(callableContainersByLowerName, expCall);
|
|
833
|
+
if (allowedParamCount) {
|
|
834
|
+
// We found a global callable, but it needs a different number of args
|
|
835
|
+
this.addMismatchParamCountDiagnostic(allowedParamCount, expCall, file);
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
if ((0, reflection_1.isFunctionType)(funcType)) {
|
|
841
|
+
// This is a generic function, and it is callable
|
|
842
|
+
}
|
|
843
|
+
else if ((0, reflection_1.isTypedFunctionType)(funcType)) {
|
|
844
|
+
// Check for Argument count mismatch.
|
|
845
|
+
//get min/max parameter count for callable
|
|
846
|
+
let paramCount = util_1.util.getMinMaxParamCount(funcType.params);
|
|
847
|
+
if (expCall.args.length > paramCount.max || expCall.args.length < paramCount.min) {
|
|
848
|
+
this.addMismatchParamCountDiagnostic(paramCount, expCall, file);
|
|
849
|
+
}
|
|
850
|
+
// Check for Argument type mismatch.
|
|
851
|
+
const paramTypeContext = { file: file, scope: this, position: (_b = expCall.functionExpression.range) === null || _b === void 0 ? void 0 : _b.start };
|
|
852
|
+
const argTypeContext = { file: file, scope: this, position: (_c = expCall.range) === null || _c === void 0 ? void 0 : _c.start };
|
|
853
|
+
for (let index = 0; index < funcType.params.length; index++) {
|
|
854
|
+
const param = funcType.params[index];
|
|
855
|
+
const arg = expCall.args[index];
|
|
856
|
+
if (!arg) {
|
|
857
|
+
// not enough args
|
|
858
|
+
break;
|
|
859
|
+
}
|
|
860
|
+
let argType = (_d = arg.type) !== null && _d !== void 0 ? _d : new UninitializedType_1.UninitializedType();
|
|
861
|
+
const paramType = (0, BscType_1.getTypeFromContext)(param.type, paramTypeContext);
|
|
862
|
+
if (!paramType) {
|
|
863
|
+
// other error - can not determine what type this parameter should be
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
argType = (0, BscType_1.getTypeFromContext)(argType, argTypeContext);
|
|
867
|
+
let assignable = argType === null || argType === void 0 ? void 0 : argType.isAssignableTo(paramType, argTypeContext);
|
|
868
|
+
if (!assignable) {
|
|
869
|
+
// TODO TYPES: perhaps this should be a strict mode setting?
|
|
870
|
+
assignable = argType === null || argType === void 0 ? void 0 : argType.isConvertibleTo(paramType, argTypeContext);
|
|
871
|
+
}
|
|
872
|
+
if (!assignable) {
|
|
873
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch(argType === null || argType === void 0 ? void 0 : argType.toString(argTypeContext), paramType.toString(paramTypeContext))), { range: arg === null || arg === void 0 ? void 0 : arg.range, file: file }));
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
else if ((0, reflection_1.isInvalidType)(symbolTypeInfo.type)) {
|
|
878
|
+
// TODO TYPES: standard member functions like integer.ToStr() are not detectable yet.
|
|
879
|
+
}
|
|
880
|
+
else if ((0, reflection_1.isDynamicType)(symbolTypeInfo.type)) {
|
|
881
|
+
// maybe this is a function? who knows
|
|
882
|
+
}
|
|
883
|
+
else {
|
|
884
|
+
const functionNameText = symbolTypeInfo.expandedTokenText;
|
|
885
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.callToUnknownFunction(functionNameText, this.name)), { range: expCall.nameRange,
|
|
886
|
+
//TODO detect end of expression call
|
|
887
|
+
file: file }));
|
|
548
888
|
}
|
|
549
889
|
}
|
|
550
890
|
}
|
|
551
891
|
}
|
|
892
|
+
addMismatchParamCountDiagnostic(paramCount, expCall, file) {
|
|
893
|
+
const minMaxParamsText = paramCount.min === paramCount.max ? paramCount.max : `${paramCount.min}-${paramCount.max}`;
|
|
894
|
+
const expCallArgCount = expCall.args.length;
|
|
895
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(minMaxParamsText, expCallArgCount)), { range: expCall.nameRange, file: file }));
|
|
896
|
+
}
|
|
552
897
|
getNewExpressions() {
|
|
553
898
|
let result = [];
|
|
554
899
|
this.enumerateBrsFiles((file) => {
|
|
@@ -560,44 +905,11 @@ class Scope {
|
|
|
560
905
|
});
|
|
561
906
|
return result;
|
|
562
907
|
}
|
|
563
|
-
validateClasses() {
|
|
908
|
+
validateClasses(file) {
|
|
564
909
|
let validator = new ClassValidator_1.BsClassValidator();
|
|
565
|
-
validator.validate(this);
|
|
910
|
+
validator.validate(this, file);
|
|
566
911
|
this.diagnostics.push(...validator.diagnostics);
|
|
567
912
|
}
|
|
568
|
-
/**
|
|
569
|
-
* Detect calls to functions with the incorrect number of parameters
|
|
570
|
-
* @param file
|
|
571
|
-
* @param callableContainersByLowerName
|
|
572
|
-
*/
|
|
573
|
-
diagnosticDetectFunctionCallsWithWrongParamCount(file, callableContainersByLowerName) {
|
|
574
|
-
//validate all function calls
|
|
575
|
-
for (let expCall of file.functionCalls) {
|
|
576
|
-
let callableContainersWithThisName = callableContainersByLowerName.get(expCall.name.toLowerCase());
|
|
577
|
-
//use the first item from callablesByLowerName, because if there are more, that's a separate error
|
|
578
|
-
let knownCallableContainer = callableContainersWithThisName ? callableContainersWithThisName[0] : undefined;
|
|
579
|
-
if (knownCallableContainer) {
|
|
580
|
-
//get min/max parameter count for callable
|
|
581
|
-
let minParams = 0;
|
|
582
|
-
let maxParams = 0;
|
|
583
|
-
for (let param of knownCallableContainer.callable.params) {
|
|
584
|
-
maxParams++;
|
|
585
|
-
//optional parameters must come last, so we can assume that minParams won't increase once we hit
|
|
586
|
-
//the first isOptional
|
|
587
|
-
if (param.isOptional === false) {
|
|
588
|
-
minParams++;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
let expCallArgCount = expCall.args.length;
|
|
592
|
-
if (expCall.args.length > maxParams || expCall.args.length < minParams) {
|
|
593
|
-
let minMaxParamsText = minParams === maxParams ? maxParams : `${minParams}-${maxParams}`;
|
|
594
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(minMaxParamsText, expCallArgCount)), { range: expCall.nameRange,
|
|
595
|
-
//TODO detect end of expression call
|
|
596
|
-
file: file }));
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
913
|
/**
|
|
602
914
|
* Detect local variables (vars declared within a function expression) that have the same name as scope calls
|
|
603
915
|
* @param file
|
|
@@ -607,10 +919,10 @@ class Scope {
|
|
|
607
919
|
const classMap = this.getClassMap();
|
|
608
920
|
for (let func of file.parser.references.functionExpressions) {
|
|
609
921
|
//every var declaration in this function expression
|
|
610
|
-
for (let symbol of func.symbolTable.
|
|
922
|
+
for (let symbol of func.symbolTable.getOwnSymbols()) {
|
|
611
923
|
const symbolNameLower = symbol.name.toLowerCase();
|
|
612
924
|
//if the var is a function
|
|
613
|
-
if (reflection_1.
|
|
925
|
+
if ((0, reflection_1.isTypedFunctionType)(symbol.type)) {
|
|
614
926
|
//local var function with same name as stdlib function
|
|
615
927
|
if (
|
|
616
928
|
//has same name as stdlib
|
|
@@ -635,44 +947,9 @@ class Scope {
|
|
|
635
947
|
//has the same name as an in-scope class
|
|
636
948
|
}
|
|
637
949
|
else if (classMap.has(symbolNameLower)) {
|
|
638
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarSameNameAsClass(classMap.get(symbolNameLower).item.getName(
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
/**
|
|
645
|
-
* Detect calls to functions that are not defined in this scope
|
|
646
|
-
* @param file
|
|
647
|
-
* @param callablesByLowerName
|
|
648
|
-
*/
|
|
649
|
-
diagnosticDetectCallsToUnknownFunctions(file, callablesByLowerName) {
|
|
650
|
-
var _a;
|
|
651
|
-
//validate all expression calls
|
|
652
|
-
for (let expCall of file.functionCalls) {
|
|
653
|
-
if (reflection_1.isBrsFile(file)) {
|
|
654
|
-
const lowerName = expCall.name.toLowerCase();
|
|
655
|
-
//for now, skip validation on any method named "super" within `.bs` contexts.
|
|
656
|
-
//TODO revise this logic so we know if this function call resides within a class constructor function
|
|
657
|
-
if (file.extension === '.bs' && lowerName === 'super') {
|
|
658
|
-
continue;
|
|
659
|
-
}
|
|
660
|
-
//find a local variable with this name
|
|
661
|
-
const localSymbol = (_a = file.getFunctionExpressionAtPosition(expCall.nameRange.start)) === null || _a === void 0 ? void 0 : _a.symbolTable.getSymbol(lowerName);
|
|
662
|
-
//if we don't already have a variable with this name.
|
|
663
|
-
if (!localSymbol) {
|
|
664
|
-
const callablesWithThisName = util_1.util.getCallableContainersFromContainerMapByFunctionCall(callablesByLowerName, expCall);
|
|
665
|
-
//use the first item from callablesByLowerName, because if there are more, that's a separate error
|
|
666
|
-
let knownCallable = callablesWithThisName ? callablesWithThisName[0] : undefined;
|
|
667
|
-
//detect calls to unknown functions
|
|
668
|
-
if (!knownCallable) {
|
|
669
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.callToUnknownFunction(expCall.name, this.name)), { range: expCall.nameRange, file: file }));
|
|
950
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarSameNameAsClass(classMap.get(symbolNameLower).item.getName(Parser_1.ParseMode.BrighterScript))), { range: symbol.range, file: file }));
|
|
670
951
|
}
|
|
671
952
|
}
|
|
672
|
-
else {
|
|
673
|
-
//if we found a variable with the same name as the function, assume the call is "known".
|
|
674
|
-
//If the variable is a different type, some other check should add a diagnostic for that.
|
|
675
|
-
}
|
|
676
953
|
}
|
|
677
954
|
}
|
|
678
955
|
}
|
|
@@ -732,10 +1009,10 @@ class Scope {
|
|
|
732
1009
|
getOwnScriptImports() {
|
|
733
1010
|
let result = [];
|
|
734
1011
|
this.enumerateOwnFiles((file) => {
|
|
735
|
-
if (reflection_1.isBrsFile(file)) {
|
|
1012
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
736
1013
|
result.push(...file.ownScriptImports);
|
|
737
1014
|
}
|
|
738
|
-
else if (reflection_1.isXmlFile(file)) {
|
|
1015
|
+
else if ((0, reflection_1.isXmlFile)(file)) {
|
|
739
1016
|
result.push(...file.scriptTagImports);
|
|
740
1017
|
}
|
|
741
1018
|
});
|
|
@@ -800,7 +1077,7 @@ class Scope {
|
|
|
800
1077
|
getCallablesAsCompletions(parseMode) {
|
|
801
1078
|
let completions = [];
|
|
802
1079
|
let callables = this.getAllCallables();
|
|
803
|
-
if (parseMode ===
|
|
1080
|
+
if (parseMode === Parser_1.ParseMode.BrighterScript) {
|
|
804
1081
|
//throw out the namespaced callables (they will be handled by another method)
|
|
805
1082
|
callables = callables.filter(x => x.callable.hasNamespace === false);
|
|
806
1083
|
}
|
|
@@ -811,7 +1088,7 @@ class Scope {
|
|
|
811
1088
|
}
|
|
812
1089
|
createCompletionFromCallable(callableContainer) {
|
|
813
1090
|
return {
|
|
814
|
-
label: callableContainer.callable.getName(
|
|
1091
|
+
label: callableContainer.callable.getName(Parser_1.ParseMode.BrighterScript),
|
|
815
1092
|
kind: vscode_languageserver_1.CompletionItemKind.Function,
|
|
816
1093
|
detail: callableContainer.callable.shortDescription,
|
|
817
1094
|
documentation: callableContainer.callable.documentation ? { kind: 'markdown', value: callableContainer.callable.documentation } : undefined
|
|
@@ -819,7 +1096,7 @@ class Scope {
|
|
|
819
1096
|
}
|
|
820
1097
|
createCompletionFromFunctionStatement(statement) {
|
|
821
1098
|
return {
|
|
822
|
-
label: statement.getName(
|
|
1099
|
+
label: statement.getName(Parser_1.ParseMode.BrighterScript),
|
|
823
1100
|
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
824
1101
|
};
|
|
825
1102
|
}
|
|
@@ -844,7 +1121,7 @@ class Scope {
|
|
|
844
1121
|
let results = new Map();
|
|
845
1122
|
let filesSearched = new Set();
|
|
846
1123
|
for (const file of this.getAllFiles()) {
|
|
847
|
-
if (reflection_1.isXmlFile(file) || filesSearched.has(file)) {
|
|
1124
|
+
if ((0, reflection_1.isXmlFile)(file) || filesSearched.has(file)) {
|
|
848
1125
|
continue;
|
|
849
1126
|
}
|
|
850
1127
|
filesSearched.add(file);
|
|
@@ -853,7 +1130,7 @@ class Scope {
|
|
|
853
1130
|
if (!results.has(s.name.text) && s.name.text.toLowerCase() !== 'new') {
|
|
854
1131
|
results.set(s.name.text, {
|
|
855
1132
|
label: s.name.text,
|
|
856
|
-
kind: reflection_1.
|
|
1133
|
+
kind: (0, reflection_1.isMethodStatement)(s) ? vscode_languageserver_1.CompletionItemKind.Method : vscode_languageserver_1.CompletionItemKind.Field
|
|
857
1134
|
});
|
|
858
1135
|
}
|
|
859
1136
|
}
|
|
@@ -864,7 +1141,7 @@ class Scope {
|
|
|
864
1141
|
/**
|
|
865
1142
|
* @param className - The name of the class (including namespace if possible)
|
|
866
1143
|
* @param callsiteNamespace - the name of the namespace where the call site resides (this is NOT the known namespace of the class).
|
|
867
|
-
* This is used to help resolve non-namespaced class names that reside in the same
|
|
1144
|
+
* This is used to help resolve non-namespaced class names that reside in the same namespace as the call site.
|
|
868
1145
|
*/
|
|
869
1146
|
getClassHierarchy(className, callsiteNamespace) {
|
|
870
1147
|
var _a, _b;
|
|
@@ -872,7 +1149,7 @@ class Scope {
|
|
|
872
1149
|
let link = this.getClassFileLink(className, callsiteNamespace);
|
|
873
1150
|
while (link) {
|
|
874
1151
|
items.push(link);
|
|
875
|
-
link = this.getClassFileLink((_b = (_a = link.item.parentClassName) === null || _a === void 0 ? void 0 : _a.getName(
|
|
1152
|
+
link = this.getClassFileLink((_b = (_a = link.item.parentClassName) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript)) === null || _b === void 0 ? void 0 : _b.toLowerCase(), callsiteNamespace);
|
|
876
1153
|
}
|
|
877
1154
|
return items;
|
|
878
1155
|
}
|