Skip to content

Commit d58dede

Browse files
committed
Improve implementation
1 parent ef223ab commit d58dede

2 files changed

Lines changed: 48 additions & 5 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1648UnitTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public async Task TestConstructorInheritsFromParentAsync()
2323
{
2424
var testCode = @"class Base
2525
{
26+
/// <summary>Base constructor.</summary>
2627
public Base() { }
2728
}
2829
@@ -33,6 +34,22 @@ public Test() { }
3334
}";
3435

3536
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
37+
38+
testCode = @"class Base
39+
{
40+
/// <summary>Base constructor.</summary>
41+
public Base(string s, int a) { }
42+
}
43+
44+
class Test : Base
45+
{
46+
/// <inheritdoc />
47+
public Test(string s, int b)
48+
: base(s, b) { }
49+
}
50+
";
51+
52+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
3653
}
3754

3855
[Fact]

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1648InheritDocMustBeUsedWithInheritingClass.cs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ private static void HandleMemberDeclaration(SyntaxNodeAnalysisContext context)
161161

162162
if (memberSyntax is ConstructorDeclarationSyntax constructorDeclarationSyntax)
163163
{
164-
// ConstructorInitializerSyntax initializer = constructorDeclarationSyntax.Initializer;
165164
ISymbol symbol = context.SemanticModel.GetDeclaredSymbol(constructorDeclarationSyntax, context.CancellationToken);
166165

167166
if (symbol is IMethodSymbol constructorMethodSymbol && constructorMethodSymbol.ContainingType is INamedTypeSymbol enclosingNamedTypeSymbol)
@@ -170,14 +169,41 @@ private static void HandleMemberDeclaration(SyntaxNodeAnalysisContext context)
170169

171170
if (baseType.SpecialType != SpecialType.System_Object)
172171
{
172+
bool foundMatchingConstructorsToInheritFrom = false;
173+
173174
foreach (IMethodSymbol baseConstructorMethod in baseType.Constructors)
174175
{
175-
// TODO: SymbolEqualityComparer?
176-
if (constructorMethodSymbol.Parameters.SequenceEqual(baseConstructorMethod.Parameters))
176+
// Constructors must have the same number of parameters.
177+
if (constructorMethodSymbol.Parameters.Count() != baseConstructorMethod.Parameters.Count())
178+
{
179+
continue;
180+
}
181+
182+
// Our constructor and the base constructor must have the same signature. But variable names can be different.
183+
bool success = true;
184+
185+
for (int i = 0; i < constructorMethodSymbol.Parameters.Length; i++)
177186
{
178-
// Matching constructor was found.
179-
return;
187+
IParameterSymbol constructorParameter = constructorMethodSymbol.Parameters[i];
188+
IParameterSymbol baseParameter = baseConstructorMethod.Parameters[i];
189+
190+
if (!constructorParameter.Type.Equals(baseParameter.Type))
191+
{
192+
success = false;
193+
break;
194+
}
180195
}
196+
197+
if (success)
198+
{
199+
foundMatchingConstructorsToInheritFrom = true;
200+
break;
201+
}
202+
}
203+
204+
if (foundMatchingConstructorsToInheritFrom)
205+
{
206+
return;
181207
}
182208
}
183209
}

0 commit comments

Comments
 (0)