brighterscript 0.66.0-alpha.0 → 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 +223 -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 +656 -340
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +10 -4
- package/dist/ProgramBuilder.js +83 -66
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +52 -49
- package/dist/Scope.js +312 -247
- package/dist/Scope.js.map +1 -1
- package/dist/SymbolTable.d.ts +35 -14
- package/dist/SymbolTable.js +89 -26
- 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 +11 -4
- package/dist/bscPlugin/BscPlugin.js +26 -6
- 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 +35 -65
- 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/ProgramValidator.d.ts +3 -3
- package/dist/bscPlugin/validation/ProgramValidator.js +6 -6
- package/dist/bscPlugin/validation/ProgramValidator.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 +63 -91
- 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 +436 -81
- 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");
|
|
@@ -14,6 +14,18 @@ const vscode_uri_1 = require("vscode-uri");
|
|
|
14
14
|
const Logger_1 = require("./Logger");
|
|
15
15
|
const reflection_1 = require("./astUtils/reflection");
|
|
16
16
|
const SymbolTable_1 = require("./SymbolTable");
|
|
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;
|
|
17
29
|
/**
|
|
18
30
|
* A class to keep track of all declarations within a given scope (like source scope, component scope)
|
|
19
31
|
*/
|
|
@@ -27,6 +39,11 @@ class Scope {
|
|
|
27
39
|
* The list of diagnostics found specifically for this scope. Individual file diagnostics are stored on the files themselves.
|
|
28
40
|
*/
|
|
29
41
|
this.diagnostics = [];
|
|
42
|
+
/**
|
|
43
|
+
* A list of functions that will be called whenever `unlinkSymbolTable` is called
|
|
44
|
+
*/
|
|
45
|
+
this.linkSymbolTableDisposables = [];
|
|
46
|
+
this.symbolsAddedDuringLinking = [];
|
|
30
47
|
this.isValidated = false;
|
|
31
48
|
//used for improved logging performance
|
|
32
49
|
this._debugLogComponentName = `Scope '${chalk_1.default.redBright(this.name)}'`;
|
|
@@ -40,6 +57,20 @@ class Scope {
|
|
|
40
57
|
* "namea", "namea.nameb", "namea.nameb.namec"
|
|
41
58
|
*/
|
|
42
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
|
+
}
|
|
43
74
|
return this.cache.getOrAdd('namespaceLookup', () => this.buildNamespaceLookup());
|
|
44
75
|
}
|
|
45
76
|
/**
|
|
@@ -58,6 +89,20 @@ class Scope {
|
|
|
58
89
|
}
|
|
59
90
|
return ns;
|
|
60
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
|
+
}
|
|
61
106
|
/**
|
|
62
107
|
* Get the class with the specified name.
|
|
63
108
|
* @param className - The class name, including the namespace of the class if possible
|
|
@@ -139,7 +184,7 @@ class Scope {
|
|
|
139
184
|
var _a, _b;
|
|
140
185
|
let lowerNameParts = (_a = enumMemberName === null || enumMemberName === void 0 ? void 0 : enumMemberName.toLowerCase()) === null || _a === void 0 ? void 0 : _a.split('.');
|
|
141
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];
|
|
142
|
-
let lowerName = lowerNameParts === null || lowerNameParts === void 0 ? void 0 : lowerNameParts.join('.')
|
|
187
|
+
let lowerName = lowerNameParts === null || lowerNameParts === void 0 ? void 0 : lowerNameParts.join('.');
|
|
143
188
|
const enumMap = this.getEnumMap();
|
|
144
189
|
let enumeration = enumMap.get(util_1.util.getFullyQualifiedClassName(lowerName, containingNamespace === null || containingNamespace === void 0 ? void 0 : containingNamespace.toLowerCase()));
|
|
145
190
|
//if we couldn't find the enum by its full namespaced name, look for a global enum with that name
|
|
@@ -167,6 +212,24 @@ class Scope {
|
|
|
167
212
|
}
|
|
168
213
|
return result;
|
|
169
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
|
+
}
|
|
170
233
|
/**
|
|
171
234
|
* Get a map of all enums by their member name.
|
|
172
235
|
* The keys are lower-case fully-qualified paths to the enum and its member. For example:
|
|
@@ -215,13 +278,12 @@ class Scope {
|
|
|
215
278
|
return this.cache.getOrAdd('classMap', () => {
|
|
216
279
|
const map = new Map();
|
|
217
280
|
this.enumerateBrsFiles((file) => {
|
|
218
|
-
var _a;
|
|
219
281
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
220
282
|
for (let cls of file.parser.references.classStatements) {
|
|
221
|
-
const
|
|
283
|
+
const className = cls.getName(Parser_1.ParseMode.BrighterScript);
|
|
222
284
|
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
223
|
-
if (
|
|
224
|
-
map.set(
|
|
285
|
+
if (className) {
|
|
286
|
+
map.set(className.toLowerCase(), { item: cls, file: file });
|
|
225
287
|
}
|
|
226
288
|
}
|
|
227
289
|
}
|
|
@@ -237,13 +299,12 @@ class Scope {
|
|
|
237
299
|
return this.cache.getOrAdd('interfaceMap', () => {
|
|
238
300
|
const map = new Map();
|
|
239
301
|
this.enumerateBrsFiles((file) => {
|
|
240
|
-
var _a;
|
|
241
302
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
242
303
|
for (let iface of file.parser.references.interfaceStatements) {
|
|
243
|
-
const
|
|
304
|
+
const ifaceName = iface.getName(Parser_1.ParseMode.BrighterScript);
|
|
244
305
|
//only track classes with a defined name (i.e. exclude nameless malformed classes)
|
|
245
|
-
if (
|
|
246
|
-
map.set(
|
|
306
|
+
if (ifaceName) {
|
|
307
|
+
map.set(ifaceName.toLowerCase(), { item: iface, file: file });
|
|
247
308
|
}
|
|
248
309
|
}
|
|
249
310
|
}
|
|
@@ -260,10 +321,9 @@ class Scope {
|
|
|
260
321
|
const map = new Map();
|
|
261
322
|
this.enumerateBrsFiles((file) => {
|
|
262
323
|
for (let enumStmt of file.parser.references.enumStatements) {
|
|
263
|
-
const lowerEnumName = enumStmt.fullName.toLowerCase();
|
|
264
324
|
//only track enums with a defined name (i.e. exclude nameless malformed enums)
|
|
265
|
-
if (
|
|
266
|
-
map.set(
|
|
325
|
+
if (enumStmt.fullName) {
|
|
326
|
+
map.set(enumStmt.fullName.toLowerCase(), { item: enumStmt, file: file });
|
|
267
327
|
}
|
|
268
328
|
}
|
|
269
329
|
});
|
|
@@ -279,10 +339,9 @@ class Scope {
|
|
|
279
339
|
const map = new Map();
|
|
280
340
|
this.enumerateBrsFiles((file) => {
|
|
281
341
|
for (let stmt of file.parser.references.constStatements) {
|
|
282
|
-
const lowerEnumName = stmt.fullName.toLowerCase();
|
|
283
342
|
//only track enums with a defined name (i.e. exclude nameless malformed enums)
|
|
284
|
-
if (
|
|
285
|
-
map.set(
|
|
343
|
+
if (stmt.fullName) {
|
|
344
|
+
map.set(stmt.fullName.toLowerCase(), { item: stmt, file: file });
|
|
286
345
|
}
|
|
287
346
|
}
|
|
288
347
|
});
|
|
@@ -347,14 +406,14 @@ class Scope {
|
|
|
347
406
|
}
|
|
348
407
|
/**
|
|
349
408
|
* Get the file from this scope with the given path.
|
|
350
|
-
* @param filePath can be a srcPath or
|
|
409
|
+
* @param filePath can be a srcPath or destPath
|
|
351
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
|
|
352
411
|
*/
|
|
353
412
|
getFile(filePath, normalizePath = true) {
|
|
354
413
|
if (typeof filePath !== 'string') {
|
|
355
414
|
return undefined;
|
|
356
415
|
}
|
|
357
|
-
const key = path.isAbsolute(filePath) ? 'srcPath' : '
|
|
416
|
+
const key = path.isAbsolute(filePath) ? 'srcPath' : 'destPath';
|
|
358
417
|
let map = this.cache.getOrAdd('fileMaps-srcPath', () => {
|
|
359
418
|
const result = new Map();
|
|
360
419
|
for (const file of this.getAllFiles()) {
|
|
@@ -395,26 +454,26 @@ class Scope {
|
|
|
395
454
|
}
|
|
396
455
|
}
|
|
397
456
|
}
|
|
398
|
-
this.logDebug('getAllFiles', () => result.map(x => x.
|
|
457
|
+
this.logDebug('getAllFiles', () => result.map(x => x.destPath));
|
|
399
458
|
return result;
|
|
400
459
|
});
|
|
401
460
|
}
|
|
402
461
|
/**
|
|
403
|
-
* Get the list of errors for this scope. It's calculated on the fly, so
|
|
404
|
-
* call this sparingly.
|
|
462
|
+
* Get the list of errors for this scope. It's calculated on the fly, so call this sparingly.
|
|
405
463
|
*/
|
|
406
464
|
getDiagnostics() {
|
|
407
|
-
let diagnosticLists = [this.diagnostics];
|
|
408
465
|
//add diagnostics from every referenced file
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
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) => {
|
|
414
474
|
return !util_1.util.diagnosticIsSuppressed(x);
|
|
415
475
|
});
|
|
416
|
-
|
|
417
|
-
return filteredDiagnostics;
|
|
476
|
+
return diagnostics;
|
|
418
477
|
}
|
|
419
478
|
addDiagnostics(diagnostics) {
|
|
420
479
|
this.diagnostics.push(...diagnostics);
|
|
@@ -472,7 +531,7 @@ class Scope {
|
|
|
472
531
|
const files = this.getOwnFiles();
|
|
473
532
|
for (const file of files) {
|
|
474
533
|
//either XML components or files without a typedef
|
|
475
|
-
if ((0, reflection_1.isXmlFile)(file) || !file.hasTypedef) {
|
|
534
|
+
if ((0, reflection_1.isXmlFile)(file) || ((0, reflection_1.isBrsFile)(file) && !file.hasTypedef)) {
|
|
476
535
|
callback(file);
|
|
477
536
|
}
|
|
478
537
|
}
|
|
@@ -483,14 +542,16 @@ class Scope {
|
|
|
483
542
|
*/
|
|
484
543
|
getOwnCallables() {
|
|
485
544
|
let result = [];
|
|
486
|
-
this.logDebug('getOwnCallables() files: ', () => this.getOwnFiles().map(x => x.
|
|
545
|
+
this.logDebug('getOwnCallables() files: ', () => this.getOwnFiles().map(x => x.destPath));
|
|
487
546
|
//get callables from own files
|
|
488
547
|
this.enumerateOwnFiles((file) => {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
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
|
+
}
|
|
494
555
|
}
|
|
495
556
|
});
|
|
496
557
|
return result;
|
|
@@ -498,64 +559,27 @@ class Scope {
|
|
|
498
559
|
/**
|
|
499
560
|
* Builds a tree of namespace objects
|
|
500
561
|
*/
|
|
501
|
-
buildNamespaceLookup() {
|
|
562
|
+
buildNamespaceLookup(options = { okToCache: true }) {
|
|
502
563
|
let namespaceLookup = new Map();
|
|
564
|
+
options.okToCache = true;
|
|
503
565
|
this.enumerateBrsFiles((file) => {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
for (let part of nameParts) {
|
|
512
|
-
loopName = loopName === null ? part : `${loopName}.${part}`;
|
|
513
|
-
let lowerLoopName = loopName.toLowerCase();
|
|
514
|
-
if (!namespaceLookup.has(lowerLoopName)) {
|
|
515
|
-
namespaceLookup.set(lowerLoopName, {
|
|
516
|
-
file: file,
|
|
517
|
-
fullName: loopName,
|
|
518
|
-
nameRange: namespaceStatement.nameExpression.range,
|
|
519
|
-
lastPartName: part,
|
|
520
|
-
namespaces: new Map(),
|
|
521
|
-
classStatements: {},
|
|
522
|
-
functionStatements: {},
|
|
523
|
-
enumStatements: new Map(),
|
|
524
|
-
constStatements: new Map(),
|
|
525
|
-
statements: [],
|
|
526
|
-
symbolTable: new SymbolTable_1.SymbolTable(`Namespace Aggregate: '${loopName}'`, () => this.symbolTable)
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
let ns = namespaceLookup.get(name.toLowerCase());
|
|
531
|
-
ns.statements.push(...namespaceStatement.body.statements);
|
|
532
|
-
for (let statement of namespaceStatement.body.statements) {
|
|
533
|
-
if ((0, reflection_1.isClassStatement)(statement) && statement.name) {
|
|
534
|
-
ns.classStatements[statement.name.text.toLowerCase()] = statement;
|
|
535
|
-
}
|
|
536
|
-
else if ((0, reflection_1.isFunctionStatement)(statement) && statement.name) {
|
|
537
|
-
ns.functionStatements[statement.name.text.toLowerCase()] = statement;
|
|
538
|
-
}
|
|
539
|
-
else if ((0, reflection_1.isEnumStatement)(statement) && statement.fullName) {
|
|
540
|
-
ns.enumStatements.set(statement.fullName.toLowerCase(), statement);
|
|
541
|
-
}
|
|
542
|
-
else if ((0, reflection_1.isConstStatement)(statement) && statement.fullName) {
|
|
543
|
-
ns.constStatements.set(statement.fullName.toLowerCase(), statement);
|
|
544
|
-
}
|
|
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);
|
|
545
573
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
parts.pop();
|
|
556
|
-
let parentName = parts.join('.');
|
|
557
|
-
const parent = namespaceLookup.get(parentName.toLowerCase());
|
|
558
|
-
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);
|
|
559
583
|
}
|
|
560
584
|
}
|
|
561
585
|
});
|
|
@@ -571,9 +595,9 @@ class Scope {
|
|
|
571
595
|
logDebug(...args) {
|
|
572
596
|
this.program.logger.debug(this._debugLogComponentName, ...args);
|
|
573
597
|
}
|
|
574
|
-
validate(
|
|
598
|
+
validate(validationOptions = { force: false }) {
|
|
575
599
|
//if this scope is already validated, no need to revalidate
|
|
576
|
-
if (this.isValidated === true && !force) {
|
|
600
|
+
if (this.isValidated === true && !validationOptions.force) {
|
|
577
601
|
this.logDebug('validate(): already validated');
|
|
578
602
|
return;
|
|
579
603
|
}
|
|
@@ -582,10 +606,10 @@ class Scope {
|
|
|
582
606
|
//validate our parent before we validate ourself
|
|
583
607
|
if (parentScope && parentScope.isValidated === false) {
|
|
584
608
|
this.logDebug('validate(): validating parent first');
|
|
585
|
-
parentScope.validate(
|
|
609
|
+
parentScope.validate(validationOptions);
|
|
586
610
|
}
|
|
587
611
|
//clear the scope's errors list (we will populate them from this method)
|
|
588
|
-
this.
|
|
612
|
+
this.clearScopeLevelDiagnostics();
|
|
589
613
|
let callables = this.getAllCallables();
|
|
590
614
|
//sort the callables by filepath and then method name, so the errors will be consistent
|
|
591
615
|
// eslint-disable-next-line prefer-arrow-callback
|
|
@@ -612,16 +636,18 @@ class Scope {
|
|
|
612
636
|
});
|
|
613
637
|
//get a list of all callables, indexed by their lower case names
|
|
614
638
|
let callableContainerMap = util_1.util.getCallableContainersByLowerName(callables);
|
|
615
|
-
let files = this.getOwnFiles();
|
|
616
639
|
//Since statements from files are shared across multiple scopes, we need to link those statements to the current scope
|
|
617
640
|
this.linkSymbolTable();
|
|
618
|
-
|
|
619
|
-
this.program.plugins.emit('onScopeValidate', {
|
|
641
|
+
const scopeValidateEvent = {
|
|
620
642
|
program: this.program,
|
|
621
|
-
scope: this
|
|
622
|
-
|
|
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
|
|
646
|
+
};
|
|
647
|
+
this.program.plugins.emit('beforeScopeValidate', scopeValidateEvent);
|
|
648
|
+
this.program.plugins.emit('onScopeValidate', scopeValidateEvent);
|
|
623
649
|
this._validate(callableContainerMap);
|
|
624
|
-
this.program.plugins.emit('afterScopeValidate',
|
|
650
|
+
this.program.plugins.emit('afterScopeValidate', scopeValidateEvent);
|
|
625
651
|
//unlink all symbol tables from this scope (so they don't accidentally stick around)
|
|
626
652
|
this.unlinkSymbolTable();
|
|
627
653
|
this.isValidated = true;
|
|
@@ -636,12 +662,22 @@ class Scope {
|
|
|
636
662
|
this.validateClasses();
|
|
637
663
|
//do many per-file checks
|
|
638
664
|
this.enumerateBrsFiles((file) => {
|
|
639
|
-
this.diagnosticDetectFunctionCallsWithWrongParamCount(file, callableContainerMap);
|
|
640
665
|
this.diagnosticDetectShadowedLocalVars(file, callableContainerMap);
|
|
641
666
|
this.diagnosticDetectFunctionCollisions(file);
|
|
642
667
|
this.detectVariableNamespaceCollisions(file);
|
|
668
|
+
this.detectNameCollisions(file);
|
|
643
669
|
});
|
|
644
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
|
+
}
|
|
645
681
|
/**
|
|
646
682
|
* Mark this scope as invalid, which means its `validate()` function needs to be called again before use.
|
|
647
683
|
*/
|
|
@@ -654,6 +690,7 @@ class Scope {
|
|
|
654
690
|
return this.cache.getOrAdd('symbolTable', () => {
|
|
655
691
|
var _a;
|
|
656
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);
|
|
657
694
|
for (let file of this.getOwnFiles()) {
|
|
658
695
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
659
696
|
result.mergeSymbolTable((_a = file.parser) === null || _a === void 0 ? void 0 : _a.symbolTable);
|
|
@@ -666,31 +703,88 @@ class Scope {
|
|
|
666
703
|
* Builds the current symbol table for the scope, by merging the tables for all the files in this scope.
|
|
667
704
|
* Also links all file symbols tables to this new table
|
|
668
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
|
+
* ```
|
|
669
720
|
*/
|
|
670
721
|
linkSymbolTable() {
|
|
722
|
+
var _a;
|
|
723
|
+
SymbolTable_1.SymbolTable.cacheVerifier.generateToken();
|
|
671
724
|
for (const file of this.getAllFiles()) {
|
|
672
725
|
if ((0, reflection_1.isBrsFile)(file)) {
|
|
673
|
-
file.parser.symbolTable.pushParentProvider(() => this.symbolTable);
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
726
|
+
this.linkSymbolTableDisposables.push(file.parser.symbolTable.pushParentProvider(() => this.symbolTable));
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
//Add namespace aggregates to namespace member tables
|
|
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) {
|
|
734
|
+
let currentNSType = null;
|
|
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;
|
|
678
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 });
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
this.symbolTable.addSymbol(nsContainer.lastPartName, { definingNode: existingNsStmt }, currentNSType, getTypeOptions.flags);
|
|
760
|
+
this.symbolsAddedDuringLinking.push({ symbolTable: this.symbolTable, name: nsContainer.lastPartName, flags: getTypeOptions.flags });
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
else {
|
|
764
|
+
break;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
// Existing known namespace
|
|
769
|
+
}
|
|
770
|
+
if (!namespaceTypesKnown.has(nsName)) {
|
|
771
|
+
namespaceTypesKnown.set(nsName, currentNSType);
|
|
679
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));
|
|
680
777
|
}
|
|
681
|
-
this.program.typeCacheVerifier.generateToken();
|
|
682
778
|
}
|
|
683
779
|
unlinkSymbolTable() {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
namespace.getSymbolTable().removeSibling(this.namespaceLookup.get(namespaceNameLower).symbolTable);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
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();
|
|
693
786
|
}
|
|
787
|
+
this.linkSymbolTableDisposables = [];
|
|
694
788
|
}
|
|
695
789
|
detectVariableNamespaceCollisions(file) {
|
|
696
790
|
var _a, _b;
|
|
@@ -701,7 +795,7 @@ class Scope {
|
|
|
701
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());
|
|
702
796
|
//see if the param matches any starting namespace part
|
|
703
797
|
if (namespace) {
|
|
704
|
-
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: [{
|
|
705
799
|
message: 'Namespace declared here',
|
|
706
800
|
location: util_1.util.createLocation(vscode_uri_1.URI.file(namespace.file.srcPath).toString(), namespace.nameRange)
|
|
707
801
|
}] }));
|
|
@@ -713,7 +807,7 @@ class Scope {
|
|
|
713
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());
|
|
714
808
|
//see if the param matches any starting namespace part
|
|
715
809
|
if (namespace) {
|
|
716
|
-
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: [{
|
|
717
811
|
message: 'Namespace declared here',
|
|
718
812
|
location: util_1.util.createLocation(vscode_uri_1.URI.file(namespace.file.srcPath).toString(), namespace.nameRange)
|
|
719
813
|
}] }));
|
|
@@ -730,13 +824,78 @@ class Scope {
|
|
|
730
824
|
if (lowerFuncName) {
|
|
731
825
|
//find function declarations with the same name as a stdlib function
|
|
732
826
|
if (globalCallables_1.globalCallableMap.has(lowerFuncName)) {
|
|
733
|
-
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 }));
|
|
734
828
|
}
|
|
735
829
|
//find any functions that have the same name as a class
|
|
736
|
-
|
|
737
|
-
|
|
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
|
+
}] }));
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
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;
|
|
738
892
|
}
|
|
739
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 }));
|
|
740
899
|
}
|
|
741
900
|
}
|
|
742
901
|
getNewExpressions() {
|
|
@@ -753,38 +912,9 @@ class Scope {
|
|
|
753
912
|
validateClasses() {
|
|
754
913
|
let validator = new ClassValidator_1.BsClassValidator();
|
|
755
914
|
validator.validate(this);
|
|
756
|
-
this.diagnostics.push(...validator.diagnostics
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
* Detect calls to functions with the incorrect number of parameters
|
|
760
|
-
*/
|
|
761
|
-
diagnosticDetectFunctionCallsWithWrongParamCount(file, callableContainersByLowerName) {
|
|
762
|
-
//validate all function calls
|
|
763
|
-
for (let expCall of file.functionCalls) {
|
|
764
|
-
let callableContainersWithThisName = callableContainersByLowerName.get(expCall.name.toLowerCase());
|
|
765
|
-
//use the first item from callablesByLowerName, because if there are more, that's a separate error
|
|
766
|
-
let knownCallableContainer = callableContainersWithThisName ? callableContainersWithThisName[0] : undefined;
|
|
767
|
-
if (knownCallableContainer) {
|
|
768
|
-
//get min/max parameter count for callable
|
|
769
|
-
let minParams = 0;
|
|
770
|
-
let maxParams = 0;
|
|
771
|
-
for (let param of knownCallableContainer.callable.params) {
|
|
772
|
-
maxParams++;
|
|
773
|
-
//optional parameters must come last, so we can assume that minParams won't increase once we hit
|
|
774
|
-
//the first isOptional
|
|
775
|
-
if (param.isOptional !== true) {
|
|
776
|
-
minParams++;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
let expCallArgCount = expCall.args.length;
|
|
780
|
-
if (expCall.args.length > maxParams || expCall.args.length < minParams) {
|
|
781
|
-
let minMaxParamsText = minParams === maxParams ? maxParams : `${minParams}-${maxParams}`;
|
|
782
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(minMaxParamsText, expCallArgCount)), { range: expCall.nameRange,
|
|
783
|
-
//TODO detect end of expression call
|
|
784
|
-
file: file }));
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
}
|
|
915
|
+
this.diagnostics.push(...validator.diagnostics.map(diag => {
|
|
916
|
+
return Object.assign(Object.assign({}, diag), { origin: interfaces_1.DiagnosticOrigin.Scope });
|
|
917
|
+
}));
|
|
788
918
|
}
|
|
789
919
|
/**
|
|
790
920
|
* Detect local variables (function scope) that have the same name as scope calls
|
|
@@ -793,39 +923,34 @@ class Scope {
|
|
|
793
923
|
var _a;
|
|
794
924
|
const classMap = this.getClassMap();
|
|
795
925
|
//loop through every function scope
|
|
796
|
-
for (let
|
|
926
|
+
for (let funcScope of file.functionScopes) {
|
|
797
927
|
//every var declaration in this function scope
|
|
798
|
-
for (let varDeclaration of
|
|
928
|
+
for (let varDeclaration of funcScope.variableDeclarations) {
|
|
799
929
|
const varName = varDeclaration.name;
|
|
800
930
|
const lowerVarName = varName.toLowerCase();
|
|
801
|
-
|
|
802
|
-
|
|
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)) {
|
|
803
937
|
//local var function with same name as stdlib function
|
|
804
|
-
if (
|
|
805
|
-
|
|
806
|
-
globalCallables_1.globalCallableMap.has(lowerVarName)) {
|
|
807
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('stdlib')), { range: varDeclaration.nameRange, file: file }));
|
|
808
|
-
//this check needs to come after the stdlib one, because the stdlib functions are included
|
|
809
|
-
//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 }));
|
|
810
940
|
}
|
|
811
|
-
else if (
|
|
812
|
-
//has same name as scope function
|
|
813
|
-
callableContainerMap.has(lowerVarName)) {
|
|
814
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.localVarFunctionShadowsParentFunction('scope')), { range: varDeclaration.nameRange, file: file }));
|
|
815
|
-
}
|
|
816
|
-
//var is not a function
|
|
817
941
|
}
|
|
818
|
-
else if (
|
|
819
|
-
//is NOT a callable from stdlib (because non-function local vars can have same name as stdlib names)
|
|
820
|
-
!globalCallables_1.globalCallableMap.has(lowerVarName)) {
|
|
942
|
+
else if (callableContainerMap.has(lowerVarName)) {
|
|
821
943
|
//is same name as a callable
|
|
822
|
-
if (
|
|
823
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
824
|
-
//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 }));
|
|
825
946
|
}
|
|
826
|
-
else
|
|
827
|
-
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 }));
|
|
828
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 }));
|
|
829
954
|
}
|
|
830
955
|
}
|
|
831
956
|
}
|
|
@@ -864,9 +989,9 @@ class Scope {
|
|
|
864
989
|
//same file: skip redundant imports
|
|
865
990
|
continue;
|
|
866
991
|
}
|
|
867
|
-
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,
|
|
868
993
|
//grab the last item in the list, which should be the closest ancestor's version
|
|
869
|
-
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 }));
|
|
870
995
|
}
|
|
871
996
|
}
|
|
872
997
|
}
|
|
@@ -874,7 +999,7 @@ class Scope {
|
|
|
874
999
|
if (ownCallables.length > 1) {
|
|
875
1000
|
for (let callableContainer of ownCallables) {
|
|
876
1001
|
let callable = callableContainer.callable;
|
|
877
|
-
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 }));
|
|
878
1003
|
}
|
|
879
1004
|
}
|
|
880
1005
|
}
|
|
@@ -901,11 +1026,11 @@ class Scope {
|
|
|
901
1026
|
let scriptImports = this.getOwnScriptImports();
|
|
902
1027
|
//verify every script import
|
|
903
1028
|
for (let scriptImport of scriptImports) {
|
|
904
|
-
let referencedFile = this.getFileByRelativePath(scriptImport.
|
|
1029
|
+
let referencedFile = this.getFileByRelativePath(scriptImport.destPath);
|
|
905
1030
|
//if we can't find the file
|
|
906
1031
|
if (!referencedFile) {
|
|
907
1032
|
//skip the default bslib file, it will exist at transpile time but should not show up in the program during validation cycle
|
|
908
|
-
if (scriptImport.
|
|
1033
|
+
if (scriptImport.destPath === this.program.bslibPkgPath) {
|
|
909
1034
|
continue;
|
|
910
1035
|
}
|
|
911
1036
|
let dInfo;
|
|
@@ -915,11 +1040,11 @@ class Scope {
|
|
|
915
1040
|
else {
|
|
916
1041
|
dInfo = DiagnosticMessages_1.DiagnosticMessages.referencedFileDoesNotExist();
|
|
917
1042
|
}
|
|
918
|
-
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 }));
|
|
919
1044
|
//if the character casing of the script import path does not match that of the actual path
|
|
920
1045
|
}
|
|
921
|
-
else if (scriptImport.
|
|
922
|
-
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 }));
|
|
923
1048
|
}
|
|
924
1049
|
}
|
|
925
1050
|
}
|
|
@@ -932,7 +1057,7 @@ class Scope {
|
|
|
932
1057
|
}
|
|
933
1058
|
let files = this.getAllFiles();
|
|
934
1059
|
for (let file of files) {
|
|
935
|
-
if (file.
|
|
1060
|
+
if (file.destPath.toLowerCase() === relativePath.toLowerCase()) {
|
|
936
1061
|
return file;
|
|
937
1062
|
}
|
|
938
1063
|
}
|
|
@@ -945,35 +1070,6 @@ class Scope {
|
|
|
945
1070
|
let hasFile = files.includes(file);
|
|
946
1071
|
return hasFile;
|
|
947
1072
|
}
|
|
948
|
-
/**
|
|
949
|
-
* Get all callables as completionItems
|
|
950
|
-
*/
|
|
951
|
-
getCallablesAsCompletions(parseMode) {
|
|
952
|
-
let completions = [];
|
|
953
|
-
let callables = this.getAllCallables();
|
|
954
|
-
if (parseMode === Parser_1.ParseMode.BrighterScript) {
|
|
955
|
-
//throw out the namespaced callables (they will be handled by another method)
|
|
956
|
-
callables = callables.filter(x => x.callable.hasNamespace === false);
|
|
957
|
-
}
|
|
958
|
-
for (let callableContainer of callables) {
|
|
959
|
-
completions.push(this.createCompletionFromCallable(callableContainer));
|
|
960
|
-
}
|
|
961
|
-
return completions;
|
|
962
|
-
}
|
|
963
|
-
createCompletionFromCallable(callableContainer) {
|
|
964
|
-
return {
|
|
965
|
-
label: callableContainer.callable.getName(Parser_1.ParseMode.BrighterScript),
|
|
966
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function,
|
|
967
|
-
detail: callableContainer.callable.shortDescription,
|
|
968
|
-
documentation: callableContainer.callable.documentation ? { kind: 'markdown', value: callableContainer.callable.documentation } : undefined
|
|
969
|
-
};
|
|
970
|
-
}
|
|
971
|
-
createCompletionFromFunctionStatement(statement) {
|
|
972
|
-
return {
|
|
973
|
-
label: statement.getName(Parser_1.ParseMode.BrighterScript),
|
|
974
|
-
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
975
|
-
};
|
|
976
|
-
}
|
|
977
1073
|
/**
|
|
978
1074
|
* Get the definition (where was this thing first defined) of the symbol under the position
|
|
979
1075
|
*/
|
|
@@ -981,37 +1077,6 @@ class Scope {
|
|
|
981
1077
|
// Overridden in XMLScope. Brs files use implementation in BrsFile
|
|
982
1078
|
return [];
|
|
983
1079
|
}
|
|
984
|
-
/**
|
|
985
|
-
* Scan all files for property names, and return them as completions
|
|
986
|
-
*/
|
|
987
|
-
getPropertyNameCompletions() {
|
|
988
|
-
let results = [];
|
|
989
|
-
this.enumerateBrsFiles((file) => {
|
|
990
|
-
results.push(...file.propertyNameCompletions);
|
|
991
|
-
});
|
|
992
|
-
return results;
|
|
993
|
-
}
|
|
994
|
-
getAllClassMemberCompletions() {
|
|
995
|
-
let results = new Map();
|
|
996
|
-
let filesSearched = new Set();
|
|
997
|
-
for (const file of this.getAllFiles()) {
|
|
998
|
-
if ((0, reflection_1.isXmlFile)(file) || filesSearched.has(file)) {
|
|
999
|
-
continue;
|
|
1000
|
-
}
|
|
1001
|
-
filesSearched.add(file);
|
|
1002
|
-
for (let cs of file.parser.references.classStatements) {
|
|
1003
|
-
for (let s of [...cs.methods, ...cs.fields]) {
|
|
1004
|
-
if (!results.has(s.name.text) && s.name.text.toLowerCase() !== 'new') {
|
|
1005
|
-
results.set(s.name.text, {
|
|
1006
|
-
label: s.name.text,
|
|
1007
|
-
kind: (0, reflection_1.isMethodStatement)(s) ? vscode_languageserver_1.CompletionItemKind.Method : vscode_languageserver_1.CompletionItemKind.Field
|
|
1008
|
-
});
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
return results;
|
|
1014
|
-
}
|
|
1015
1080
|
/**
|
|
1016
1081
|
* @param className - The name of the class (including namespace if possible)
|
|
1017
1082
|
* @param callsiteNamespace - the name of the namespace where the call site resides (this is NOT the known namespace of the class).
|