diff --git a/PublicApiAnalyzer/PublicApiAnalyzer/ApiDesign/DeclarePublicAPIAnalyzer.Impl.cs b/PublicApiAnalyzer/PublicApiAnalyzer/ApiDesign/DeclarePublicAPIAnalyzer.Impl.cs
index 6de1cdd..f8866c6 100644
--- a/PublicApiAnalyzer/PublicApiAnalyzer/ApiDesign/DeclarePublicAPIAnalyzer.Impl.cs
+++ b/PublicApiAnalyzer/PublicApiAnalyzer/ApiDesign/DeclarePublicAPIAnalyzer.Impl.cs
@@ -102,6 +102,25 @@ internal void OnSymbolAction(SymbolAnalysisContext symbolContext)
this.OnSymbolActionCore(symbolContext.Symbol, symbolContext.ReportDiagnostic);
}
+ internal void OnPropertyAction(SymbolAnalysisContext symbolContext)
+ {
+ // If a property is non-implicit, but it's accessors *are* implicit,
+ // then we will not get called back for the accessor methods. Add
+ // those methods explicitly in this case. This happens, for example,
+ // in VB with properties like:
+ //
+ // public readonly property A as Integer
+ //
+ // In this case, the getter/setters are both implicit, and will not
+ // trigger the callback to analyze them. So we manually do it ourselves.
+ var property = (IPropertySymbol)symbolContext.Symbol;
+ if (!property.IsImplicitlyDeclared)
+ {
+ this.CheckPropertyAccessor(symbolContext, property.GetMethod);
+ this.CheckPropertyAccessor(symbolContext, property.SetMethod);
+ }
+ }
+
internal void OnCompilationEnd(CompilationAnalysisContext context)
{
this.ProcessTypeForwardedAttributes(context.Compilation, context.ReportDiagnostic, context.CancellationToken);
@@ -169,6 +188,28 @@ private static bool ContainsPublicApiName(string apiLineText, string publicApiNa
return index == 0 || (index > 0 && apiLineText[index - 1] == ' ');
}
+ private void CheckPropertyAccessor(SymbolAnalysisContext symbolContext, IMethodSymbol accessor)
+ {
+ if (accessor == null)
+ {
+ return;
+ }
+
+ // Only process implicit accessors. We won't get callbacks for them
+ // normally with RegisterSymbolAction.
+ if (!accessor.IsImplicitlyDeclared)
+ {
+ return;
+ }
+
+ if (!this.IsPublicAPI(accessor))
+ {
+ return;
+ }
+
+ this.OnSymbolActionCore(accessor, symbolContext.ReportDiagnostic, isImplicitlyDeclaredConstructor: false);
+ }
+
/// Analyzes a symbol.
/// The symbol to analyze. Will also analyze implicit constructors too.
/// Action called to actually report a diagnostic.
diff --git a/PublicApiAnalyzer/PublicApiAnalyzer/ApiDesign/DeclarePublicAPIAnalyzer.cs b/PublicApiAnalyzer/PublicApiAnalyzer/ApiDesign/DeclarePublicAPIAnalyzer.cs
index 7320969..b72ae2c 100644
--- a/PublicApiAnalyzer/PublicApiAnalyzer/ApiDesign/DeclarePublicAPIAnalyzer.cs
+++ b/PublicApiAnalyzer/PublicApiAnalyzer/ApiDesign/DeclarePublicAPIAnalyzer.cs
@@ -259,6 +259,9 @@ private void OnCompilationStart(CompilationStartAnalysisContext compilationConte
SymbolKind.Event,
SymbolKind.Field,
SymbolKind.Method);
+ compilationContext.RegisterSymbolAction(
+ impl.OnPropertyAction,
+ SymbolKind.Property);
compilationContext.RegisterCompilationEndAction(impl.OnCompilationEnd);
}