Skip to content
This repository was archived by the owner on Apr 8, 2019. It is now read-only.

Commit dc2a045

Browse files
authored
Merge pull request #24 from sharwell/implicit-struct-ctor
Structs always have an implicit constructor
2 parents 82fc62b + d8529cb commit dc2a045

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

PublicApiAnalyzer/PublicApiAnalyzer.Test/ApiDesign/DeclarePublicAPIAnalyzerTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,50 @@ public class C
189189
await this.VerifyCSharpDiagnosticAsync(source, expected, CancellationToken.None).ConfigureAwait(false);
190190
}
191191

192+
[Fact]
193+
public async Task ShippedTextWithMissingImplicitStructConstructorAsync()
194+
{
195+
var source = @"
196+
public struct C
197+
{
198+
}
199+
";
200+
201+
this.shippedText = @"
202+
C";
203+
this.unshippedText = string.Empty;
204+
205+
// Test0.cs(2,15): warning RS0016: Symbol 'implicit constructor for C' is not part of the declared API.
206+
string arg = string.Format(RoslynDiagnosticsResources.PublicImplicitConstructorErrorMessageName, "C");
207+
var expected = this.CSharpDiagnostic(DeclarePublicAPIAnalyzer.DeclareNewApiRule).WithArguments(arg).WithLocation(2, 15);
208+
209+
await this.VerifyCSharpDiagnosticAsync(source, expected, CancellationToken.None).ConfigureAwait(false);
210+
}
211+
212+
[Fact]
213+
public async Task ShippedTextWithMissingImplicitStructConstructorWithOtherOverloadsAsync()
214+
{
215+
var source = @"
216+
public struct C
217+
{
218+
public C(int value)
219+
{
220+
}
221+
}
222+
";
223+
224+
this.shippedText = @"
225+
C
226+
C.C(int value) -> void";
227+
this.unshippedText = string.Empty;
228+
229+
// Test0.cs(2,15): warning RS0016: Symbol 'implicit constructor for C' is not part of the declared API.
230+
string arg = string.Format(RoslynDiagnosticsResources.PublicImplicitConstructorErrorMessageName, "C");
231+
var expected = this.CSharpDiagnostic(DeclarePublicAPIAnalyzer.DeclareNewApiRule).WithArguments(arg).WithLocation(2, 15);
232+
233+
await this.VerifyCSharpDiagnosticAsync(source, expected, CancellationToken.None).ConfigureAwait(false);
234+
}
235+
192236
[Fact]
193237
public async Task ShippedTextWithImplicitConstructorAndBreakingCodeChangeAsync()
194238
{

PublicApiAnalyzer/PublicApiAnalyzer/ApiDesign/DeclarePublicAPIAnalyzer.Impl.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,13 @@ private void OnSymbolActionCore(ISymbol symbol, Action<Diagnostic> reportDiagnos
188188
if (symbol.Kind == SymbolKind.NamedType)
189189
{
190190
var namedType = (INamedTypeSymbol)symbol;
191-
if (namedType.InstanceConstructors.Length == 1 &&
192-
(namedType.TypeKind == TypeKind.Class || namedType.TypeKind == TypeKind.Struct))
191+
if ((namedType.InstanceConstructors.Length == 1 && namedType.TypeKind == TypeKind.Class)
192+
|| namedType.TypeKind == TypeKind.Struct)
193193
{
194-
var instanceConstructor = namedType.InstanceConstructors[0];
195-
if (instanceConstructor.IsImplicitlyDeclared)
194+
var implicitConstructor = namedType.InstanceConstructors.SingleOrDefault(x => x.IsImplicitlyDeclared);
195+
if (implicitConstructor != null)
196196
{
197-
this.OnSymbolActionCore(instanceConstructor, reportDiagnostic, isImplicitlyDeclaredConstructor: true, explicitLocation: explicitLocation);
197+
this.OnSymbolActionCore(implicitConstructor, reportDiagnostic, isImplicitlyDeclaredConstructor: true, explicitLocation: explicitLocation);
198198
}
199199
}
200200
}

0 commit comments

Comments
 (0)