brighterscript 0.66.0-alpha.1 → 0.66.0-alpha.10
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 +215 -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 +637 -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 +442 -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 +128 -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 +243 -293
- 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 +157 -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
package/dist/Scope.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Scope = void 0;
|
|
4
4
|
const path = require("path");
|
|
5
|
-
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
6
5
|
const chalk_1 = require("chalk");
|
|
7
6
|
const DiagnosticMessages_1 = require("./DiagnosticMessages");
|
|
7
|
+
const interfaces_1 = require("./interfaces");
|
|
8
8
|
const ClassValidator_1 = require("./validators/ClassValidator");
|
|
9
9
|
const Parser_1 = require("./parser/Parser");
|
|
10
10
|
const util_1 = require("./util");
|
|
@@ -15,6 +15,17 @@ const Logger_1 = require("./Logger");
|
|
|
15
15
|
const reflection_1 = require("./astUtils/reflection");
|
|
16
16
|
const SymbolTable_1 = require("./SymbolTable");
|
|
17
17
|
const NamespaceType_1 = require("./types/NamespaceType");
|
|
18
|
+
const ReferenceType_1 = require("./types/ReferenceType");
|
|
19
|
+
const UnionType_1 = require("./types/UnionType");
|
|
20
|
+
const AssociativeArrayType_1 = require("./types/AssociativeArrayType");
|
|
21
|
+
const AstNode_1 = require("./parser/AstNode");
|
|
22
|
+
const visitors_1 = require("./astUtils/visitors");
|
|
23
|
+
/**
|
|
24
|
+
* Assign some few factories to the SymbolTable to prevent cyclical imports. This file seems like the most intuitive place to do the linking
|
|
25
|
+
* since Scope will be used by pretty much everything
|
|
26
|
+
*/
|
|
27
|
+
SymbolTable_1.SymbolTable.referenceTypeFactory = ReferenceType_1.referenceTypeFactory;
|
|
28
|
+
SymbolTable_1.SymbolTable.unionTypeFactory = UnionType_1.unionTypeFactory;
|
|
18
29
|
/**
|
|
19
30
|
* A class to keep track of all declarations within a given scope (like source scope, component scope)
|
|
20
31
|
*/
|
|
@@ -28,6 +39,11 @@ class Scope {
|
|
|
28
39
|
* The list of diagnostics found specifically for this scope. Individual file diagnostics are stored on the files themselves.
|
|
29
40
|
*/
|
|
30
41
|
this.diagnostics = [];
|
|
42
|
+
/**
|
|
43
|
+
* A list of functions that will be called whenever `unlinkSymbolTable` is called
|
|
44
|
+
*/
|
|
45
|
+
this.linkSymbolTableDisposables = [];
|
|
46
|
+
this.symbolsAddedDuringLinking = [];
|
|
31
47
|
this.isValidated = false;
|
|
32
48
|
//used for improved logging performance
|
|
33
49
|
this._debugLogComponentName = `Scope '${chalk_1.default.redBright(this.name)}'`;
|
|
@@ -41,6 +57,20 @@ class Scope {
|
|
|
41
57
|
* "namea", "namea.nameb", "namea.nameb.namec"
|
|
42
58
|
*/
|
|
43
59
|
get namespaceLookup() {
|
|
60
|
+
let allFilesValidated = true;
|
|
61
|
+
for (const file of this.getAllFiles()) {
|
|
62
|
+
if ((0, reflection_1.isBrsFile)(file) && !file.hasTypedef) {
|
|
63
|
+
allFilesValidated = allFilesValidated && file.isValidated;
|
|
64
|
+
if (!allFilesValidated) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!allFilesValidated) {
|
|
70
|
+
// This is not fit to cache
|
|
71
|
+
// Since the files have not been validated, all namespace info might not have been available
|
|
72
|
+
return this.buildNamespaceLookup();
|
|
73
|
+
}
|
|
44
74
|
return this.cache.getOrAdd('namespaceLookup', () => this.buildNamespaceLookup());
|
|
45
75
|
}
|
|
46
76
|
/**
|
|
@@ -59,6 +89,20 @@ class Scope {
|
|
|
59
89
|
}
|
|
60
90
|
return ns;
|
|
61
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Get a NamespaceContainer by its name, looking for a fully qualified version first, then global version next if not found
|
|
94
|
+
*/
|
|
95
|
+
getNamespacesWithRoot(rootName, containingNamespace) {
|
|
96
|
+
const nameLower = rootName === null || rootName === void 0 ? void 0 : rootName.toLowerCase();
|
|
97
|
+
const lookup = this.namespaceLookup;
|
|
98
|
+
const lookupKeys = [...lookup.keys()];
|
|
99
|
+
let lookupName = nameLower;
|
|
100
|
+
if (containingNamespace) {
|
|
101
|
+
lookupName = `${containingNamespace === null || containingNamespace === void 0 ? void 0 : containingNamespace.toLowerCase()}.${nameLower}`;
|
|
102
|
+
}
|
|
103
|
+
const nsList = lookupKeys.filter(key => key.startsWith(lookupName)).map(key => lookup.get(key));
|
|
104
|
+
return nsList;
|
|
105
|
+
}
|
|
62
106
|
/**
|
|
63
107
|
* Get the class with the specified name.
|
|
64
108
|
* @param className - The class name, including the namespace of the class if possible
|
|
@@ -140,7 +184,7 @@ class Scope {
|
|
|
140
184
|
var _a, _b;
|
|
141
185
|
let lowerNameParts = (_a = enumMemberName === null || enumMemberName === void 0 ? void 0 : enumMemberName.toLowerCase()) === null || _a === void 0 ? void 0 : _a.split('.');
|
|
142
186
|
let memberName = (_b = lowerNameParts === null || lowerNameParts === void 0 ? void 0 : lowerNameParts.splice(lowerNameParts.length - 1, 1)) === null || _b === void 0 ? void 0 : _b[0];
|
|
143
|
-
let lowerName = lowerNameParts === null || lowerNameParts === void 0 ? void 0 : lowerNameParts.join('.')
|
|
187
|
+
let lowerName = lowerNameParts === null || lowerNameParts === void 0 ? void 0 : lowerNameParts.join('.');
|
|
144
188
|
const enumMap = this.getEnumMap();
|
|
145
189
|
let enumeration = enumMap.get(util_1.util.getFullyQualifiedClassName(lowerName, containingNamespace === null || containingNamespace === void 0 ? void 0 : containingNamespace.toLowerCase()));
|
|
146
190
|
//if we couldn't find the enum by its full namespaced name, look for a global enum with that name
|
|
@@ -168,6 +212,24 @@ class Scope {
|
|
|
168
212
|
}
|
|
169
213
|
return result;
|
|
170
214
|
}
|
|
215
|
+
getAllFileLinks(name, containingNamespace) {
|
|
216
|
+
var _a, _b, _c, _d, _e, _f;
|
|
217
|
+
let links = [];
|
|
218
|
+
links.push((_a = this.getClassFileLink(name)) !== null && _a !== void 0 ? _a : this.getClassFileLink(name, containingNamespace), (_b = this.getInterfaceFileLink(name)) !== null && _b !== void 0 ? _b : this.getInterfaceFileLink(name, containingNamespace), (_c = this.getConstFileLink(name)) !== null && _c !== void 0 ? _c : this.getConstFileLink(name, containingNamespace), (_d = this.getEnumFileLink(name)) !== null && _d !== void 0 ? _d : this.getEnumFileLink(name, containingNamespace));
|
|
219
|
+
const nameSpaces = this.getNamespacesWithRoot(name, containingNamespace);
|
|
220
|
+
if ((nameSpaces === null || nameSpaces === void 0 ? void 0 : nameSpaces.length) > 0) {
|
|
221
|
+
const nsContainersWithStatement = (_e = nameSpaces.filter(nsContainer => { var _a; return ((_a = nsContainer === null || nsContainer === void 0 ? void 0 : nsContainer.namespaceStatements) === null || _a === void 0 ? void 0 : _a.length) > 0; })) === null || _e === void 0 ? void 0 : _e[0];
|
|
222
|
+
if (nsContainersWithStatement) {
|
|
223
|
+
links.push({ item: (_f = nsContainersWithStatement === null || nsContainersWithStatement === void 0 ? void 0 : nsContainersWithStatement.namespaceStatements) === null || _f === void 0 ? void 0 : _f[0], file: nsContainersWithStatement === null || nsContainersWithStatement === void 0 ? void 0 : nsContainersWithStatement.file });
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
const callable = this.getCallableByName(name);
|
|
227
|
+
if (callable) {
|
|
228
|
+
links.push({ item: callable.functionStatement, file: callable.file });
|
|
229
|
+
}
|
|
230
|
+
// remove empty links
|
|
231
|
+
return links.filter(link => link);
|
|
232
|
+
}
|
|
171
233
|
/**
|
|
172
234
|
* Get a map of all enums by their member name.
|
|
173
235
|
* The keys are lower-case fully-qualified paths to the enum and its member. For example:
|
|
@@ -216,13 +278,12 @@ class Scope {
|
|
|
216
278
|
return this.cache.getOrAdd('classMap', () => {
|
|
217
279
|
const map = new Map();
|
|
218
280
|
this.enumerateBrsFiles((file) => {
|
|
219
|
-
var _a;
|
|
220
281
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
221
282
|
for (let cls of file.parser.references.classStatements) {
|
|
222
|
-
const
|
|
283
|
+
const className = cls.getName(Parser_1.ParseMode.BrighterScript);
|
|
223
284
|
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
224
|
-
if (
|
|
225
|
-
map.set(
|
|
285
|
+
if (className) {
|
|
286
|
+
map.set(className.toLowerCase(), { item: cls, file: file });
|
|
226
287
|
}
|
|
227
288
|
}
|
|
228
289
|
}
|
|
@@ -238,13 +299,12 @@ class Scope {
|
|
|
238
299
|
return this.cache.getOrAdd('interfaceMap', () => {
|
|
239
300
|
const map = new Map();
|
|
240
301
|
this.enumerateBrsFiles((file) => {
|
|
241
|
-
var _a;
|
|
242
302
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
243
303
|
for (let iface of file.parser.references.interfaceStatements) {
|
|
244
|
-
const
|
|
304
|
+
const ifaceName = iface.getName(Parser_1.ParseMode.BrighterScript);
|
|
245
305
|
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
246
|
-
if (
|
|
247
|
-
map.set(
|
|
306
|
+
if (ifaceName) {
|
|
307
|
+
map.set(ifaceName.toLowerCase(), { item: iface, file: file });
|
|
248
308
|
}
|
|
249
309
|
}
|
|
250
310
|
}
|
|
@@ -261,10 +321,9 @@ class Scope {
|
|
|
261
321
|
const map = new Map();
|
|
262
322
|
this.enumerateBrsFiles((file) => {
|
|
263
323
|
for (let enumStmt of file.parser.references.enumStatements) {
|
|
264
|
-
const lowerEnumName = enumStmt.fullName.toLowerCase();
|
|
265
324
|
//only track enums with a defined name (i.e. exclude nameless malformed enums)
|
|
266
|
-
if (
|
|
267
|
-
map.set(
|
|
325
|
+
if (enumStmt.fullName) {
|
|
326
|
+
map.set(enumStmt.fullName.toLowerCase(), { item: enumStmt, file: file });
|
|
268
327
|
}
|
|
269
328
|
}
|
|
270
329
|
});
|
|
@@ -280,10 +339,9 @@ class Scope {
|
|
|
280
339
|
const map = new Map();
|
|
281
340
|
this.enumerateBrsFiles((file) => {
|
|
282
341
|
for (let stmt of file.parser.references.constStatements) {
|
|
283
|
-
const lowerEnumName = stmt.fullName.toLowerCase();
|
|
284
342
|
//only track enums with a defined name (i.e. exclude nameless malformed enums)
|
|
285
|
-
if (
|
|
286
|
-
map.set(
|
|
343
|
+
if (stmt.fullName) {
|
|
344
|
+
map.set(stmt.fullName.toLowerCase(), { item: stmt, file: file });
|
|
287
345
|
}
|
|
288
346
|
}
|
|
289
347
|
});
|
|
@@ -348,14 +406,14 @@ class Scope {
|
|
|
348
406
|
}
|
|
349
407
|
/**
|
|
350
408
|
* Get the file from this scope with the given path.
|
|
351
|
-
* @param filePath can be a srcPath or
|
|
409
|
+
* @param filePath can be a srcPath or destPath
|
|
352
410
|
* @param normalizePath should this function repair and standardize the path? Passing false should have a performance boost if you can guarantee your path is already sanitized
|
|
353
411
|
*/
|
|
354
412
|
getFile(filePath, normalizePath = true) {
|
|
355
413
|
if (typeof filePath !== 'string') {
|
|
356
414
|
return undefined;
|
|
357
415
|
}
|
|
358
|
-
const key = path.isAbsolute(filePath) ? 'srcPath' : '
|
|
416
|
+
const key = path.isAbsolute(filePath) ? 'srcPath' : 'destPath';
|
|
359
417
|
let map = this.cache.getOrAdd('fileMaps-srcPath', () => {
|
|
360
418
|
const result = new Map();
|
|
361
419
|
for (const file of this.getAllFiles()) {
|
|
@@ -396,26 +454,26 @@ class Scope {
|
|
|
396
454
|
}
|
|
397
455
|
}
|
|
398
456
|
}
|
|
399
|
-
this.logDebug('getAllFiles', () => result.map(x => x.
|
|
457
|
+
this.logDebug('getAllFiles', () => result.map(x => x.destPath));
|
|
400
458
|
return result;
|
|
401
459
|
});
|
|
402
460
|
}
|
|
403
461
|
/**
|
|
404
|
-
* Get the list of errors for this scope. It's calculated on the fly, so
|
|
405
|
-
* call this sparingly.
|
|
462
|
+
* Get the list of errors for this scope. It's calculated on the fly, so call this sparingly.
|
|
406
463
|
*/
|
|
407
464
|
getDiagnostics() {
|
|
408
|
-
let diagnosticLists = [this.diagnostics];
|
|
409
465
|
//add diagnostics from every referenced file
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
466
|
+
const diagnostics = [
|
|
467
|
+
//diagnostics raised on this scope
|
|
468
|
+
...this.diagnostics,
|
|
469
|
+
//get diagnostics from all files
|
|
470
|
+
...this.getOwnFiles().map(x => { var _a; return (_a = x.diagnostics) !== null && _a !== void 0 ? _a : []; }).flat()
|
|
471
|
+
]
|
|
472
|
+
//exclude diagnostics that match any of the comment flags
|
|
473
|
+
.filter((x) => {
|
|
415
474
|
return !util_1.util.diagnosticIsSuppressed(x);
|
|
416
475
|
});
|
|
417
|
-
|
|
418
|
-
return filteredDiagnostics;
|
|
476
|
+
return diagnostics;
|
|
419
477
|
}
|
|
420
478
|
addDiagnostics(diagnostics) {
|
|
421
479
|
this.diagnostics.push(...diagnostics);
|
|
@@ -473,7 +531,7 @@ class Scope {
|
|
|
473
531
|
const files = this.getOwnFiles();
|
|
474
532
|
for (const file of files) {
|
|
475
533
|
//either XML components or files without a typedef
|
|
476
|
-
if ((0, reflection_1.isXmlFile)(file) || !file.hasTypedef) {
|
|
534
|
+
if ((0, reflection_1.isXmlFile)(file) || ((0, reflection_1.isBrsFile)(file) && !file.hasTypedef)) {
|
|
477
535
|
callback(file);
|
|
478
536
|
}
|
|
479
537
|
}
|
|
@@ -484,14 +542,16 @@ class Scope {
|
|
|
484
542
|
*/
|
|
485
543
|
getOwnCallables() {
|
|
486
544
|
let result = [];
|
|
487
|
-
this.logDebug('getOwnCallables() files: ', () => this.getOwnFiles().map(x => x.
|
|
545
|
+
this.logDebug('getOwnCallables() files: ', () => this.getOwnFiles().map(x => x.destPath));
|
|
488
546
|
//get callables from own files
|
|
489
547
|
this.enumerateOwnFiles((file) => {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
548
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
549
|
+
for (let callable of file.callables) {
|
|
550
|
+
result.push({
|
|
551
|
+
callable: callable,
|
|
552
|
+
scope: this
|
|
553
|
+
});
|
|
554
|
+
}
|
|
495
555
|
}
|
|
496
556
|
});
|
|
497
557
|
return result;
|
|
@@ -499,64 +559,27 @@ class Scope {
|
|
|
499
559
|
/**
|
|
500
560
|
* Builds a tree of namespace objects
|
|
501
561
|
*/
|
|
502
|
-
buildNamespaceLookup() {
|
|
562
|
+
buildNamespaceLookup(options = { okToCache: true }) {
|
|
503
563
|
let namespaceLookup = new Map();
|
|
564
|
+
options.okToCache = true;
|
|
504
565
|
this.enumerateBrsFiles((file) => {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
for (let part of nameParts) {
|
|
513
|
-
loopName = loopName === null ? part : `${loopName}.${part}`;
|
|
514
|
-
let lowerLoopName = loopName.toLowerCase();
|
|
515
|
-
if (!namespaceLookup.has(lowerLoopName)) {
|
|
516
|
-
namespaceLookup.set(lowerLoopName, {
|
|
517
|
-
file: file,
|
|
518
|
-
fullName: loopName,
|
|
519
|
-
nameRange: namespaceStatement.nameExpression.range,
|
|
520
|
-
lastPartName: part,
|
|
521
|
-
namespaces: new Map(),
|
|
522
|
-
classStatements: {},
|
|
523
|
-
functionStatements: {},
|
|
524
|
-
enumStatements: new Map(),
|
|
525
|
-
constStatements: new Map(),
|
|
526
|
-
statements: [],
|
|
527
|
-
symbolTable: new SymbolTable_1.SymbolTable(`Namespace Aggregate: '${loopName}'`, () => this.symbolTable)
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
let ns = namespaceLookup.get(name.toLowerCase());
|
|
532
|
-
ns.statements.push(...namespaceStatement.body.statements);
|
|
533
|
-
for (let statement of namespaceStatement.body.statements) {
|
|
534
|
-
if ((0, reflection_1.isClassStatement)(statement) && statement.name) {
|
|
535
|
-
ns.classStatements[statement.name.text.toLowerCase()] = statement;
|
|
536
|
-
}
|
|
537
|
-
else if ((0, reflection_1.isFunctionStatement)(statement) && statement.name) {
|
|
538
|
-
ns.functionStatements[statement.name.text.toLowerCase()] = statement;
|
|
539
|
-
}
|
|
540
|
-
else if ((0, reflection_1.isEnumStatement)(statement) && statement.fullName) {
|
|
541
|
-
ns.enumStatements.set(statement.fullName.toLowerCase(), statement);
|
|
542
|
-
}
|
|
543
|
-
else if ((0, reflection_1.isConstStatement)(statement) && statement.fullName) {
|
|
544
|
-
ns.constStatements.set(statement.fullName.toLowerCase(), statement);
|
|
545
|
-
}
|
|
566
|
+
options.okToCache = options.okToCache && file.isValidated;
|
|
567
|
+
const fileNamespaceLookup = file.getNamespaceLookupObject();
|
|
568
|
+
for (const [lowerNamespaceName, nsContainer] of fileNamespaceLookup) {
|
|
569
|
+
if (!namespaceLookup.has(lowerNamespaceName)) {
|
|
570
|
+
const clonedNsContainer = Object.assign(Object.assign({}, nsContainer), { namespaceStatements: [...nsContainer.namespaceStatements], symbolTable: new SymbolTable_1.SymbolTable(`Namespace Aggregate: '${nsContainer.fullName}'`) });
|
|
571
|
+
clonedNsContainer.symbolTable.mergeSymbolTable(nsContainer.symbolTable);
|
|
572
|
+
namespaceLookup.set(lowerNamespaceName, clonedNsContainer);
|
|
546
573
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
parts.pop();
|
|
557
|
-
let parentName = parts.join('.');
|
|
558
|
-
const parent = namespaceLookup.get(parentName.toLowerCase());
|
|
559
|
-
parent.namespaces.set(ns.lastPartName.toLowerCase(), ns);
|
|
574
|
+
else {
|
|
575
|
+
const existingContainer = namespaceLookup.get(lowerNamespaceName);
|
|
576
|
+
existingContainer.classStatements = new Map([...existingContainer.classStatements, ...nsContainer.classStatements]);
|
|
577
|
+
existingContainer.constStatements = new Map([...existingContainer.constStatements, ...nsContainer.constStatements]);
|
|
578
|
+
existingContainer.enumStatements = new Map([...existingContainer.enumStatements, ...nsContainer.enumStatements]);
|
|
579
|
+
existingContainer.functionStatements = new Map([...existingContainer.functionStatements, ...nsContainer.functionStatements]);
|
|
580
|
+
existingContainer.namespaces = new Map([...existingContainer.namespaces, ...nsContainer.namespaces]);
|
|
581
|
+
existingContainer.namespaceStatements.push(...nsContainer.namespaceStatements);
|
|
582
|
+
existingContainer.symbolTable.mergeSymbolTable(nsContainer.symbolTable);
|
|
560
583
|
}
|
|
561
584
|
}
|
|
562
585
|
});
|
|
@@ -572,9 +595,9 @@ class Scope {
|
|
|
572
595
|
logDebug(...args) {
|
|
573
596
|
this.program.logger.debug(this._debugLogComponentName, ...args);
|
|
574
597
|
}
|
|
575
|
-
validate(
|
|
598
|
+
validate(validationOptions = { force: false }) {
|
|
576
599
|
//if this scope is already validated, no need to revalidate
|
|
577
|
-
if (this.isValidated === true && !force) {
|
|
600
|
+
if (this.isValidated === true && !validationOptions.force) {
|
|
578
601
|
this.logDebug('validate(): already validated');
|
|
579
602
|
return;
|
|
580
603
|
}
|
|
@@ -583,10 +606,10 @@ class Scope {
|
|
|
583
606
|
//validate our parent before we validate ourself
|
|
584
607
|
if (parentScope && parentScope.isValidated === false) {
|
|
585
608
|
this.logDebug('validate(): validating parent first');
|
|
586
|
-
parentScope.validate(
|
|
609
|
+
parentScope.validate(validationOptions);
|
|
587
610
|
}
|
|
588
611
|
//clear the scope's errors list (we will populate them from this method)
|
|
589
|
-
this.
|
|
612
|
+
this.clearScopeLevelDiagnostics();
|
|
590
613
|
let callables = this.getAllCallables();
|
|
591
614
|
//sort the callables by filepath and then method name, so the errors will be consistent
|
|
592
615
|
// eslint-disable-next-line prefer-arrow-callback
|
|
@@ -617,7 +640,9 @@ class Scope {
|
|
|
617
640
|
this.linkSymbolTable();
|
|
618
641
|
const scopeValidateEvent = {
|
|
619
642
|
program: this.program,
|
|
620
|
-
scope: this
|
|
643
|
+
scope: this,
|
|
644
|
+
changedFiles: validationOptions === null || validationOptions === void 0 ? void 0 : validationOptions.changedFiles,
|
|
645
|
+
changedSymbols: validationOptions === null || validationOptions === void 0 ? void 0 : validationOptions.changedSymbols
|
|
621
646
|
};
|
|
622
647
|
this.program.plugins.emit('beforeScopeValidate', scopeValidateEvent);
|
|
623
648
|
this.program.plugins.emit('onScopeValidate', scopeValidateEvent);
|
|
@@ -637,12 +662,22 @@ class Scope {
|
|
|
637
662
|
this.validateClasses();
|
|
638
663
|
//do many per-file checks
|
|
639
664
|
this.enumerateBrsFiles((file) => {
|
|
640
|
-
this.diagnosticDetectFunctionCallsWithWrongParamCount(file, callableContainerMap);
|
|
641
665
|
this.diagnosticDetectShadowedLocalVars(file, callableContainerMap);
|
|
642
666
|
this.diagnosticDetectFunctionCollisions(file);
|
|
643
667
|
this.detectVariableNamespaceCollisions(file);
|
|
668
|
+
this.detectNameCollisions(file);
|
|
644
669
|
});
|
|
645
670
|
}
|
|
671
|
+
clearAstSegmentDiagnostics(astSegment) {
|
|
672
|
+
this.diagnostics = this.diagnostics.filter(diag => !(diag.origin === interfaces_1.DiagnosticOrigin.ASTSegment && diag.astSegment === astSegment));
|
|
673
|
+
}
|
|
674
|
+
clearAstSegmentDiagnosticsByFile(file) {
|
|
675
|
+
const lowerSrcPath = file.srcPath.toLowerCase();
|
|
676
|
+
this.diagnostics = this.diagnostics.filter(diag => !(diag.origin === interfaces_1.DiagnosticOrigin.ASTSegment && diag.file.srcPath.toLowerCase() === lowerSrcPath));
|
|
677
|
+
}
|
|
678
|
+
clearScopeLevelDiagnostics() {
|
|
679
|
+
this.diagnostics = this.diagnostics.filter(diag => diag.origin !== interfaces_1.DiagnosticOrigin.Scope);
|
|
680
|
+
}
|
|
646
681
|
/**
|
|
647
682
|
* Mark this scope as invalid, which means its `validate()` function needs to be called again before use.
|
|
648
683
|
*/
|
|
@@ -655,6 +690,7 @@ class Scope {
|
|
|
655
690
|
return this.cache.getOrAdd('symbolTable', () => {
|
|
656
691
|
var _a;
|
|
657
692
|
const result = new SymbolTable_1.SymbolTable(`Scope: '${this.name}'`, () => { var _a; return (_a = this.getParentScope()) === null || _a === void 0 ? void 0 : _a.symbolTable; });
|
|
693
|
+
result.addSymbol('m', undefined, new AssociativeArrayType_1.AssociativeArrayType(), SymbolTable_1.SymbolTypeFlag.runtime);
|
|
658
694
|
for (let file of this.getOwnFiles()) {
|
|
659
695
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
660
696
|
result.mergeSymbolTable((_a = file.parser) === null || _a === void 0 ? void 0 : _a.symbolTable);
|
|
@@ -667,71 +703,88 @@ class Scope {
|
|
|
667
703
|
* Builds the current symbol table for the scope, by merging the tables for all the files in this scope.
|
|
668
704
|
* Also links all file symbols tables to this new table
|
|
669
705
|
* This will only rebuilt if the symbol table has not been built before
|
|
706
|
+
*
|
|
707
|
+
* Tree of symbol tables:
|
|
708
|
+
* ```
|
|
709
|
+
* Global Scope Symbol Table
|
|
710
|
+
* - Source Scope Symbol Table :: Aggregate Namespaces Symbol Table (Siblings)
|
|
711
|
+
* - File 1 Symbol Table
|
|
712
|
+
* - File 2 Symbol Table
|
|
713
|
+
* - Component A Scope Symbol Table :: Aggregate Namespaces Symbol Table (Siblings)
|
|
714
|
+
* - File 1 Symbol Table
|
|
715
|
+
* - File 2 Symbol Table
|
|
716
|
+
* - Component B Scope Symbol Table :: Aggregate Namespaces Symbol Table (Siblings)
|
|
717
|
+
* - File 1 Symbol Table
|
|
718
|
+
* - File 2 Symbol Table
|
|
719
|
+
* ```
|
|
670
720
|
*/
|
|
671
721
|
linkSymbolTable() {
|
|
672
|
-
|
|
722
|
+
var _a;
|
|
723
|
+
SymbolTable_1.SymbolTable.cacheVerifier.generateToken();
|
|
673
724
|
for (const file of this.getAllFiles()) {
|
|
674
725
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
675
|
-
file.parser.symbolTable.pushParentProvider(() => this.symbolTable);
|
|
676
|
-
allNameSpaces.push(...file.parser.references.namespaceStatements);
|
|
726
|
+
this.linkSymbolTableDisposables.push(file.parser.symbolTable.pushParentProvider(() => this.symbolTable));
|
|
677
727
|
}
|
|
678
728
|
}
|
|
679
729
|
//Add namespace aggregates to namespace member tables
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
// eslint-disable-next-line no-bitwise
|
|
685
|
-
let getSymbolFlags = { flags: SymbolTable_1.SymbolTypeFlag.runtime | SymbolTable_1.SymbolTypeFlag.typetime };
|
|
730
|
+
const namespaceTypesKnown = new Map();
|
|
731
|
+
// eslint-disable-next-line no-bitwise
|
|
732
|
+
let getTypeOptions = { flags: SymbolTable_1.SymbolTypeFlag.runtime | SymbolTable_1.SymbolTypeFlag.typetime };
|
|
733
|
+
for (const [nsName, nsContainer] of this.namespaceLookup) {
|
|
686
734
|
let currentNSType = null;
|
|
687
|
-
let
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
}
|
|
735
|
+
let parentNSType = null;
|
|
736
|
+
const existingNsStmt = (_a = nsContainer.namespaceStatements) === null || _a === void 0 ? void 0 : _a[0];
|
|
737
|
+
if (!nsContainer.isTopLevel) {
|
|
738
|
+
parentNSType = namespaceTypesKnown.get(nsContainer.parentNameLower);
|
|
739
|
+
if (!parentNSType) {
|
|
740
|
+
// we don't know about the parent namespace... uh, oh!
|
|
741
|
+
break;
|
|
742
|
+
}
|
|
743
|
+
currentNSType = parentNSType.getMemberType(nsContainer.fullNameLower, getTypeOptions);
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
currentNSType = this.symbolTable.getSymbolType(nsContainer.fullNameLower, getTypeOptions);
|
|
747
|
+
}
|
|
748
|
+
if (!(0, reflection_1.isNamespaceType)(currentNSType)) {
|
|
749
|
+
if (!currentNSType || (0, reflection_1.isReferenceType)(currentNSType)) {
|
|
750
|
+
currentNSType = existingNsStmt
|
|
751
|
+
? existingNsStmt.getType(getTypeOptions)
|
|
752
|
+
: new NamespaceType_1.NamespaceType(nsName);
|
|
753
|
+
if (parentNSType) {
|
|
754
|
+
// adding as a member of existing NS
|
|
755
|
+
parentNSType.addMember(nsContainer.lastPartName, { definingNode: existingNsStmt }, currentNSType, getTypeOptions.flags);
|
|
756
|
+
this.symbolsAddedDuringLinking.push({ symbolTable: parentNSType.getMemberTable(), name: nsContainer.lastPartName, flags: getTypeOptions.flags });
|
|
709
757
|
}
|
|
710
758
|
else {
|
|
711
|
-
|
|
759
|
+
this.symbolTable.addSymbol(nsContainer.lastPartName, { definingNode: existingNsStmt }, currentNSType, getTypeOptions.flags);
|
|
760
|
+
this.symbolsAddedDuringLinking.push({ symbolTable: this.symbolTable, name: nsContainer.lastPartName, flags: getTypeOptions.flags });
|
|
712
761
|
}
|
|
713
762
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
currentNSType.memberTable.addSibling(aggregateNSSymbolTable);
|
|
717
|
-
if (isFinalNamespace) {
|
|
718
|
-
namespace.body.getSymbolTable().addSibling(aggregateNSSymbolTable);
|
|
763
|
+
else {
|
|
764
|
+
break;
|
|
719
765
|
}
|
|
720
766
|
}
|
|
767
|
+
else {
|
|
768
|
+
// Existing known namespace
|
|
769
|
+
}
|
|
770
|
+
if (!namespaceTypesKnown.has(nsName)) {
|
|
771
|
+
namespaceTypesKnown.set(nsName, currentNSType);
|
|
772
|
+
}
|
|
773
|
+
for (let nsStmt of nsContainer.namespaceStatements) {
|
|
774
|
+
this.linkSymbolTableDisposables.push(nsStmt === null || nsStmt === void 0 ? void 0 : nsStmt.getSymbolTable().addSibling(nsContainer.symbolTable));
|
|
775
|
+
}
|
|
776
|
+
this.linkSymbolTableDisposables.push(currentNSType.memberTable.addSibling(nsContainer.symbolTable));
|
|
721
777
|
}
|
|
722
|
-
this.program.typeCacheVerifier.generateToken();
|
|
723
778
|
}
|
|
724
779
|
unlinkSymbolTable() {
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
namespace.getSymbolTable().removeSibling(this.namespaceLookup.get(namespaceNameLower).symbolTable);
|
|
732
|
-
}
|
|
733
|
-
}
|
|
780
|
+
for (const symbolToRemove of this.symbolsAddedDuringLinking) {
|
|
781
|
+
this.symbolTable.removeSymbol(symbolToRemove.name);
|
|
782
|
+
}
|
|
783
|
+
this.symbolsAddedDuringLinking = [];
|
|
784
|
+
for (const dispose of this.linkSymbolTableDisposables) {
|
|
785
|
+
dispose();
|
|
734
786
|
}
|
|
787
|
+
this.linkSymbolTableDisposables = [];
|
|
735
788
|
}
|
|
736
789
|
detectVariableNamespaceCollisions(file) {
|
|
737
790
|
var _a, _b;
|
|
@@ -742,7 +795,7 @@ class Scope {
|
|
|
742
795
|
let namespace = this.getNamespace(lowerParamName, (_a = param.findAncestor(reflection_1.isNamespaceStatement)) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript).toLowerCase());
|
|
743
796
|
//see if the param matches any starting namespace part
|
|
744
797
|
if (namespace) {
|
|
745
|
-
this.diagnostics.push(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.parameterMayNotHaveSameNameAsNamespace(param.name.text)), { range: param.name.range, relatedInformation: [{
|
|
798
|
+
this.diagnostics.push(Object.assign(Object.assign({ origin: interfaces_1.DiagnosticOrigin.Scope, file: file }, DiagnosticMessages_1.DiagnosticMessages.parameterMayNotHaveSameNameAsNamespace(param.name.text)), { range: param.name.range, relatedInformation: [{
|
|
746
799
|
message: 'Namespace declared here',
|
|
747
800
|
location: util_1.util.createLocation(vscode_uri_1.URI.file(namespace.file.srcPath).toString(), namespace.nameRange)
|
|
748
801
|
}] }));
|
|
@@ -754,7 +807,7 @@ class Scope {
|
|
|
754
807
|
let namespace = this.getNamespace(lowerAssignmentName, (_b = assignment.findAncestor(reflection_1.isNamespaceStatement)) === null || _b === void 0 ? void 0 : _b.getName(Parser_1.ParseMode.BrighterScript).toLowerCase());
|
|
755
808
|
//see if the param matches any starting namespace part
|
|
756
809
|
if (namespace) {
|
|
757
|
-
this.diagnostics.push(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.variableMayNotHaveSameNameAsNamespace(assignment.name.text)), { range: assignment.name.range, relatedInformation: [{
|
|
810
|
+
this.diagnostics.push(Object.assign(Object.assign({ origin: interfaces_1.DiagnosticOrigin.Scope, file: file }, DiagnosticMessages_1.DiagnosticMessages.variableMayNotHaveSameNameAsNamespace(assignment.name.text)), { range: assignment.name.range, relatedInformation: [{
|
|
758
811
|
message: 'Namespace declared here',
|
|
759
812
|
location: util_1.util.createLocation(vscode_uri_1.URI.file(namespace.file.srcPath).toString(), namespace.nameRange)
|
|
760
813
|
}] }));
|
|
@@ -771,15 +824,80 @@ class Scope {
|
|
|
771
824
|
if (lowerFuncName) {
|
|
772
825
|
//find function declarations with the same name as a stdlib function
|
|
773
826
|
if (globalCallables_1.globalCallableMap.has(lowerFuncName)) {
|
|
774
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.scopeFunctionShadowedByBuiltInFunction()), { range: func.nameRange, file: file }));
|
|
827
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.scopeFunctionShadowedByBuiltInFunction()), { range: func.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
775
828
|
}
|
|
776
829
|
//find any functions that have the same name as a class
|
|
777
|
-
|
|
778
|
-
|
|
830
|
+
const klassLink = this.getClassFileLink(lowerFuncName);
|
|
831
|
+
if (klassLink) {
|
|
832
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass(funcName)), { range: func.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope, relatedInformation: [{
|
|
833
|
+
location: util_1.util.createLocation(vscode_uri_1.URI.file(klassLink.file.srcPath).toString(), klassLink.item.name.range),
|
|
834
|
+
message: 'Original class declared here'
|
|
835
|
+
}] }));
|
|
779
836
|
}
|
|
780
837
|
}
|
|
781
838
|
}
|
|
782
839
|
}
|
|
840
|
+
detectNameCollisions(file) {
|
|
841
|
+
file.ast.walk((0, visitors_1.createVisitor)({
|
|
842
|
+
NamespaceStatement: (nsStmt) => {
|
|
843
|
+
var _a;
|
|
844
|
+
this.validateNameCollision(file, nsStmt, (_a = nsStmt.getNameParts()) === null || _a === void 0 ? void 0 : _a[0]);
|
|
845
|
+
},
|
|
846
|
+
ClassStatement: (classStmt) => {
|
|
847
|
+
this.validateNameCollision(file, classStmt, classStmt.name);
|
|
848
|
+
},
|
|
849
|
+
InterfaceStatement: (ifaceStmt) => {
|
|
850
|
+
this.validateNameCollision(file, ifaceStmt, ifaceStmt.tokens.name);
|
|
851
|
+
},
|
|
852
|
+
ConstStatement: (constStmt) => {
|
|
853
|
+
this.validateNameCollision(file, constStmt, constStmt.tokens.name);
|
|
854
|
+
},
|
|
855
|
+
EnumStatement: (enumStmt) => {
|
|
856
|
+
this.validateNameCollision(file, enumStmt, enumStmt.tokens.name);
|
|
857
|
+
}
|
|
858
|
+
}), {
|
|
859
|
+
walkMode: visitors_1.WalkMode.visitStatements
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
validateNameCollision(file, node, nameIdentifier) {
|
|
863
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
864
|
+
const name = nameIdentifier === null || nameIdentifier === void 0 ? void 0 : nameIdentifier.text;
|
|
865
|
+
if (!name || !node) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
const nameRange = nameIdentifier.range;
|
|
869
|
+
const containingNamespace = (_a = node.findAncestor(reflection_1.isNamespaceStatement)) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript);
|
|
870
|
+
const links = this.getAllFileLinks(name, containingNamespace);
|
|
871
|
+
for (let link of links) {
|
|
872
|
+
if (!link || link.item === node) {
|
|
873
|
+
// refers to same node
|
|
874
|
+
continue;
|
|
875
|
+
}
|
|
876
|
+
if ((0, reflection_1.isNamespaceStatement)(link.item) && (0, reflection_1.isNamespaceStatement)(node)) {
|
|
877
|
+
// namespace can be declared multiple times
|
|
878
|
+
continue;
|
|
879
|
+
}
|
|
880
|
+
const thisNodeKindName = util_1.util.getAstNodeFriendlyName(node);
|
|
881
|
+
const thatNodeKindName = link.file.srcPath === 'global' ? 'Global Function' : (_b = util_1.util.getAstNodeFriendlyName(link.item)) !== null && _b !== void 0 ? _b : '';
|
|
882
|
+
let thatNameRange = (_f = (_e = (_d = (_c = link.item) === null || _c === void 0 ? void 0 : _c.tokens) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.range) !== null && _f !== void 0 ? _f : (_g = link.item) === null || _g === void 0 ? void 0 : _g.range;
|
|
883
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
884
|
+
switch ((_h = link.item) === null || _h === void 0 ? void 0 : _h.kind) {
|
|
885
|
+
case AstNode_1.AstNodeKind.ClassStatement: {
|
|
886
|
+
thatNameRange = (_j = link.item.name) === null || _j === void 0 ? void 0 : _j.range;
|
|
887
|
+
break;
|
|
888
|
+
}
|
|
889
|
+
case AstNode_1.AstNodeKind.NamespaceStatement: {
|
|
890
|
+
thatNameRange = (_l = (_k = link.item.getNameParts()) === null || _k === void 0 ? void 0 : _k[0]) === null || _l === void 0 ? void 0 : _l.range;
|
|
891
|
+
break;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
const relatedInformation = thatNameRange ? [{
|
|
895
|
+
message: `${thatNodeKindName} declared here`,
|
|
896
|
+
location: util_1.util.createLocation(vscode_uri_1.URI.file((_m = link.file) === null || _m === void 0 ? void 0 : _m.srcPath).toString(), thatNameRange)
|
|
897
|
+
}] : undefined;
|
|
898
|
+
this.diagnostics.push(Object.assign(Object.assign({ file: file }, DiagnosticMessages_1.DiagnosticMessages.nameCollision(thisNodeKindName, thatNodeKindName, name)), { origin: interfaces_1.DiagnosticOrigin.Scope, range: nameRange, relatedInformation: relatedInformation }));
|
|
899
|
+
}
|
|
900
|
+
}
|
|
783
901
|
getNewExpressions() {
|
|
784
902
|
let result = [];
|
|
785
903
|
this.enumerateBrsFiles((file) => {
|
|
@@ -794,38 +912,9 @@ class Scope {
|
|
|
794
912
|
validateClasses() {
|
|
795
913
|
let validator = new ClassValidator_1.BsClassValidator();
|
|
796
914
|
validator.validate(this);
|
|
797
|
-
this.diagnostics.push(...validator.diagnostics
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
* Detect calls to functions with the incorrect number of parameters
|
|
801
|
-
*/
|
|
802
|
-
diagnosticDetectFunctionCallsWithWrongParamCount(file, callableContainersByLowerName) {
|
|
803
|
-
//validate all function calls
|
|
804
|
-
for (let expCall of file.functionCalls) {
|
|
805
|
-
let callableContainersWithThisName = callableContainersByLowerName.get(expCall.name.toLowerCase());
|
|
806
|
-
//use the first item from callablesByLowerName, because if there are more, that's a separate error
|
|
807
|
-
let knownCallableContainer = callableContainersWithThisName ? callableContainersWithThisName[0] : undefined;
|
|
808
|
-
if (knownCallableContainer) {
|
|
809
|
-
//get min/max parameter count for callable
|
|
810
|
-
let minParams = 0;
|
|
811
|
-
let maxParams = 0;
|
|
812
|
-
for (let param of knownCallableContainer.callable.params) {
|
|
813
|
-
maxParams++;
|
|
814
|
-
//optional parameters must come last, so we can assume that minParams won't increase once we hit
|
|
815
|
-
//the first isOptional
|
|
816
|
-
if (param.isOptional !== true) {
|
|
817
|
-
minParams++;
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
let expCallArgCount = expCall.args.length;
|
|
821
|
-
if (expCall.args.length > maxParams || expCall.args.length < minParams) {
|
|
822
|
-
let minMaxParamsText = minParams === maxParams ? maxParams : `${minParams}-${maxParams}`;
|
|
823
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(minMaxParamsText, expCallArgCount)), { range: expCall.nameRange,
|
|
824
|
-
//TODO detect end of expression call
|
|
825
|
-
file: file }));
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
}
|
|
915
|
+
this.diagnostics.push(...validator.diagnostics.map(diag => {
|
|
916
|
+
return Object.assign(Object.assign({}, diag), { origin: interfaces_1.DiagnosticOrigin.Scope });
|
|
917
|
+
}));
|
|
829
918
|
}
|
|
830
919
|
/**
|
|
831
920
|
* Detect local variables (function scope) that have the same name as scope calls
|
|
@@ -834,39 +923,34 @@ class Scope {
|
|
|
834
923
|
var _a;
|
|
835
924
|
const classMap = this.getClassMap();
|
|
836
925
|
//loop through every function scope
|
|
837
|
-
for (let
|
|
926
|
+
for (let funcScope of file.functionScopes) {
|
|
838
927
|
//every var declaration in this function scope
|
|
839
|
-
for (let varDeclaration of
|
|
928
|
+
for (let varDeclaration of funcScope.variableDeclarations) {
|
|
840
929
|
const varName = varDeclaration.name;
|
|
841
930
|
const lowerVarName = varName.toLowerCase();
|
|
842
|
-
|
|
843
|
-
|
|
931
|
+
const varIsFunction = () => {
|
|
932
|
+
return (0, reflection_1.isCallableType)(varDeclaration.getType());
|
|
933
|
+
};
|
|
934
|
+
if (
|
|
935
|
+
//has same name as stdlib
|
|
936
|
+
globalCallables_1.globalCallableMap.has(lowerVarName)) {
|
|
844
937
|
//local var function with same name as stdlib function
|
|
845
|
-
if (
|
|
846
|
-
|
|
847
|
-
globalCallables_1.globalCallableMap.has(lowerVarName)) {
|
|
848
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('stdlib')), { range: varDeclaration.nameRange, file: file }));
|
|
849
|
-
//this check needs to come after the stdlib one, because the stdlib functions are included
|
|
850
|
-
//in the scope function list
|
|
938
|
+
if (varIsFunction()) {
|
|
939
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('stdlib')), { range: varDeclaration.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
851
940
|
}
|
|
852
|
-
else if (
|
|
853
|
-
//has same name as scope function
|
|
854
|
-
callableContainerMap.has(lowerVarName)) {
|
|
855
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('scope')), { range: varDeclaration.nameRange, file: file }));
|
|
856
|
-
}
|
|
857
|
-
//var is not a function
|
|
858
941
|
}
|
|
859
|
-
else if (
|
|
860
|
-
//is NOT a callable from stdlib (because non-function local vars can have same name as stdlib names)
|
|
861
|
-
!globalCallables_1.globalCallableMap.has(lowerVarName)) {
|
|
942
|
+
else if (callableContainerMap.has(lowerVarName)) {
|
|
862
943
|
//is same name as a callable
|
|
863
|
-
if (
|
|
864
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
865
|
-
//has the same name as an in-scope class
|
|
944
|
+
if (varIsFunction()) {
|
|
945
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('scope')), { range: varDeclaration.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
866
946
|
}
|
|
867
|
-
else
|
|
868
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
947
|
+
else {
|
|
948
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarShadowedByScopedFunction()), { range: varDeclaration.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
869
949
|
}
|
|
950
|
+
//has the same name as an in-scope class
|
|
951
|
+
}
|
|
952
|
+
else if (classMap.has(lowerVarName)) {
|
|
953
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarSameNameAsClass((_a = classMap.get(lowerVarName)) === null || _a === void 0 ? void 0 : _a.item.getName(Parser_1.ParseMode.BrighterScript))), { range: varDeclaration.nameRange, file: file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
870
954
|
}
|
|
871
955
|
}
|
|
872
956
|
}
|
|
@@ -905,9 +989,9 @@ class Scope {
|
|
|
905
989
|
//same file: skip redundant imports
|
|
906
990
|
continue;
|
|
907
991
|
}
|
|
908
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.overridesAncestorFunction(container.callable.name, container.scope.name, shadowedCallable.callable.file.
|
|
992
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.overridesAncestorFunction(container.callable.name, container.scope.name, shadowedCallable.callable.file.destPath,
|
|
909
993
|
//grab the last item in the list, which should be the closest ancestor's version
|
|
910
|
-
shadowedCallable.scope.name)), { range: container.callable.nameRange, file: container.callable.file }));
|
|
994
|
+
shadowedCallable.scope.name)), { range: container.callable.nameRange, file: container.callable.file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
911
995
|
}
|
|
912
996
|
}
|
|
913
997
|
}
|
|
@@ -915,7 +999,7 @@ class Scope {
|
|
|
915
999
|
if (ownCallables.length > 1) {
|
|
916
1000
|
for (let callableContainer of ownCallables) {
|
|
917
1001
|
let callable = callableContainer.callable;
|
|
918
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateFunctionImplementation(callable.name, callableContainer.scope.name)), { range: util_1.util.createRange(callable.nameRange.start.line, callable.nameRange.start.character, callable.nameRange.start.line, callable.nameRange.end.character), file: callable.file }));
|
|
1002
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateFunctionImplementation(callable.name, callableContainer.scope.name)), { range: util_1.util.createRange(callable.nameRange.start.line, callable.nameRange.start.character, callable.nameRange.start.line, callable.nameRange.end.character), file: callable.file, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
919
1003
|
}
|
|
920
1004
|
}
|
|
921
1005
|
}
|
|
@@ -942,11 +1026,11 @@ class Scope {
|
|
|
942
1026
|
let scriptImports = this.getOwnScriptImports();
|
|
943
1027
|
//verify every script import
|
|
944
1028
|
for (let scriptImport of scriptImports) {
|
|
945
|
-
let referencedFile = this.getFileByRelativePath(scriptImport.
|
|
1029
|
+
let referencedFile = this.getFileByRelativePath(scriptImport.destPath);
|
|
946
1030
|
//if we can't find the file
|
|
947
1031
|
if (!referencedFile) {
|
|
948
1032
|
//skip the default bslib file, it will exist at transpile time but should not show up in the program during validation cycle
|
|
949
|
-
if (scriptImport.
|
|
1033
|
+
if (scriptImport.destPath === this.program.bslibPkgPath) {
|
|
950
1034
|
continue;
|
|
951
1035
|
}
|
|
952
1036
|
let dInfo;
|
|
@@ -956,11 +1040,11 @@ class Scope {
|
|
|
956
1040
|
else {
|
|
957
1041
|
dInfo = DiagnosticMessages_1.DiagnosticMessages.referencedFileDoesNotExist();
|
|
958
1042
|
}
|
|
959
|
-
this.diagnostics.push(Object.assign(Object.assign({}, dInfo), { range: scriptImport.filePathRange, file: scriptImport.sourceFile }));
|
|
1043
|
+
this.diagnostics.push(Object.assign(Object.assign({}, dInfo), { range: scriptImport.filePathRange, file: scriptImport.sourceFile, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
960
1044
|
//if the character casing of the script import path does not match that of the actual path
|
|
961
1045
|
}
|
|
962
|
-
else if (scriptImport.
|
|
963
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.scriptImportCaseMismatch(referencedFile.
|
|
1046
|
+
else if (scriptImport.destPath !== referencedFile.destPath) {
|
|
1047
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.scriptImportCaseMismatch(referencedFile.destPath)), { range: scriptImport.filePathRange, file: scriptImport.sourceFile, origin: interfaces_1.DiagnosticOrigin.Scope }));
|
|
964
1048
|
}
|
|
965
1049
|
}
|
|
966
1050
|
}
|
|
@@ -973,7 +1057,7 @@ class Scope {
|
|
|
973
1057
|
}
|
|
974
1058
|
let files = this.getAllFiles();
|
|
975
1059
|
for (let file of files) {
|
|
976
|
-
if (file.
|
|
1060
|
+
if (file.destPath.toLowerCase() === relativePath.toLowerCase()) {
|
|
977
1061
|
return file;
|
|
978
1062
|
}
|
|
979
1063
|
}
|
|
@@ -986,35 +1070,6 @@ class Scope {
|
|
|
986
1070
|
let hasFile = files.includes(file);
|
|
987
1071
|
return hasFile;
|
|
988
1072
|
}
|
|
989
|
-
/**
|
|
990
|
-
* Get all callables as completionItems
|
|
991
|
-
*/
|
|
992
|
-
getCallablesAsCompletions(parseMode) {
|
|
993
|
-
let completions = [];
|
|
994
|
-
let callables = this.getAllCallables();
|
|
995
|
-
if (parseMode === Parser_1.ParseMode.BrighterScript) {
|
|
996
|
-
//throw out the namespaced callables (they will be handled by another method)
|
|
997
|
-
callables = callables.filter(x => x.callable.hasNamespace === false);
|
|
998
|
-
}
|
|
999
|
-
for (let callableContainer of callables) {
|
|
1000
|
-
completions.push(this.createCompletionFromCallable(callableContainer));
|
|
1001
|
-
}
|
|
1002
|
-
return completions;
|
|
1003
|
-
}
|
|
1004
|
-
createCompletionFromCallable(callableContainer) {
|
|
1005
|
-
return {
|
|
1006
|
-
label: callableContainer.callable.getName(Parser_1.ParseMode.BrighterScript),
|
|
1007
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function,
|
|
1008
|
-
detail: callableContainer.callable.shortDescription,
|
|
1009
|
-
documentation: callableContainer.callable.documentation ? { kind: 'markdown', value: callableContainer.callable.documentation } : undefined
|
|
1010
|
-
};
|
|
1011
|
-
}
|
|
1012
|
-
createCompletionFromFunctionStatement(statement) {
|
|
1013
|
-
return {
|
|
1014
|
-
label: statement.getName(Parser_1.ParseMode.BrighterScript),
|
|
1015
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
1016
|
-
};
|
|
1017
|
-
}
|
|
1018
1073
|
/**
|
|
1019
1074
|
* Get the definition (where was this thing first defined) of the symbol under the position
|
|
1020
1075
|
*/
|
|
@@ -1022,37 +1077,6 @@ class Scope {
|
|
|
1022
1077
|
// Overridden in XMLScope. Brs files use implementation in BrsFile
|
|
1023
1078
|
return [];
|
|
1024
1079
|
}
|
|
1025
|
-
/**
|
|
1026
|
-
* Scan all files for property names, and return them as completions
|
|
1027
|
-
*/
|
|
1028
|
-
getPropertyNameCompletions() {
|
|
1029
|
-
let results = [];
|
|
1030
|
-
this.enumerateBrsFiles((file) => {
|
|
1031
|
-
results.push(...file.propertyNameCompletions);
|
|
1032
|
-
});
|
|
1033
|
-
return results;
|
|
1034
|
-
}
|
|
1035
|
-
getAllClassMemberCompletions() {
|
|
1036
|
-
let results = new Map();
|
|
1037
|
-
let filesSearched = new Set();
|
|
1038
|
-
for (const file of this.getAllFiles()) {
|
|
1039
|
-
if ((0, reflection_1.isXmlFile)(file) || filesSearched.has(file)) {
|
|
1040
|
-
continue;
|
|
1041
|
-
}
|
|
1042
|
-
filesSearched.add(file);
|
|
1043
|
-
for (let cs of file.parser.references.classStatements) {
|
|
1044
|
-
for (let s of [...cs.methods, ...cs.fields]) {
|
|
1045
|
-
if (!results.has(s.name.text) && s.name.text.toLowerCase() !== 'new') {
|
|
1046
|
-
results.set(s.name.text, {
|
|
1047
|
-
label: s.name.text,
|
|
1048
|
-
kind: (0, reflection_1.isMethodStatement)(s) ? vscode_languageserver_1.CompletionItemKind.Method : vscode_languageserver_1.CompletionItemKind.Field
|
|
1049
|
-
});
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
return results;
|
|
1055
|
-
}
|
|
1056
1080
|
/**
|
|
1057
1081
|
* @param className - The name of the class (including namespace if possible)
|
|
1058
1082
|
* @param callsiteNamespace - the name of the namespace where the call site resides (this is NOT the known namespace of the class).
|