brighterscript 0.66.0-alpha.1 → 0.66.0-alpha.11
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 +224 -10
- package/README.md +13 -3
- package/bsconfig.schema.json +15 -0
- package/dist/ActionPipeline.d.ts +10 -0
- package/dist/ActionPipeline.js +40 -0
- package/dist/ActionPipeline.js.map +1 -0
- package/dist/AstValidationSegmenter.d.ts +25 -0
- package/dist/AstValidationSegmenter.js +150 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +13 -4
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.js +3 -3
- package/dist/Cache.js.map +1 -1
- package/dist/CacheVerifier.d.ts +0 -1
- package/dist/CodeActionUtil.d.ts +2 -2
- package/dist/CommentFlagProcessor.d.ts +4 -3
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DiagnosticCollection.js +8 -5
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +34 -4
- package/dist/DiagnosticMessages.js +59 -4
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/FunctionScope.d.ts +1 -1
- package/dist/LanguageServer.d.ts +23 -1
- package/dist/LanguageServer.js +139 -57
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +3 -2
- package/dist/Logger.js +10 -2
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +11 -2
- package/dist/PluginInterface.js +69 -10
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +138 -49
- package/dist/Program.js +644 -349
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +10 -4
- package/dist/ProgramBuilder.js +76 -74
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +52 -49
- package/dist/Scope.js +298 -274
- package/dist/Scope.js.map +1 -1
- package/dist/SymbolTable.d.ts +35 -14
- package/dist/SymbolTable.js +90 -29
- package/dist/SymbolTable.js.map +1 -1
- package/dist/Throttler.d.ts +12 -0
- package/dist/Throttler.js +39 -0
- package/dist/Throttler.js.map +1 -1
- package/dist/XmlScope.d.ts +7 -4
- package/dist/XmlScope.js +52 -12
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +6 -1
- package/dist/astUtils/{AstEditor.js → Editor.js} +9 -3
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +10 -6
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +3 -1
- package/dist/astUtils/creators.js +14 -4
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +37 -9
- package/dist/astUtils/reflection.js +83 -14
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +87 -5
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +14 -3
- package/dist/astUtils/visitors.js +22 -2
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +58 -7
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +10 -2
- package/dist/bscPlugin/BscPlugin.js +24 -4
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +3 -3
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
- package/dist/bscPlugin/FileWriter.d.ts +6 -0
- package/dist/bscPlugin/FileWriter.js +24 -0
- package/dist/bscPlugin/FileWriter.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +8 -8
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +4 -4
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +50 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.js +445 -23
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1737 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +7 -3
- package/dist/bscPlugin/hover/HoverProcessor.js +133 -103
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +241 -29
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +43 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +22 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
- package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
- package/dist/bscPlugin/serialize/BslibManager.js +40 -0
- package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
- package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
- package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
- package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
- package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.d.ts → BrsFileTranspileProcessor.d.ts} +4 -2
- package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.js → BrsFileTranspileProcessor.js} +29 -5
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +2 -2
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +0 -4
- package/dist/bscPlugin/validation/BrsFileValidator.js +34 -29
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +28 -7
- package/dist/bscPlugin/validation/ScopeValidator.js +393 -205
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2038 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js +2 -2
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
- package/dist/cli.js +104 -13
- package/dist/cli.js.map +1 -1
- package/dist/deferred.d.ts +3 -3
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +8 -2
- package/dist/diagnosticUtils.js +45 -16
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +1 -1
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +26 -0
- package/dist/files/AssetFile.js +26 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +383 -56
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +73 -46
- package/dist/files/BrsFile.js +370 -534
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1139 -682
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/Factory.d.ts +25 -0
- package/dist/files/Factory.js +22 -0
- package/dist/files/Factory.js.map +1 -0
- package/dist/files/File.d.ts +106 -0
- package/dist/files/File.js +16 -0
- package/dist/files/File.js.map +1 -0
- package/dist/files/LazyFileData.d.ts +20 -0
- package/dist/files/LazyFileData.js +54 -0
- package/dist/files/LazyFileData.js.map +1 -0
- package/dist/files/LazyFileData.spec.d.ts +1 -0
- package/dist/files/LazyFileData.spec.js +27 -0
- package/dist/files/LazyFileData.spec.js.map +1 -0
- package/dist/files/XmlFile.d.ts +56 -23
- package/dist/files/XmlFile.js +88 -60
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +64 -93
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +21 -8
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.js +14 -14
- package/dist/files/tests/optionalChaning.spec.js.map +1 -1
- package/dist/globalCallables.js +88 -84
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +389 -94
- package/dist/interfaces.js +13 -2
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +12 -0
- package/dist/lexer/Lexer.js +28 -8
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +40 -0
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +4 -0
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +5 -0
- package/dist/lexer/TokenKind.js +14 -2
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +9 -2
- package/dist/parser/AstNode.js +16 -0
- package/dist/parser/AstNode.js.map +1 -1
- package/dist/parser/BrsTranspileState.d.ts +3 -2
- package/dist/parser/BrsTranspileState.js +3 -2
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +21 -5
- package/dist/parser/Expression.js +130 -35
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +103 -1
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +7 -0
- package/dist/parser/Parser.js +117 -21
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +557 -5
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +4 -4
- package/dist/parser/SGParser.js +3 -3
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +2 -2
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +2 -2
- package/dist/parser/Statement.d.ts +37 -12
- package/dist/parser/Statement.js +153 -46
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/tests/Parser.spec.js +2 -1
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +16 -8
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +12 -6
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +8 -4
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +4 -4
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +29 -29
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +75 -36
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +36 -36
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js +71 -22
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Continue.spec.js +2 -2
- package/dist/parser/tests/statement/Continue.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.js +38 -285
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
- package/dist/parser/tests/statement/For.spec.js +6 -6
- package/dist/parser/tests/statement/For.spec.js.map +1 -1
- package/dist/parser/tests/statement/ForEach.spec.js +4 -4
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +26 -10
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +16 -13
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +5 -3
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +26 -13
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +1 -1
- package/dist/preprocessor/Manifest.js +2 -2
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/roku-types/data.json +244 -294
- package/dist/roku-types/index.d.ts +17 -38
- package/dist/types/ArrayType.d.ts +4 -1
- package/dist/types/ArrayType.js +46 -6
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +32 -3
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +11 -0
- package/dist/types/AssociativeArrayType.js +52 -0
- package/dist/types/AssociativeArrayType.js.map +1 -0
- package/dist/types/BaseFunctionType.d.ts +9 -0
- package/dist/types/BaseFunctionType.js +25 -0
- package/dist/types/BaseFunctionType.js.map +1 -0
- package/dist/types/BooleanType.d.ts +2 -1
- package/dist/types/BooleanType.js +8 -2
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BscType.d.ts +10 -6
- package/dist/types/BscType.js +69 -16
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BscTypeKind.d.ts +3 -0
- package/dist/types/BscTypeKind.js +3 -0
- package/dist/types/BscTypeKind.js.map +1 -1
- package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
- package/dist/types/BuiltInInterfaceAdder.js +164 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +116 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
- package/dist/types/ClassType.d.ts +10 -4
- package/dist/types/ClassType.js +32 -5
- package/dist/types/ClassType.js.map +1 -1
- package/dist/types/ClassType.spec.js +5 -3
- package/dist/types/ClassType.spec.js.map +1 -1
- package/dist/types/ComponentType.d.ts +26 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +2 -1
- package/dist/types/DoubleType.js +9 -2
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DynamicType.d.ts +2 -2
- package/dist/types/DynamicType.js +3 -1
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/EnumType.d.ts +24 -6
- package/dist/types/EnumType.js +29 -7
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/FloatType.d.ts +2 -1
- package/dist/types/FloatType.js +9 -2
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FunctionType.d.ts +8 -20
- package/dist/types/FunctionType.js +17 -45
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +7 -4
- package/dist/types/InheritableType.js +67 -3
- package/dist/types/InheritableType.js.map +1 -1
- package/dist/types/IntegerType.d.ts +2 -1
- package/dist/types/IntegerType.js +9 -2
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +6 -4
- package/dist/types/InterfaceType.js +8 -11
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +30 -2
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/InvalidType.d.ts +2 -1
- package/dist/types/InvalidType.js +7 -1
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +2 -1
- package/dist/types/LongIntegerType.js +9 -2
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/NamespaceType.d.ts +2 -1
- package/dist/types/NamespaceType.js +3 -0
- package/dist/types/NamespaceType.js.map +1 -1
- package/dist/types/ObjectType.d.ts +2 -2
- package/dist/types/ObjectType.js +5 -10
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ReferenceType.d.ts +15 -3
- package/dist/types/ReferenceType.js +173 -24
- package/dist/types/ReferenceType.js.map +1 -1
- package/dist/types/ReferenceType.spec.js +21 -6
- package/dist/types/ReferenceType.spec.js.map +1 -1
- package/dist/types/StringType.d.ts +2 -1
- package/dist/types/StringType.js +9 -2
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +33 -0
- package/dist/types/TypedFunctionType.js +106 -0
- package/dist/types/TypedFunctionType.js.map +1 -0
- package/dist/types/TypedFunctionType.spec.d.ts +1 -0
- package/dist/types/TypedFunctionType.spec.js +122 -0
- package/dist/types/TypedFunctionType.spec.js.map +1 -0
- package/dist/types/UninitializedType.d.ts +2 -1
- package/dist/types/UninitializedType.js +1 -1
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +4 -2
- package/dist/types/UnionType.js +36 -4
- package/dist/types/UnionType.js.map +1 -1
- package/dist/types/UnionType.spec.js +46 -19
- package/dist/types/UnionType.spec.js.map +1 -1
- package/dist/types/VoidType.d.ts +2 -1
- package/dist/types/VoidType.js +7 -2
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/helper.spec.js +15 -0
- package/dist/types/helper.spec.js.map +1 -1
- package/dist/types/helpers.d.ts +5 -0
- package/dist/types/helpers.js +50 -3
- package/dist/types/helpers.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/util.d.ts +71 -15
- package/dist/util.js +578 -150
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +0 -1
- package/dist/validators/ClassValidator.js +0 -22
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +3 -2
- package/dist/astUtils/AstEditor.js.map +0 -1
- package/dist/astUtils/AstEditor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -31
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
- package/dist/types/FunctionType.spec.js +0 -23
- package/dist/types/FunctionType.spec.js.map +0 -1
- /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
- /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{types/FunctionType.spec.d.ts → bscPlugin/serialize/BslibInjector.spec.d.ts} +0 -0
|
@@ -5,16 +5,21 @@ const vscode_uri_1 = require("vscode-uri");
|
|
|
5
5
|
const reflection_1 = require("../../astUtils/reflection");
|
|
6
6
|
const Cache_1 = require("../../Cache");
|
|
7
7
|
const DiagnosticMessages_1 = require("../../DiagnosticMessages");
|
|
8
|
+
const interfaces_1 = require("../../interfaces");
|
|
8
9
|
const SymbolTable_1 = require("../../SymbolTable");
|
|
9
10
|
const util_1 = require("../../util");
|
|
10
11
|
const roku_types_1 = require("../../roku-types");
|
|
11
|
-
const
|
|
12
|
+
const Expression_1 = require("../../parser/Expression");
|
|
13
|
+
const visitors_1 = require("../../astUtils/visitors");
|
|
14
|
+
const AstValidationSegmenter_1 = require("../../AstValidationSegmenter");
|
|
12
15
|
const TokenKind_1 = require("../../lexer/TokenKind");
|
|
16
|
+
const Parser_1 = require("../../parser/Parser");
|
|
13
17
|
/**
|
|
14
18
|
* The lower-case names of all platform-included scenegraph nodes
|
|
15
19
|
*/
|
|
16
|
-
|
|
17
|
-
const
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
21
|
+
const platformNodeNames = roku_types_1.nodes ? new Set(Object.values(roku_types_1.nodes).map(x => x === null || x === void 0 ? void 0 : x.name.toLowerCase())) : new Set();
|
|
22
|
+
const platformComponentNames = roku_types_1.components ? new Set(Object.values(roku_types_1.components).map(x => x === null || x === void 0 ? void 0 : x.name.toLowerCase())) : new Set();
|
|
18
23
|
/**
|
|
19
24
|
* A validator that handles all scope validations for a program validation cycle.
|
|
20
25
|
* You should create ONE of these to handle all scope events between beforeProgramValidate and afterProgramValidate,
|
|
@@ -22,12 +27,14 @@ const platformComponentNames = new Set(Object.values(roku_types_1.components).ma
|
|
|
22
27
|
*/
|
|
23
28
|
class ScopeValidator {
|
|
24
29
|
constructor() {
|
|
25
|
-
this.expressionsByFile = new Cache_1.Cache();
|
|
26
30
|
this.onceCache = new Cache_1.Cache();
|
|
27
31
|
this.multiScopeCache = new Cache_1.Cache();
|
|
28
32
|
}
|
|
29
33
|
processEvent(event) {
|
|
30
34
|
this.event = event;
|
|
35
|
+
if (this.event.program.globalScope === this.event.scope) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
31
38
|
this.walkFiles();
|
|
32
39
|
this.detectDuplicateEnums();
|
|
33
40
|
}
|
|
@@ -39,163 +46,82 @@ class ScopeValidator {
|
|
|
39
46
|
walkFiles() {
|
|
40
47
|
this.event.scope.enumerateOwnFiles((file) => {
|
|
41
48
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
42
|
-
this.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
//TODO: this is much faster than node.findAncestor(), but will not work for "complicated" type expressions
|
|
49
|
-
// like UnionTypes
|
|
50
|
-
if ((0, reflection_1.isTypeExpression)(expression) ||
|
|
51
|
-
(0, reflection_1.isTypeExpression)(expression.parent)) {
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
|
-
if ((0, reflection_1.isBinaryExpression)(expression.parent)) {
|
|
55
|
-
let currentExpr = expression.parent;
|
|
56
|
-
while ((0, reflection_1.isBinaryExpression)(currentExpr) && currentExpr.operator.kind === TokenKind_1.TokenKind.Or) {
|
|
57
|
-
currentExpr = currentExpr.parent;
|
|
58
|
-
}
|
|
59
|
-
return (0, reflection_1.isTypeExpression)(currentExpr);
|
|
60
|
-
}
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
iterateFileExpressions(file) {
|
|
64
|
-
var _a, _b, _c, _d, _e;
|
|
65
|
-
const { scope } = this.event;
|
|
66
|
-
//build an expression collection ONCE per file
|
|
67
|
-
const expressionInfos = this.expressionsByFile.getOrAdd(file, () => {
|
|
68
|
-
var _a, _b;
|
|
69
|
-
const result = [];
|
|
70
|
-
const expressions = [...file.parser.references.expressions];
|
|
71
|
-
for (let expression of expressions) {
|
|
72
|
-
if (!expression) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
//walk left-to-right on every expression, only keep the ones that start with VariableExpression, and then keep subsequent DottedGet parts
|
|
76
|
-
const parts = util_1.default.getDottedGetPath(expression);
|
|
77
|
-
if (parts.length > 0) {
|
|
78
|
-
result.push({
|
|
79
|
-
parts: parts,
|
|
80
|
-
expression: expression,
|
|
81
|
-
enclosingNamespaceNameLower: (_b = (_a = expression.findAncestor(reflection_1.isNamespaceStatement)) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript)) === null || _b === void 0 ? void 0 : _b.toLowerCase()
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return result;
|
|
86
|
-
});
|
|
87
|
-
outer: for (const info of expressionInfos) {
|
|
88
|
-
const firstNamespacePart = info.parts[0].name.text;
|
|
89
|
-
const firstNamespacePartLower = firstNamespacePart === null || firstNamespacePart === void 0 ? void 0 : firstNamespacePart.toLowerCase();
|
|
90
|
-
//get the namespace container (accounting for namespace-relative as well)
|
|
91
|
-
const namespaceContainer = scope.getNamespace(firstNamespacePartLower, info.enclosingNamespaceNameLower);
|
|
92
|
-
const isUsedAsType = this.checkIfUsedAsTypeExpression(info.expression);
|
|
93
|
-
let symbolType = SymbolTable_1.SymbolTypeFlag.runtime;
|
|
94
|
-
let oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.typetime;
|
|
95
|
-
if (isUsedAsType) {
|
|
96
|
-
// This is used in a TypeExpression - only look up types from SymbolTable
|
|
97
|
-
symbolType = SymbolTable_1.SymbolTypeFlag.typetime;
|
|
98
|
-
oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.runtime;
|
|
99
|
-
}
|
|
100
|
-
if (scope.program.options.enableTypeValidation) {
|
|
101
|
-
// Do a complete type check on all DottedGet and Variable expressions
|
|
102
|
-
// this will create a diagnostic if an invalid member is accessed
|
|
103
|
-
const typeChain = [];
|
|
104
|
-
let exprType = info.expression.getType({
|
|
105
|
-
flags: symbolType,
|
|
106
|
-
typeChain: typeChain
|
|
107
|
-
});
|
|
108
|
-
if (!exprType || !exprType.isResolvable()) {
|
|
109
|
-
if ((_a = info.expression.getType({ flags: oppositeSymbolType })) === null || _a === void 0 ? void 0 : _a.isResolvable()) {
|
|
110
|
-
const oppoSiteTypeChain = [];
|
|
111
|
-
const invalidlyUsedResolvedType = info.expression.getType({ flags: oppositeSymbolType, typeChain: oppoSiteTypeChain });
|
|
112
|
-
const typeChainScan = util_1.default.processTypeChain(oppoSiteTypeChain);
|
|
113
|
-
if (isUsedAsType) {
|
|
114
|
-
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsType(typeChainScan.fullChainName)), { range: info.expression.range, file: file }), 'When used in scope');
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable(invalidlyUsedResolvedType.toString())), { range: info.expression.range, file: file }), 'When used in scope');
|
|
118
|
-
}
|
|
119
|
-
continue;
|
|
49
|
+
const hasChangeInfo = this.event.changedFiles && this.event.changedSymbols;
|
|
50
|
+
let thisFileRequiresChangedSymbol = false;
|
|
51
|
+
for (let requiredSymbol of file.requiredSymbols) {
|
|
52
|
+
const changeSymbolSetForFlag = this.event.changedSymbols.get(requiredSymbol.flags);
|
|
53
|
+
if (util_1.default.setContainsUnresolvedSymbol(changeSymbolSetForFlag, requiredSymbol)) {
|
|
54
|
+
thisFileRequiresChangedSymbol = true;
|
|
120
55
|
}
|
|
121
|
-
const typeChainScan = util_1.default.processTypeChain(typeChain);
|
|
122
|
-
this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(typeChainScan.missingItemName, typeChainScan.fullNameOfMissingItem)), { range: typeChainScan.range }));
|
|
123
|
-
//skip to the next expression
|
|
124
|
-
continue;
|
|
125
56
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const firstPart = info.parts[0];
|
|
131
|
-
if (!(symbolTable === null || symbolTable === void 0 ? void 0 : symbolTable.hasSymbol((_b = firstPart.name) === null || _b === void 0 ? void 0 : _b.text, symbolType)) &&
|
|
132
|
-
!namespaceContainer) {
|
|
133
|
-
this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName((_c = firstPart.name) === null || _c === void 0 ? void 0 : _c.text)), { range: firstPart.name.range }));
|
|
134
|
-
//skip to the next expression
|
|
135
|
-
continue;
|
|
57
|
+
const thisFileHasChanges = this.event.changedFiles.includes(file);
|
|
58
|
+
if (hasChangeInfo && !thisFileRequiresChangedSymbol && !thisFileHasChanges) {
|
|
59
|
+
// this file does not require a symbol that has changed, and this file has not changed
|
|
60
|
+
return;
|
|
136
61
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
//if this isn't a namespace, skip it
|
|
140
|
-
if (!namespaceContainer && !enumStatement) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
//catch unknown namespace items
|
|
144
|
-
let entityName = firstNamespacePart;
|
|
145
|
-
let entityNameLower = firstNamespacePart.toLowerCase();
|
|
146
|
-
for (let i = 1; i < info.parts.length; i++) {
|
|
147
|
-
const part = info.parts[i];
|
|
148
|
-
entityName += '.' + part.name.text;
|
|
149
|
-
entityNameLower += '.' + part.name.text.toLowerCase();
|
|
150
|
-
//if this is an enum member, stop validating here to prevent errors further down the chain
|
|
151
|
-
if (scope.getEnumMemberFileLink(entityName, info.enclosingNamespaceNameLower)) {
|
|
152
|
-
break;
|
|
62
|
+
if (thisFileHasChanges) {
|
|
63
|
+
this.event.scope.clearAstSegmentDiagnosticsByFile(file);
|
|
153
64
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
this.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
65
|
+
const validationVisitor = (0, visitors_1.createVisitor)({
|
|
66
|
+
VariableExpression: (varExpr) => {
|
|
67
|
+
this.validateVariableAndDottedGetExpressions(file, varExpr);
|
|
68
|
+
},
|
|
69
|
+
DottedGetExpression: (dottedGet) => {
|
|
70
|
+
this.validateVariableAndDottedGetExpressions(file, dottedGet);
|
|
71
|
+
},
|
|
72
|
+
CallExpression: (functionCall) => {
|
|
73
|
+
this.validateFunctionCall(file, functionCall);
|
|
74
|
+
this.validateCreateObjectCall(file, functionCall);
|
|
75
|
+
},
|
|
76
|
+
ReturnStatement: (returnStatement) => {
|
|
77
|
+
this.validateReturnStatement(file, returnStatement);
|
|
78
|
+
},
|
|
79
|
+
DottedSetStatement: (dottedSetStmt) => {
|
|
80
|
+
this.validateDottedSetStatement(file, dottedSetStmt);
|
|
81
|
+
},
|
|
82
|
+
BinaryExpression: (binaryExpr) => {
|
|
83
|
+
this.validateBinaryExpression(file, binaryExpr);
|
|
84
|
+
},
|
|
85
|
+
UnaryExpression: (unaryExpr) => {
|
|
86
|
+
this.validateUnaryExpression(file, unaryExpr);
|
|
167
87
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
88
|
+
});
|
|
89
|
+
const segmentsToWalkForValidation = (thisFileHasChanges || !hasChangeInfo)
|
|
90
|
+
? file.validationSegmenter.segmentsForValidation // validate everything in the file
|
|
91
|
+
: file.getValidationSegments(this.event.changedSymbols); // validate only what's needed in the file
|
|
92
|
+
for (const segment of segmentsToWalkForValidation) {
|
|
93
|
+
this.currentSegmentBeingValidated = segment;
|
|
94
|
+
this.event.scope.clearAstSegmentDiagnostics(segment);
|
|
95
|
+
segment.walk(validationVisitor, {
|
|
96
|
+
walkMode: AstValidationSegmenter_1.InsideSegmentWalkMode
|
|
97
|
+
});
|
|
98
|
+
file.markSegmentAsValidated(segment);
|
|
173
99
|
}
|
|
174
100
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (scope.getNamespace(entityNameLower, info.enclosingNamespaceNameLower)) {
|
|
181
|
-
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('namespace')), { range: info.expression.range, file: file }), 'When used in scope');
|
|
182
|
-
}
|
|
183
|
-
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
isTypeKnown(exprType) {
|
|
104
|
+
let isKnownType = exprType === null || exprType === void 0 ? void 0 : exprType.isResolvable();
|
|
105
|
+
return isKnownType;
|
|
184
106
|
}
|
|
185
107
|
/**
|
|
186
|
-
*
|
|
187
|
-
* For example, all of these would return the enum: `SomeNamespace.SomeEnum.SomeMember`, SomeEnum.SomeMember, `SomeEnum`
|
|
108
|
+
* If this is the lhs of an assignment, we don't need to flag it as unresolved
|
|
188
109
|
*/
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
110
|
+
ignoreUnresolvedAssignmentLHS(expression, exprType, definingNode) {
|
|
111
|
+
var _a, _b;
|
|
112
|
+
if (!(0, reflection_1.isVariableExpression)(expression)) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
let assignmentAncestor;
|
|
116
|
+
if ((0, reflection_1.isAssignmentStatement)(definingNode) && definingNode.equals.kind === TokenKind_1.TokenKind.Equal) {
|
|
117
|
+
// this symbol was defined in a "normal" assignment (eg. not a compound assignment)
|
|
118
|
+
assignmentAncestor = definingNode;
|
|
119
|
+
return ((_a = assignmentAncestor === null || assignmentAncestor === void 0 ? void 0 : assignmentAncestor.name) === null || _a === void 0 ? void 0 : _a.text.toLowerCase()) === ((_b = expression === null || expression === void 0 ? void 0 : expression.name) === null || _b === void 0 ? void 0 : _b.text.toLowerCase());
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
assignmentAncestor = expression === null || expression === void 0 ? void 0 : expression.findAncestor(reflection_1.isAssignmentStatement);
|
|
123
|
+
}
|
|
124
|
+
return (assignmentAncestor === null || assignmentAncestor === void 0 ? void 0 : assignmentAncestor.name) === (expression === null || expression === void 0 ? void 0 : expression.name) && (0, reflection_1.isUnionType)(exprType);
|
|
199
125
|
}
|
|
200
126
|
/**
|
|
201
127
|
* Flag duplicate enums
|
|
@@ -236,7 +162,7 @@ class ScopeValidator {
|
|
|
236
162
|
diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateEnumDeclaration(this.event.scope.name, fullName)), { file: duplicateEnumInfo.file, range: duplicateEnumInfo.statement.tokens.name.range, relatedInformation: [{
|
|
237
163
|
message: 'Enum declared here',
|
|
238
164
|
location: util_1.default.createLocation(vscode_uri_1.URI.file(primaryEnum.file.srcPath).toString(), primaryEnum.statement.tokens.name.range)
|
|
239
|
-
}] }));
|
|
165
|
+
}], origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
240
166
|
}
|
|
241
167
|
}
|
|
242
168
|
this.event.scope.addDiagnostics(diagnostics);
|
|
@@ -247,57 +173,296 @@ class ScopeValidator {
|
|
|
247
173
|
* what these calls are supposed to look like, and this is a very common thing for brs devs to do, so just
|
|
248
174
|
* do this manually for now.
|
|
249
175
|
*/
|
|
250
|
-
|
|
251
|
-
var _a, _b, _c, _d, _e, _f
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
176
|
+
validateCreateObjectCall(file, call) {
|
|
177
|
+
var _a, _b, _c, _d, _e, _f;
|
|
178
|
+
//skip non CreateObject function calls
|
|
179
|
+
const callName = (_a = util_1.default.getAllDottedGetPartsAsString(call.callee)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
180
|
+
if (callName !== 'createobject' || !(0, reflection_1.isLiteralExpression)(call === null || call === void 0 ? void 0 : call.args[0])) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const firstParamToken = (_b = call === null || call === void 0 ? void 0 : call.args[0]) === null || _b === void 0 ? void 0 : _b.token;
|
|
184
|
+
const firstParamStringValue = (_c = firstParamToken === null || firstParamToken === void 0 ? void 0 : firstParamToken.text) === null || _c === void 0 ? void 0 : _c.replace(/"/g, '');
|
|
185
|
+
//if this is a `createObject('roSGNode'` call, only support known sg node types
|
|
186
|
+
if ((firstParamStringValue === null || firstParamStringValue === void 0 ? void 0 : firstParamStringValue.toLowerCase()) === 'rosgnode' && (0, reflection_1.isLiteralExpression)(call === null || call === void 0 ? void 0 : call.args[1])) {
|
|
187
|
+
const componentName = (_d = call === null || call === void 0 ? void 0 : call.args[1]) === null || _d === void 0 ? void 0 : _d.token;
|
|
188
|
+
//don't validate any components with a colon in their name (probably component libraries, but regular components can have them too).
|
|
189
|
+
if ((_e = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _e === void 0 ? void 0 : _e.includes(':')) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
//add diagnostic for unknown components
|
|
193
|
+
const unquotedComponentName = (_f = componentName === null || componentName === void 0 ? void 0 : componentName.text) === null || _f === void 0 ? void 0 : _f.replace(/"/g, '');
|
|
194
|
+
if (unquotedComponentName && !platformNodeNames.has(unquotedComponentName.toLowerCase()) && !this.event.program.getComponent(unquotedComponentName)) {
|
|
195
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownRoSGNode(unquotedComponentName)), { range: componentName.range }));
|
|
196
|
+
}
|
|
197
|
+
else if ((call === null || call === void 0 ? void 0 : call.args.length) !== 2) {
|
|
198
|
+
// roSgNode should only ever have 2 args in `createObject`
|
|
199
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.mismatchCreateObjectArgumentCount(firstParamStringValue, [2], call === null || call === void 0 ? void 0 : call.args.length)), { range: call.range }));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else if (!platformComponentNames.has(firstParamStringValue.toLowerCase())) {
|
|
203
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownBrightScriptComponent(firstParamStringValue)), { range: firstParamToken.range }));
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
// This is valid brightscript component
|
|
207
|
+
// Test for invalid arg counts
|
|
208
|
+
const brightScriptComponent = roku_types_1.components[firstParamStringValue.toLowerCase()];
|
|
209
|
+
// Valid arg counts for createObject are 1+ number of args for constructor
|
|
210
|
+
let validArgCounts = brightScriptComponent.constructors.map(cnstr => cnstr.params.length + 1);
|
|
211
|
+
if (validArgCounts.length === 0) {
|
|
212
|
+
// no constructors for this component, so createObject only takes 1 arg
|
|
213
|
+
validArgCounts = [1];
|
|
257
214
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
215
|
+
if (!validArgCounts.includes(call === null || call === void 0 ? void 0 : call.args.length)) {
|
|
216
|
+
// Incorrect number of arguments included in `createObject()`
|
|
217
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.mismatchCreateObjectArgumentCount(firstParamStringValue, validArgCounts, call === null || call === void 0 ? void 0 : call.args.length)), { range: call.range }));
|
|
218
|
+
}
|
|
219
|
+
// Test for deprecation
|
|
220
|
+
if (brightScriptComponent.isDeprecated) {
|
|
221
|
+
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.deprecatedBrightScriptComponent(firstParamStringValue, brightScriptComponent.deprecatedDescription)), { range: call.range }));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Detect calls to functions with the incorrect number of parameters, or wrong types of arguments
|
|
227
|
+
*/
|
|
228
|
+
validateFunctionCall(file, expression) {
|
|
229
|
+
var _a, _b;
|
|
230
|
+
const getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
231
|
+
let funcType = (_a = expression === null || expression === void 0 ? void 0 : expression.callee) === null || _a === void 0 ? void 0 : _a.getType(getTypeOptions);
|
|
232
|
+
if ((funcType === null || funcType === void 0 ? void 0 : funcType.isResolvable()) && (0, reflection_1.isClassType)(funcType)) {
|
|
233
|
+
// We're calling a class - get the constructor
|
|
234
|
+
funcType = funcType.getMemberType('new', getTypeOptions);
|
|
235
|
+
}
|
|
236
|
+
if ((funcType === null || funcType === void 0 ? void 0 : funcType.isResolvable()) && (0, reflection_1.isTypedFunctionType)(funcType)) {
|
|
237
|
+
//funcType.setName(expression.callee. .name);
|
|
238
|
+
//get min/max parameter count for callable
|
|
239
|
+
let minParams = 0;
|
|
240
|
+
let maxParams = 0;
|
|
241
|
+
for (let param of funcType.params) {
|
|
242
|
+
maxParams++;
|
|
243
|
+
//optional parameters must come last, so we can assume that minParams won't increase once we hit
|
|
244
|
+
//the first isOptional
|
|
245
|
+
if (param.isOptional !== true) {
|
|
246
|
+
minParams++;
|
|
266
247
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
248
|
+
}
|
|
249
|
+
if (funcType.isVariadic) {
|
|
250
|
+
// function accepts variable number of arguments
|
|
251
|
+
maxParams = Expression_1.CallExpression.MaximumArguments;
|
|
252
|
+
}
|
|
253
|
+
let expCallArgCount = expression.args.length;
|
|
254
|
+
if (expCallArgCount > maxParams || expCallArgCount < minParams) {
|
|
255
|
+
let minMaxParamsText = minParams === maxParams ? maxParams : `${minParams}-${maxParams}`;
|
|
256
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(minMaxParamsText, expCallArgCount)), { range: expression.callee.range,
|
|
257
|
+
//TODO detect end of expression call
|
|
258
|
+
file: file }));
|
|
259
|
+
}
|
|
260
|
+
let paramIndex = 0;
|
|
261
|
+
for (let arg of expression.args) {
|
|
262
|
+
const data = {};
|
|
263
|
+
let argType = arg.getType({ flags: SymbolTable_1.SymbolTypeFlag.runtime, data: data });
|
|
264
|
+
const paramType = (_b = funcType.params[paramIndex]) === null || _b === void 0 ? void 0 : _b.type;
|
|
265
|
+
if (!paramType) {
|
|
266
|
+
// unable to find a paramType -- maybe there are more args than params
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
if ((0, reflection_1.isCallableType)(paramType) && (0, reflection_1.isClassType)(argType) && (0, reflection_1.isClassStatement)(data.definingNode)) {
|
|
270
|
+
// the param is expecting a function, but we're passing a Class... are we actually passing the constructor? then we're ok!
|
|
271
|
+
const namespace = expression.findAncestor(reflection_1.isNamespaceStatement);
|
|
272
|
+
if (file.calleeIsKnownFunction(arg, namespace === null || namespace === void 0 ? void 0 : namespace.getName(Parser_1.ParseMode.BrighterScript))) {
|
|
273
|
+
argType = data.definingNode.getConstructorType();
|
|
274
|
+
}
|
|
271
275
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
this.
|
|
276
|
+
const compatibilityData = {};
|
|
277
|
+
if (!(paramType === null || paramType === void 0 ? void 0 : paramType.isTypeCompatible(argType, compatibilityData))) {
|
|
278
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.argumentTypeMismatch(argType.toString(), paramType.toString(), compatibilityData)), { range: arg.range,
|
|
279
|
+
//TODO detect end of expression call
|
|
280
|
+
file: file }));
|
|
275
281
|
}
|
|
282
|
+
paramIndex++;
|
|
276
283
|
}
|
|
277
|
-
|
|
278
|
-
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Detect return statements with incompatible types vs. declared return type
|
|
288
|
+
*/
|
|
289
|
+
validateReturnStatement(file, returnStmt) {
|
|
290
|
+
var _a;
|
|
291
|
+
const getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
292
|
+
let funcType = returnStmt.findAncestor(reflection_1.isFunctionExpression).getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
293
|
+
if ((0, reflection_1.isTypedFunctionType)(funcType)) {
|
|
294
|
+
const actualReturnType = (_a = returnStmt.value) === null || _a === void 0 ? void 0 : _a.getType(getTypeOptions);
|
|
295
|
+
const compatibilityData = {};
|
|
296
|
+
if (actualReturnType && !funcType.returnType.isTypeCompatible(actualReturnType, compatibilityData)) {
|
|
297
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.returnTypeMismatch(actualReturnType.toString(), funcType.returnType.toString(), compatibilityData)), { range: returnStmt.value.range, file: file }));
|
|
279
298
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Detect return statements with incompatible types vs. declared return type
|
|
303
|
+
*/
|
|
304
|
+
validateDottedSetStatement(file, dottedSetStmt) {
|
|
305
|
+
var _a, _b, _c;
|
|
306
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
307
|
+
const expectedLHSType = (_b = (_a = dottedSetStmt === null || dottedSetStmt === void 0 ? void 0 : dottedSetStmt.obj) === null || _a === void 0 ? void 0 : _a.getType(getTypeOpts)) === null || _b === void 0 ? void 0 : _b.getMemberType(dottedSetStmt.name.text, getTypeOpts);
|
|
308
|
+
const actualRHSType = (_c = dottedSetStmt === null || dottedSetStmt === void 0 ? void 0 : dottedSetStmt.value) === null || _c === void 0 ? void 0 : _c.getType(getTypeOpts);
|
|
309
|
+
const compatibilityData = {};
|
|
310
|
+
if ((expectedLHSType === null || expectedLHSType === void 0 ? void 0 : expectedLHSType.isResolvable()) && !(expectedLHSType === null || expectedLHSType === void 0 ? void 0 : expectedLHSType.isTypeCompatible(actualRHSType, compatibilityData))) {
|
|
311
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.assignmentTypeMismatch(actualRHSType.toString(), expectedLHSType.toString(), compatibilityData)), { range: dottedSetStmt.range, file: file }));
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Detect invalid use of a binary operator
|
|
316
|
+
*/
|
|
317
|
+
validateBinaryExpression(file, binaryExpr) {
|
|
318
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
319
|
+
if (util_1.default.isInTypeExpression(binaryExpr)) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
let leftType = binaryExpr.left.getType(getTypeOpts);
|
|
323
|
+
let rightType = binaryExpr.right.getType(getTypeOpts);
|
|
324
|
+
if (!leftType.isResolvable() || !rightType.isResolvable()) {
|
|
325
|
+
// Can not find the type. error handled elsewhere
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
let leftTypeToTest = leftType;
|
|
329
|
+
let rightTypeToTest = rightType;
|
|
330
|
+
if ((0, reflection_1.isEnumMemberType)(leftType) || (0, reflection_1.isEnumType)(leftType)) {
|
|
331
|
+
leftTypeToTest = leftType.underlyingType;
|
|
332
|
+
}
|
|
333
|
+
if ((0, reflection_1.isEnumMemberType)(rightType) || (0, reflection_1.isEnumType)(rightType)) {
|
|
334
|
+
rightTypeToTest = rightType.underlyingType;
|
|
335
|
+
}
|
|
336
|
+
if ((0, reflection_1.isUnionType)(leftType) || (0, reflection_1.isUnionType)(rightType)) {
|
|
337
|
+
// TODO: it is possible to validate based on innerTypes, but more complicated
|
|
338
|
+
// Because you need to verify each combination of types
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const leftIsPrimitive = (0, reflection_1.isPrimitiveType)(leftTypeToTest);
|
|
342
|
+
const rightIsPrimitive = (0, reflection_1.isPrimitiveType)(rightTypeToTest);
|
|
343
|
+
const leftIsAny = (0, reflection_1.isDynamicType)(leftTypeToTest) || (0, reflection_1.isObjectType)(leftTypeToTest);
|
|
344
|
+
const rightIsAny = (0, reflection_1.isDynamicType)(rightTypeToTest) || (0, reflection_1.isObjectType)(rightTypeToTest);
|
|
345
|
+
if (leftIsAny && rightIsAny) {
|
|
346
|
+
// both operands are basically "any" type... ignore;
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
else if ((leftIsAny && rightIsPrimitive) || (leftIsPrimitive && rightIsAny)) {
|
|
350
|
+
// one operand is basically "any" type... ignore;
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const opResult = util_1.default.binaryOperatorResultType(leftTypeToTest, binaryExpr.operator, rightTypeToTest);
|
|
354
|
+
if ((0, reflection_1.isDynamicType)(opResult)) {
|
|
355
|
+
// if the result was dynamic, that means there wasn't a valid operation
|
|
356
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(binaryExpr.operator.text, leftType.toString(), rightType.toString())), { range: binaryExpr.range, file: file }));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Detect invalid use of a Unary operator
|
|
361
|
+
*/
|
|
362
|
+
validateUnaryExpression(file, unaryExpr) {
|
|
363
|
+
const getTypeOpts = { flags: SymbolTable_1.SymbolTypeFlag.runtime };
|
|
364
|
+
let rightType = unaryExpr.right.getType(getTypeOpts);
|
|
365
|
+
if (!rightType.isResolvable()) {
|
|
366
|
+
// Can not find the type. error handled elsewhere
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
let rightTypeToTest = rightType;
|
|
370
|
+
if ((0, reflection_1.isEnumMemberType)(rightType)) {
|
|
371
|
+
rightTypeToTest = rightType.underlyingType;
|
|
372
|
+
}
|
|
373
|
+
if ((0, reflection_1.isUnionType)(rightTypeToTest)) {
|
|
374
|
+
// TODO: it is possible to validate based on innerTypes, but more complicated
|
|
375
|
+
// Because you need to verify each combination of types
|
|
376
|
+
}
|
|
377
|
+
else if ((0, reflection_1.isDynamicType)(rightTypeToTest) || (0, reflection_1.isObjectType)(rightTypeToTest)) {
|
|
378
|
+
// operand is basically "any" type... ignore;
|
|
379
|
+
}
|
|
380
|
+
else if ((0, reflection_1.isPrimitiveType)(rightType)) {
|
|
381
|
+
const opResult = util_1.default.unaryOperatorResultType(unaryExpr.operator, rightTypeToTest);
|
|
382
|
+
if ((0, reflection_1.isDynamicType)(opResult)) {
|
|
383
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(unaryExpr.operator.text, rightType.toString())), { range: unaryExpr.range, file: file }));
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
// rhs is not a primitive, so no binary operator is allowed
|
|
388
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.operatorTypeMismatch(unaryExpr.operator.text, rightType.toString())), { range: unaryExpr.range, file: file }));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
validateVariableAndDottedGetExpressions(file, expression) {
|
|
392
|
+
var _a, _b;
|
|
393
|
+
if ((0, reflection_1.isDottedGetExpression)(expression.parent)) {
|
|
394
|
+
// We validate dottedGetExpressions at the top-most level
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if ((0, reflection_1.isVariableExpression)(expression)) {
|
|
398
|
+
if ((0, reflection_1.isAssignmentStatement)(expression.parent) && expression.parent.name === expression.name) {
|
|
399
|
+
// Don't validate LHS of assignments
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
else if ((0, reflection_1.isNamespaceStatement)(expression.parent)) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
let symbolType = SymbolTable_1.SymbolTypeFlag.runtime;
|
|
407
|
+
let oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.typetime;
|
|
408
|
+
const isUsedAsType = util_1.default.isInTypeExpression(expression);
|
|
409
|
+
if (isUsedAsType) {
|
|
410
|
+
// This is used in a TypeExpression - only look up types from SymbolTable
|
|
411
|
+
symbolType = SymbolTable_1.SymbolTypeFlag.typetime;
|
|
412
|
+
oppositeSymbolType = SymbolTable_1.SymbolTypeFlag.runtime;
|
|
413
|
+
}
|
|
414
|
+
// Do a complete type check on all DottedGet and Variable expressions
|
|
415
|
+
// this will create a diagnostic if an invalid member is accessed
|
|
416
|
+
const typeChain = [];
|
|
417
|
+
const typeData = {};
|
|
418
|
+
let exprType = expression.getType({
|
|
419
|
+
flags: symbolType,
|
|
420
|
+
typeChain: typeChain,
|
|
421
|
+
data: typeData
|
|
422
|
+
});
|
|
423
|
+
const shouldIgnoreLHS = this.ignoreUnresolvedAssignmentLHS(expression, exprType, typeData === null || typeData === void 0 ? void 0 : typeData.definingNode);
|
|
424
|
+
if (!this.isTypeKnown(exprType) && !shouldIgnoreLHS) {
|
|
425
|
+
if ((_a = expression.getType({ flags: oppositeSymbolType })) === null || _a === void 0 ? void 0 : _a.isResolvable()) {
|
|
426
|
+
const oppoSiteTypeChain = [];
|
|
427
|
+
const invalidlyUsedResolvedType = expression.getType({ flags: oppositeSymbolType, typeChain: oppoSiteTypeChain });
|
|
428
|
+
const typeChainScan = util_1.default.processTypeChain(oppoSiteTypeChain);
|
|
429
|
+
if (isUsedAsType) {
|
|
430
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsType(typeChainScan.fullChainName)), { range: expression.range, file: file }));
|
|
293
431
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
this.addDiagnosticOnce(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.deprecatedBrightScriptComponent(firstParamStringValue, brightScriptComponent.deprecatedDescription)), { range: call.range }));
|
|
432
|
+
else {
|
|
433
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable(invalidlyUsedResolvedType.toString())), { range: expression.range, file: file }));
|
|
297
434
|
}
|
|
298
435
|
}
|
|
436
|
+
else {
|
|
437
|
+
const typeChainScan = util_1.default.processTypeChain(typeChain);
|
|
438
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.cannotFindName(typeChainScan.itemName, typeChainScan.fullNameOfItem)), { range: typeChainScan.range }));
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (isUsedAsType) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
const lastTypeInfo = typeChain[typeChain.length - 1];
|
|
445
|
+
const parentTypeInfo = typeChain[typeChain.length - 2];
|
|
446
|
+
if ((0, reflection_1.isNamespaceType)(exprType)) {
|
|
447
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('namespace')), { range: expression.range, file: file }));
|
|
448
|
+
}
|
|
449
|
+
else if ((0, reflection_1.isEnumType)(exprType)) {
|
|
450
|
+
const enumStatement = this.event.scope.getEnum(util_1.default.getAllDottedGetPartsAsString(expression));
|
|
451
|
+
if (enumStatement) {
|
|
452
|
+
// there's an enum with this name
|
|
453
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('enum')), { range: expression.range, file: file }));
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
else if ((0, reflection_1.isDynamicType)(exprType) && (0, reflection_1.isEnumType)(parentTypeInfo === null || parentTypeInfo === void 0 ? void 0 : parentTypeInfo.type) && (0, reflection_1.isDottedGetExpression)(expression)) {
|
|
457
|
+
const enumFileLink = this.event.scope.getEnumFileLink(util_1.default.getAllDottedGetPartsAsString(expression.obj));
|
|
458
|
+
const typeChainScanForParent = util_1.default.processTypeChain(typeChain.slice(0, -1));
|
|
459
|
+
if (enumFileLink) {
|
|
460
|
+
this.addMultiScopeDiagnostic(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.unknownEnumValue(lastTypeInfo === null || lastTypeInfo === void 0 ? void 0 : lastTypeInfo.name, typeChainScanForParent.fullChainName)), { range: lastTypeInfo === null || lastTypeInfo === void 0 ? void 0 : lastTypeInfo.range, relatedInformation: [{
|
|
461
|
+
message: 'Enum declared here',
|
|
462
|
+
location: util_1.default.createLocation(vscode_uri_1.URI.file(enumFileLink === null || enumFileLink === void 0 ? void 0 : enumFileLink.file.srcPath).toString(), (_b = enumFileLink === null || enumFileLink === void 0 ? void 0 : enumFileLink.item) === null || _b === void 0 ? void 0 : _b.tokens.name.range)
|
|
463
|
+
}] }));
|
|
464
|
+
}
|
|
299
465
|
}
|
|
300
|
-
this.event.scope.addDiagnostics(diagnostics);
|
|
301
466
|
}
|
|
302
467
|
/**
|
|
303
468
|
* Adds a diagnostic to the first scope for this key. Prevents duplicate diagnostics
|
|
@@ -305,35 +470,58 @@ class ScopeValidator {
|
|
|
305
470
|
*/
|
|
306
471
|
addDiagnosticOnce(diagnostic) {
|
|
307
472
|
this.onceCache.getOrAdd(`${diagnostic.code}-${diagnostic.message}-${util_1.default.rangeToString(diagnostic.range)}`, () => {
|
|
308
|
-
|
|
473
|
+
const diagnosticWithOrigin = Object.assign({}, diagnostic);
|
|
474
|
+
if (!diagnosticWithOrigin.origin) {
|
|
475
|
+
// diagnostic does not have origin.
|
|
476
|
+
// set the origin to the current astSegment
|
|
477
|
+
diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
|
|
478
|
+
diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
|
|
479
|
+
}
|
|
480
|
+
this.event.scope.addDiagnostics([diagnosticWithOrigin]);
|
|
309
481
|
return true;
|
|
310
482
|
});
|
|
311
483
|
}
|
|
312
484
|
addDiagnostic(diagnostic) {
|
|
313
|
-
|
|
485
|
+
const diagnosticWithOrigin = Object.assign({}, diagnostic);
|
|
486
|
+
if (!diagnosticWithOrigin.origin) {
|
|
487
|
+
// diagnostic does not have origin.
|
|
488
|
+
// set the origin to the current astSegment
|
|
489
|
+
diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
|
|
490
|
+
diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
|
|
491
|
+
}
|
|
492
|
+
this.event.scope.addDiagnostics([diagnosticWithOrigin]);
|
|
314
493
|
}
|
|
315
494
|
/**
|
|
316
495
|
* Add a diagnostic (to the first scope) that will have `relatedInformation` for each affected scope
|
|
317
496
|
*/
|
|
318
|
-
addMultiScopeDiagnostic(diagnostic
|
|
319
|
-
var _a, _b;
|
|
497
|
+
addMultiScopeDiagnostic(diagnostic) {
|
|
498
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
320
499
|
diagnostic = this.multiScopeCache.getOrAdd(`${(_a = diagnostic.file) === null || _a === void 0 ? void 0 : _a.srcPath}-${diagnostic.code}-${diagnostic.message}-${util_1.default.rangeToString(diagnostic.range)}`, () => {
|
|
321
500
|
if (!diagnostic.relatedInformation) {
|
|
322
501
|
diagnostic.relatedInformation = [];
|
|
323
502
|
}
|
|
324
|
-
|
|
325
|
-
|
|
503
|
+
const diagnosticWithOrigin = Object.assign({}, diagnostic);
|
|
504
|
+
if (!diagnosticWithOrigin.origin) {
|
|
505
|
+
// diagnostic does not have origin.
|
|
506
|
+
// set the origin to the current astSegment
|
|
507
|
+
diagnosticWithOrigin.origin = interfaces_1.DiagnosticOrigin.ASTSegment;
|
|
508
|
+
diagnosticWithOrigin.astSegment = this.currentSegmentBeingValidated;
|
|
509
|
+
}
|
|
510
|
+
this.addDiagnostic(diagnosticWithOrigin);
|
|
511
|
+
return diagnosticWithOrigin;
|
|
326
512
|
});
|
|
327
|
-
const info = {
|
|
328
|
-
message: `${message} '${this.event.scope.name}'`
|
|
329
|
-
};
|
|
330
513
|
if ((0, reflection_1.isXmlScope)(this.event.scope) && ((_b = this.event.scope.xmlFile) === null || _b === void 0 ? void 0 : _b.srcPath)) {
|
|
331
|
-
|
|
514
|
+
diagnostic.relatedInformation.push({
|
|
515
|
+
message: `In component scope '${(_e = (_d = (_c = this.event.scope) === null || _c === void 0 ? void 0 : _c.xmlFile) === null || _d === void 0 ? void 0 : _d.componentName) === null || _e === void 0 ? void 0 : _e.text}'`,
|
|
516
|
+
location: util_1.default.createLocation(vscode_uri_1.URI.file(this.event.scope.xmlFile.srcPath).toString(), (_o = (_m = (_l = (_k = (_j = (_h = (_g = (_f = this.event.scope) === null || _f === void 0 ? void 0 : _f.xmlFile) === null || _g === void 0 ? void 0 : _g.ast) === null || _h === void 0 ? void 0 : _h.componentElement) === null || _j === void 0 ? void 0 : _j.getAttribute('name')) === null || _k === void 0 ? void 0 : _k.tokens) === null || _l === void 0 ? void 0 : _l.value) === null || _m === void 0 ? void 0 : _m.range) !== null && _o !== void 0 ? _o : util_1.default.createRange(0, 0, 0, 10))
|
|
517
|
+
});
|
|
332
518
|
}
|
|
333
519
|
else {
|
|
334
|
-
|
|
520
|
+
diagnostic.relatedInformation.push({
|
|
521
|
+
message: `In scope '${this.event.scope.name}'`,
|
|
522
|
+
location: util_1.default.createLocation(vscode_uri_1.URI.file(diagnostic.file.srcPath).toString(), diagnostic.range)
|
|
523
|
+
});
|
|
335
524
|
}
|
|
336
|
-
diagnostic.relatedInformation.push(info);
|
|
337
525
|
}
|
|
338
526
|
}
|
|
339
527
|
exports.ScopeValidator = ScopeValidator;
|