提交 3640ed98 编写于 作者: M Martin Strecker

Check if IMethodSymbol might have cascading declarations.

上级 e5a00c2c
......@@ -1696,5 +1696,43 @@ public class T
</Workspace>";
await TestInRegularAndScriptAsync(code, fix);
}
[WorkItem(21446, "https://github.com/dotnet/roslyn/issues/21446")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddParameter)]
public async Task TestInvocation_Cascading_OfferFixCascadingForImplicitInterface()
{
// error CS1501: No overload for method 'M1' takes 1 arguments
var code =
@"
interface I1
{
void M1();
}
class C: I1
{
public void M1() { }
void MTest()
{
[|M1|](1);
}
}
";
var fix0 =
@"
interface I1
{
void M1(int v);
}
class C: I1
{
public void M1(int v) { }
void MTest()
{
M1(1);
}
}
";
await TestInRegularAndScriptAsync(code, fix0);
}
}
}
......@@ -152,9 +152,8 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
var methodToUpdate = argumentInsertPositionData.MethodToUpdate;
var argumentToInsert = argumentInsertPositionData.ArgumentToInsert;
var parameters = methodToUpdate.Parameters.Select(p => p.ToDisplayString(SimpleFormat));
var signature = $"{methodToUpdate.Name}({string.Join(", ", parameters)})";
var title = string.Format(FeaturesResources.Add_parameter_to_0, signature);
var title = GetCodeFixTitle(methodToUpdate, parameters);
var hasCascadingDeclarations = HasCascadingDeclarations(methodToUpdate);
context.RegisterCodeFix(
new MyCodeAction(title, c => FixAsync(context.Document, methodToUpdate, argumentToInsert, arguments, c)),
......@@ -162,6 +161,54 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
}
}
/// <summary>
/// Checks if there are indications that there might be more than one declaration that needs to be fixed.
/// The check does not look-up if there are other declarations (this is done later in the CodeAction).
/// </summary>
/// <param name="method"></param>
/// <returns></returns>
private bool HasCascadingDeclarations(IMethodSymbol method)
{
// Virtual methods of all kinds might have overrides somewhere else that need to be fixed.
if (method.IsVirtual || method.IsOverride || method.IsAbstract)
{
return true;
}
// If interfaces are involved we will fix those too
// Explicit interface implementations are easy
if (method.ExplicitInterfaceImplementations.Length > 0)
{
return true;
}
// For implicit interface implementations lets check if the characteristic of the method
// allows it to implicit implement an interface member.
if (method.DeclaredAccessibility == Accessibility.Private || method.DeclaredAccessibility == Accessibility.NotApplicable)
{
return false;
}
if (method.IsStatic)
{
return false;
}
// Now check if the method does implement an interface member
var containingType = method.ContainingType;
var allMethodsInAllInterfaces = containingType.AllInterfaces.SelectMany(i => i.GetMembers(method.Name));
var isMethodImplementingAnInterfaceMember = allMethodsInAllInterfaces.Any(
methodInInterface => containingType.FindImplementationForInterfaceMember(methodInInterface) == method);
return isMethodImplementingAnInterfaceMember;
}
private static string GetCodeFixTitle(IMethodSymbol methodToUpdate, IEnumerable<string> parameters)
{
var signature = $"{methodToUpdate.Name}({string.Join(", ", parameters)})";
var title = string.Format(FeaturesResources.Add_parameter_to_0, signature);
return title;
}
private ImmutableArray<ArgumentInsertPositionData<TArgumentSyntax>> GetArgumentInsertPositionForMethodCandidates(
TArgumentSyntax argumentOpt,
SemanticModel semanticModel,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册