diff --git a/src/EditorFeatures/CSharpTest/InlineMethod/CSharpInlineMethodTests.cs b/src/EditorFeatures/CSharpTest/InlineMethod/CSharpInlineMethodTests.cs index 31d7b879523742a94cfc8aad1e2383ffee9efa1b..2c15582496cbf6f269fdc625cb5d002019857b82 100644 --- a/src/EditorFeatures/CSharpTest/InlineMethod/CSharpInlineMethodTests.cs +++ b/src/EditorFeatures/CSharpTest/InlineMethod/CSharpInlineMethodTests.cs @@ -288,9 +288,9 @@ public class TestClass { private void Caller(float s1, float s2) { - float s3 = SomeCaculation(s1); - float s4 = SomeCaculation(s2); - System.Console.WriteLine(""This is s1"" + s3 + ""This is s2"" + s4); + float s11 = SomeCaculation(s1); + float s21 = SomeCaculation(s2); + System.Console.WriteLine(""This is s1"" + s11 + ""This is s2"" + s21); } private void Callee(float s1, float s2) diff --git a/src/Features/CSharp/Portable/CodeRefactorings/InlineMethod/CSharpInlineMethodRefactoringProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/InlineMethod/CSharpInlineMethodRefactoringProvider.cs index d101a2a0d860683779d8e5ef579502da47d802ef..8da1b062e5b9486c256dc5166041e9a4b02f7d68 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/InlineMethod/CSharpInlineMethodRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/InlineMethod/CSharpInlineMethodRefactoringProvider.cs @@ -44,7 +44,7 @@ internal sealed class CSharpInlineMethodRefactoringProvider : [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public CSharpInlineMethodRefactoringProvider() : base(CSharpSyntaxFacts.Instance) + public CSharpInlineMethodRefactoringProvider() : base(CSharpSyntaxFacts.Instance, CSharpSemanticFactsService.Instance) { } diff --git a/src/Features/Core/Portable/InlineMethod/AbstractInlineMethodRefactoringProvider.InlineContext.cs b/src/Features/Core/Portable/InlineMethod/AbstractInlineMethodRefactoringProvider.InlineContext.cs index 65f342abee5ca4d5f108a62951f1231e5a5c7b30..07354b9f1e71afd850f85d0819800a9fa25b7b2a 100644 --- a/src/Features/Core/Portable/InlineMethod/AbstractInlineMethodRefactoringProvider.InlineContext.cs +++ b/src/Features/Core/Portable/InlineMethod/AbstractInlineMethodRefactoringProvider.InlineContext.cs @@ -12,13 +12,13 @@ using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.LanguageServices; -using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.InlineMethod { - internal abstract partial class AbstractInlineMethodRefactoringProvider + internal abstract partial class AbstractInlineMethodRefactoringProvider where TInvocationSyntaxNode : SyntaxNode where TExpressionSyntax : SyntaxNode where TArgumentSyntax : SyntaxNode @@ -74,6 +74,7 @@ private class InlineMethodContext public static async Task GetInlineContextAsync( AbstractInlineMethodRefactoringProvider inlineMethodRefactoringProvider, ISyntaxFacts syntaxFacts, + ISemanticFactsService semanticFactsService, Document document, SemanticModel semanticModel, SyntaxNode calleeInvocationSyntaxNode, @@ -84,7 +85,8 @@ private class InlineMethodContext CancellationToken cancellationToken) { var syntaxGenerator = SyntaxGenerator.GetGenerator(document); - var inlineSyntaxNode = inlineMethodRefactoringProvider.GetInlineStatement(calleeMethodDeclarationSyntaxNode); + var inlineSyntaxNode = + inlineMethodRefactoringProvider.GetInlineStatement(calleeMethodDeclarationSyntaxNode); // The replacement/insertion work done might cause naming conflict. // So first compute a mapping from symbol to newName (renameTable) // Cases are: @@ -141,7 +143,8 @@ private class InlineMethodContext .Where(parameterAndName => parameterAndName.Name != null) .ToImmutableArray(); - var parametersWithVariableDeclarationArgumentToName = methodParametersInfo.ParametersWithVariableDeclarationArgument + var parametersWithVariableDeclarationArgumentToName = methodParametersInfo + .ParametersWithVariableDeclarationArgument .Select(parameterAndArgument => (parameterAndArgument.parameterSymbol, semanticModel @@ -150,29 +153,16 @@ private class InlineMethodContext .Where(parameterAndName => parameterAndName.Name != null) .ToImmutableArray(); - var allSymbolsOfCaller = semanticModel.LookupSymbols(calleeInvocationSyntaxNode.Span.End); - var inUsedNamesOfCaller = allSymbolsOfCaller - .Select(symbol => symbol.Name) - .ToImmutableHashSet(); - var staticAndFieldNamesInClass = allSymbolsOfCaller - .Where(symbol => symbol.IsStatic || symbol.IsKind(SymbolKind.Field)) - .Select(symbol => symbol.Name) - .ToImmutableHashSet(); - var operationVisitor = new VariableDeclaratorOperationVisitor(cancellationToken); - var calleeOperation = semanticModel.GetOperation(calleeMethodDeclarationSyntaxNode, cancellationToken); - var localSymbolOfCallee = operationVisitor.FindAllLocalSymbols(calleeOperation); - var inUsedNameOfCallee = localSymbolOfCallee - .Select(symbol => symbol.Name) - .Concat(staticAndFieldNamesInClass) - .ToImmutableHashSet(); - var renameTable = ComputeRenameTable( + semanticFactsService, + semanticModel, + calleeInvocationSyntaxNode, + inlineSyntaxNode, parametersWithIdentifierArgumentToName!, - methodParametersInfo.ParametersNeedGenerateDeclarations.SelectAsArray(parameterToArgument => parameterToArgument.parameterSymbol), + methodParametersInfo.ParametersNeedGenerateDeclarations.SelectAsArray(parameterToArgument => + parameterToArgument.parameterSymbol), parametersWithVariableDeclarationArgumentToName!, - inUsedNamesOfCaller, - localSymbolOfCallee, - inUsedNameOfCallee); + cancellationToken); // Generate all the statements need to be put in the caller. var localDeclarationStatementsNeedInsert = GetLocalDeclarationStatementsNeedInsert( @@ -187,7 +177,8 @@ private class InlineMethodContext // The syntax node that contains the invocation syntax node. // Example1: var x = Callee(); Then LocalDeclarationStatement is the containing syntax node. // Example1: if (Callee()) {} Then IfStatement is the containing syntax node - var statementContainingCallee = inlineMethodRefactoringProvider.GetStatementContainsCallee(calleeInvocationSyntaxNode); + var statementContainingCallee = + inlineMethodRefactoringProvider.GetStatementContainsCallee(calleeInvocationSyntaxNode); // Do the replacement work within the callee. Including: // 1. Literal replacement @@ -282,18 +273,21 @@ private class InlineMethodContext // return 1; // }; // One variable declaration needs to be generated. - var unusedTemporaryName = GetUnusedName( - TemporaryName, - inUsedNamesOfCaller - .Concat(inUsedNameOfCallee) - .Concat(renameTable.Values) - .ToImmutableHashSet()); + var unusedLocalName = + semanticFactsService.GenerateUniqueLocalName( + semanticModel, + calleeInvocationSyntaxNode, + null, + TemporaryName, + renameTable.Values, + cancellationToken); return new InlineMethodContext( localDeclarationStatementsNeedInsert, statementContainingCallee, syntaxGenerator - .LocalDeclarationStatement(calleeMethodSymbol.ReturnType, unusedTemporaryName, inlineSyntaxNode), + .LocalDeclarationStatement(calleeMethodSymbol.ReturnType, unusedLocalName.Text, + inlineSyntaxNode), statementContainingCallee, containsAwaitExpression); } @@ -302,7 +296,7 @@ private class InlineMethodContext localDeclarationStatementsNeedInsert, statementContainingCallee, inlineMethodRefactoringProvider.Parenthesize(inlineSyntaxNode) - // add the trivia of the calleeInvocationSyntaxNode so that the format is correct + // add the trivia of the calleeInvocationSyntaxNode so that the format is correct .WithLeadingTrivia(calleeInvocationSyntaxNode.GetLeadingTrivia()) .WithTrailingTrivia(calleeInvocationSyntaxNode.GetTrailingTrivia()), calleeInvocationSyntaxNode, @@ -310,21 +304,28 @@ private class InlineMethodContext } private static ImmutableArray GetLocalDeclarationStatementsNeedInsert( - AbstractInlineMethodRefactoringProvider inlineMethodRefactoringProvider, + AbstractInlineMethodRefactoringProvider + inlineMethodRefactoringProvider, SemanticModel semanticModel, SyntaxGenerator syntaxGenerator, - ImmutableArray<(IParameterSymbol parameterSymbol, ImmutableArray arguments)> parametersNeedGenerateDeclarations, - ImmutableArray<(IParameterSymbol parameterSymbol, string name)> parametersWithVariableDeclarationArgument, + ImmutableArray<(IParameterSymbol parameterSymbol, ImmutableArray arguments)> + parametersNeedGenerateDeclarations, + ImmutableArray<(IParameterSymbol parameterSymbol, string name)> + parametersWithVariableDeclarationArgument, ImmutableDictionary renameTable, CancellationToken cancellationToken) => parametersNeedGenerateDeclarations - .Select(parameterAndArguments => CreateLocalDeclarationStatement(inlineMethodRefactoringProvider, semanticModel, syntaxGenerator, renameTable, parameterAndArguments, cancellationToken)) + .Select(parameterAndArguments => CreateLocalDeclarationStatement(inlineMethodRefactoringProvider, + semanticModel, syntaxGenerator, renameTable, parameterAndArguments, cancellationToken)) .Concat(parametersWithVariableDeclarationArgument - .Select(parameterAndName => syntaxGenerator.LocalDeclarationStatement(parameterAndName.parameterSymbol.Type, parameterAndName.name))) + .Select(parameterAndName => + syntaxGenerator.LocalDeclarationStatement(parameterAndName.parameterSymbol.Type, + parameterAndName.name))) .ToImmutableArray(); private static SyntaxNode CreateLocalDeclarationStatement( - AbstractInlineMethodRefactoringProvider inlineMethodRefactoringProvider, + AbstractInlineMethodRefactoringProvider + inlineMethodRefactoringProvider, SemanticModel semanticModel, SyntaxGenerator syntaxGenerator, ImmutableDictionary renameTable, @@ -332,17 +333,22 @@ private class InlineMethodContext CancellationToken cancellationToken) { var (parameterSymbol, arguments) = parameterAndArguments; - var name = renameTable.ContainsKey(parameterSymbol) ? renameTable[parameterSymbol] : parameterSymbol.Name; + var name = renameTable.ContainsKey(parameterSymbol) + ? renameTable[parameterSymbol] + : parameterSymbol.Name; var generateArrayDeclarationStatement = parameterSymbol.IsParams - // If arguments number is not one, it means this paramsArray maps to multiple or zero arguments. An array declaration is needed. - && (arguments.Length != 1 - // If the arguments number is one, it could be the single element of the array (an array declaration is needed) - // Example: void Callee(params int[] x) {} - // void Caller() { Callee(1, 2, 3) } - // or it could an array (like array creation, and array declaration is not need) - // Example: void Callee(params int[] x) {} - // void Caller() { Callee(new int[] { 1, 2, 3}) } - || (arguments.Length == 1 && !parameterSymbol.Type.Equals(semanticModel.GetTypeInfo(arguments[0], cancellationToken).Type))); + // If arguments number is not one, it means this paramsArray maps to multiple or zero arguments. An array declaration is needed. + && (arguments.Length != 1 + // If the arguments number is one, it could be the single element of the array (an array declaration is needed) + // Example: void Callee(params int[] x) {} + // void Caller() { Callee(1, 2, 3) } + // or it could an array (like array creation, and array declaration is not need) + // Example: void Callee(params int[] x) {} + // void Caller() { Callee(new int[] { 1, 2, 3}) } + || (arguments.Length == 1 && + !parameterSymbol.Type.Equals(semanticModel + .GetTypeInfo(arguments[0], cancellationToken) + .Type))); if (generateArrayDeclarationStatement) { @@ -370,7 +376,9 @@ private class InlineMethodContext foreach (var (symbol, syntaxNode) in replacementTable) { - var allReferences = await SymbolFinder.FindReferencesAsync(symbol, document.Project.Solution, cancellationToken).ConfigureAwait(false); + var allReferences = await SymbolFinder + .FindReferencesAsync(symbol, document.Project.Solution, cancellationToken) + .ConfigureAwait(false); var allSyntaxNodesToReplace = allReferences .SelectMany(reference => reference.Locations .Select(location => root.FindNode(location.Location.SourceSpan))) @@ -396,20 +404,25 @@ private class InlineMethodContext /// is the replacement syntax node for all its occurence. /// private static ImmutableDictionary ComputeReplacementTable( - AbstractInlineMethodRefactoringProvider inlineMethodRefactoringProvider, + AbstractInlineMethodRefactoringProvider + inlineMethodRefactoringProvider, IMethodSymbol calleeMethodSymbol, - ImmutableArray<(IParameterSymbol parameterSymbol , SyntaxNode literalExpression)> parametersWithLiteralArgument, + ImmutableArray<(IParameterSymbol parameterSymbol, SyntaxNode literalExpression)> + parametersWithLiteralArgument, ImmutableArray parametersWithDefaultValue, SyntaxGenerator syntaxGenerator, ImmutableDictionary renameTable) { var typeParametersReplacementQuery = calleeMethodSymbol.TypeParameters .Zip(calleeMethodSymbol.TypeArguments, - (parameter, argument) => (parameter: (ISymbol)parameter, syntaxNode: inlineMethodRefactoringProvider.GenerateTypeSyntax(argument))); + (parameter, argument) => (parameter: (ISymbol)parameter, + syntaxNode: inlineMethodRefactoringProvider.GenerateTypeSyntax(argument))); var defaultValueReplacementQuery = parametersWithDefaultValue - .Select(symbol => (parameter: (ISymbol)symbol, syntaxNode: syntaxGenerator.LiteralExpression(symbol.ExplicitDefaultValue))); + .Select(symbol => (parameter: (ISymbol)symbol, + syntaxNode: syntaxGenerator.LiteralExpression(symbol.ExplicitDefaultValue))); var literalArgumentReplacementQuery = parametersWithLiteralArgument - .Select(parameterAndArgument => (parameter: (ISymbol)parameterAndArgument.parameterSymbol, syntaxNode: parameterAndArgument.literalExpression)); + .Select(parameterAndArgument => (parameter: (ISymbol)parameterAndArgument.parameterSymbol, + syntaxNode: parameterAndArgument.literalExpression)); return renameTable .Select(kvp => (parameter: kvp.Key, @@ -420,32 +433,24 @@ private class InlineMethodContext .ToImmutableDictionary(tuple => tuple.parameter, tuple => tuple.syntaxNode); } - private static string GetUnusedName(string preferredNamePrefix, ImmutableHashSet inUsedNames) - { - var newName = preferredNamePrefix; - while (inUsedNames.Contains(preferredNamePrefix)) - { - newName = GenerateNewName(preferredNamePrefix); - } - - return newName; - } - /// /// Get a map which key is the symbol is the identifier in , and value is /// its new name after inlining. /// private static ImmutableDictionary ComputeRenameTable( + ISemanticFactsService semanticFacts, + SemanticModel semanticModel, + SyntaxNode calleeInvocationSyntaxNode, + SyntaxNode inlineSyntaxNode, ImmutableArray<(IParameterSymbol parameterSymbol, string variableName)> identifierArguments, ImmutableArray parametersNeedGenerateDeclaration, ImmutableArray<(IParameterSymbol parameterSymbol, string variableName)> variableDeclarationArguments, - ImmutableHashSet inUsedNamesOfCaller, - ImmutableArray localSymbolsOfCallee, - ImmutableHashSet inUsedNamesOfCallee) + CancellationToken cancellationToken) { + var renameTable = new Dictionary(); // After inlining, there might be naming conflict because // case 1: caller's identifier is introduced to callee. - // Example: + // Example 1 (for identifier): // Before: // void Caller() // { @@ -466,8 +471,44 @@ private static string GetUnusedName(string preferredNamePrefix, ImmutableHashSet // { // int i = 100; // } - // - // case 2: callee's parameter is introduced to caller + // Example 2 (for variable declaration): + // Before: + // void Caller() + // { + // int i = 10; + // Callee(out i) + // } + // void Callee(out int j) + // { + // DoSomething(out j, out int i); + // } + // After: + // void Caller() + // { + // int i = 10; + // DoSomething(out i, out int i2); + // } + // void Callee(out int j) + // { + // DoSomething(out j, out int i); + // } + foreach (var (parameterSymbol, variableName) in identifierArguments.Concat(variableDeclarationArguments)) + { + if (!parameterSymbol.Name.Equals(variableName)) + { + var usedNames = renameTable.Values; + renameTable[parameterSymbol] = semanticFacts + .GenerateUniqueLocalName( + semanticModel, + inlineSyntaxNode, + null, + variableName, + usedNames, + cancellationToken).Text; + } + } + + // Case 2: callee's parameter is introduced to caller // Before: // void Caller() // { @@ -489,107 +530,21 @@ private static string GetUnusedName(string preferredNamePrefix, ImmutableHashSet // { // Bar(i); // } - inUsedNamesOfCallee = inUsedNamesOfCallee - .Concat(identifierArguments.Select(parameterAndName => parameterAndName.variableName)) - .Concat(variableDeclarationArguments.Select(parameterAndName => parameterAndName.variableName)) - .ToImmutableHashSet(); - - var renameTable = identifierArguments.Concat(variableDeclarationArguments) - .ToDictionary(parameterAndName => (ISymbol)parameterAndName.parameterSymbol, - parameterAndName => parameterAndName.variableName); - - // Handle case 1 discussed above - foreach (var localSymbol in localSymbolsOfCallee) - { - var localSymbolName = localSymbol.Name; - while (inUsedNamesOfCallee.Contains(localSymbolName) - || renameTable.ContainsValue(localSymbolName)) - { - localSymbolName = GenerateNewName(localSymbolName); - } - - if (!localSymbolName.Equals(localSymbol.Name)) - { - renameTable[localSymbol] = localSymbolName; - } - } - - // Handle case 2 discussed above foreach (var parameterSymbol in parametersNeedGenerateDeclaration) { - var parameterName = parameterSymbol.Name; - while (inUsedNamesOfCaller.Contains(parameterName) - || inUsedNamesOfCallee.Contains(parameterName) - || renameTable.ContainsValue(parameterName)) - { - parameterName = GenerateNewName(parameterName); - } - - if (!parameterName.Equals(parameterSymbol.Name)) - { - renameTable[parameterSymbol] = parameterName; - } + var usedNames = renameTable.Values; + renameTable[parameterSymbol] = semanticFacts + .GenerateUniqueLocalName( + semanticModel, + calleeInvocationSyntaxNode, + null, + parameterSymbol.Name, + usedNames, + cancellationToken).Text; } return renameTable.ToImmutableDictionary(); } - - /// - /// Generate a new identifier name. If has a number suffix, - /// increase it by 1. Otherwise, append 1 to it. - /// - private static string GenerateNewName(string preferredName) - { - var stack = new Stack(); - for (var i = preferredName.Length - 1; i >= 0; i--) - { - var currentCharacter = preferredName[i]; - if (char.IsNumber(currentCharacter)) - { - stack.Push(currentCharacter); - } - else - { - break; - } - } - - var suffixNumber = stack.IsEmpty() ? 1 : int.Parse(new string(stack.ToArray())) + 1; - return preferredName.Substring(0, preferredName.Length - stack.Count) + suffixNumber; - } - } - - private class VariableDeclaratorOperationVisitor : OperationWalker - { - private readonly CancellationToken _cancellationToken; - private readonly HashSet _localSymbols; - - public VariableDeclaratorOperationVisitor(CancellationToken cancellationToken) - { - _cancellationToken = cancellationToken; - _localSymbols = new HashSet(); - } - - public ImmutableArray FindAllLocalSymbols(IOperation? operation) - { - if (operation != null) - { - Visit(operation); - } - - return _localSymbols.ToImmutableArray(); - } - - public override void Visit(IOperation operation) - { - _cancellationToken.ThrowIfCancellationRequested(); - if (operation is IVariableDeclaratorOperation variableDeclaratorOperation) - { - _localSymbols.Add(variableDeclaratorOperation.Symbol); - } - - base.Visit(operation); - } } } } diff --git a/src/Features/Core/Portable/InlineMethod/AbstractInlineMethodRefactoringProvider.cs b/src/Features/Core/Portable/InlineMethod/AbstractInlineMethodRefactoringProvider.cs index ba9b4ac601d315486d1d5129b7c5c91cfa69a709..e2bd76ec6c37cb49ef3ebaa64a501d95b37c4cf0 100644 --- a/src/Features/Core/Portable/InlineMethod/AbstractInlineMethodRefactoringProvider.cs +++ b/src/Features/Core/Portable/InlineMethod/AbstractInlineMethodRefactoringProvider.cs @@ -22,6 +22,7 @@ internal abstract partial class AbstractInlineMethodRefactoringProvider /// Check if the has only one expression or it is using arrow expression. @@ -34,9 +35,10 @@ internal abstract partial class AbstractInlineMethodRefactoringProvider s_LocalNameFilter = s => + s.Kind == SymbolKind.Local || + s.Kind == SymbolKind.Parameter || + s.Kind == SymbolKind.RangeVariable || + s.Kind == SymbolKind.Field || + s.Kind == SymbolKind.Property; + public SyntaxToken GenerateUniqueName( SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt, string baseName, CancellationToken cancellationToken) @@ -39,19 +50,16 @@ internal abstract class AbstractSemanticFactsService : ISemanticFacts SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt, string baseName, CancellationToken cancellationToken) { - // local name can be same as field or property. but that will hide - // those and can cause semantic change later in some context. - // so to be safe, we consider field and property in scope when - // creating unique name for local - Func filter = s => - s.Kind == SymbolKind.Local || - s.Kind == SymbolKind.Parameter || - s.Kind == SymbolKind.RangeVariable || - s.Kind == SymbolKind.Field || - s.Kind == SymbolKind.Property; + return GenerateUniqueName( + semanticModel, location, containerOpt, baseName, s_LocalNameFilter, usedNames: Enumerable.Empty(), cancellationToken); + } + public SyntaxToken GenerateUniqueLocalName( + SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt, + string baseName, IEnumerable usedNames, CancellationToken cancellationToken) + { return GenerateUniqueName( - semanticModel, location, containerOpt, baseName, filter, usedNames: Enumerable.Empty(), cancellationToken); + semanticModel, location, containerOpt, baseName, s_LocalNameFilter, usedNames: usedNames, cancellationToken); } public SyntaxToken GenerateUniqueName( diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/SemanticsFactsService/ISemanticFactsService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/SemanticsFactsService/ISemanticFactsService.cs index bd0fd1d353538fe172dd186a0f17c620288f6a8b..2d0fc1e61ceb4c25d7ef186045aeada65f5da07b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/SemanticsFactsService/ISemanticFactsService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/SemanticsFactsService/ISemanticFactsService.cs @@ -39,6 +39,10 @@ internal interface ISemanticFactsService : ISemanticFacts, ILanguageService SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt, string baseName, CancellationToken cancellationToken); + SyntaxToken GenerateUniqueLocalName( + SemanticModel semanticModel, SyntaxNode location, + SyntaxNode containerOpt, string baseName, IEnumerable usedNames, CancellationToken cancellationToken); + SyntaxToken GenerateUniqueName(string baseName, IEnumerable usedNames); } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicSemanticFactsService.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicSemanticFactsService.vb index 09239a4918b43be306227c4dee3d8ea7d2bb7098..8b0192b9b2a5ded5e91ebf9abb258f83de893065 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicSemanticFactsService.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicSemanticFactsService.vb @@ -118,6 +118,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return MyBase.GenerateUniqueLocalName(semanticModel, location, containerOpt, baseName, cancellationToken) End Function + Private Function ISemanticFactsService_GenerateUniqueLocalName( + semanticModel As SemanticModel, location As SyntaxNode, containerOpt As SyntaxNode, baseName As String, usedName As IEnumerable(Of String), cancellationToken As CancellationToken) As SyntaxToken Implements ISemanticFactsService.GenerateUniqueLocalName + Return MyBase.GenerateUniqueLocalName(semanticModel, location, containerOpt, baseName, usedName, cancellationToken) + End Function + Private Function ISemanticFactsService_GenerateUniqueName(semanticModel As SemanticModel, location As SyntaxNode, containerOpt As SyntaxNode, baseName As String, filter As Func(Of ISymbol, Boolean), usedNames As IEnumerable(Of String), cancellationToken As CancellationToken) As SyntaxToken Implements ISemanticFactsService.GenerateUniqueName Return MyBase.GenerateUniqueName(semanticModel, location, containerOpt, baseName, filter, usedNames, cancellationToken) End Function