Skip to content

Commit 9e45ad4

Browse files
committed
Add support for detecting and tracking internal APIs
Closes dotnet#6156. I took the approach of refactoring the analyzer implementation to understand both public and internal, which are tracked in separate files (the new one is InternalAPI.(Un)Shipped.txt). I've also refactored the tests to run on both public and internal, with a few marginal baseline changes to account for some subtle differences between public and internal. Separated out into two commits to ensure that the test modification is correctly detected as a rename and modify, not a new file.
1 parent c76a28b commit 9e45ad4

33 files changed

+4444
-2276
lines changed

restore.sh

100644100755
File mode changed.
Original file line numberDiff line numberDiff line change
@@ -1 +1,17 @@
11
; Please do not edit this file manually, it should only be updated through code fix application.
2+
3+
### New Rules
4+
5+
Rule ID | Category | Severity | Notes
6+
--------|----------|----------|-------
7+
RS0051 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
8+
RS0052 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
9+
RS0053 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
10+
RS0054 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
11+
RS0055 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
12+
RS0056 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
13+
RS0057 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
14+
RS0058 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
15+
RS0059 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md)
16+
RS0060 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md)
17+
RS0061 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs

+114-83
Large diffs are not rendered by default.

src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.cs

+60-169
Large diffs are not rendered by default.

src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer_Diagnostics.cs

+278
Large diffs are not rendered by default.

src/PublicApiAnalyzers/Core/Analyzers/PublicApiAnalyzerResources.resx

+100-30
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@
121121
<value>Add public types and members to the declared API</value>
122122
</data>
123123
<data name="DeclarePublicApiMessage" xml:space="preserve">
124-
<value>Symbol '{0}' is not part of the declared API</value>
124+
<value>Symbol '{0}' is not part of the declared public API</value>
125125
</data>
126126
<data name="DeclarePublicApiDescription" xml:space="preserve">
127127
<value>All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes.</value>
@@ -135,13 +135,13 @@
135135
<data name="AnnotatePublicApiDescription" xml:space="preserve">
136136
<value>All public types and members should be declared with nullability annotations in PublicAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes.</value>
137137
</data>
138-
<data name="ShouldAnnotateApiFilesTitle" xml:space="preserve">
138+
<data name="ShouldAnnotatePublicApiFilesTitle" xml:space="preserve">
139139
<value>Enable tracking of nullability of reference types in the declared API</value>
140140
</data>
141-
<data name="ShouldAnnotateApiFilesMessage" xml:space="preserve">
141+
<data name="ShouldAnnotatePublicApiFilesMessage" xml:space="preserve">
142142
<value>PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking.</value>
143143
</data>
144-
<data name="ShouldAnnotateApiFilesDescription" xml:space="preserve">
144+
<data name="ShouldAnnotatePublicApiFilesDescription" xml:space="preserve">
145145
<value>PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line).</value>
146146
</data>
147147
<data name="ObliviousPublicApiTitle" xml:space="preserve">
@@ -153,13 +153,13 @@
153153
<data name="ObliviousPublicApiDescription" xml:space="preserve">
154154
<value>All public members should use either nullable or non-nullable reference types, but no oblivious reference types.</value>
155155
</data>
156-
<data name="RemoveDeletedApiTitle" xml:space="preserve">
156+
<data name="RemoveDeletedPublicApiTitle" xml:space="preserve">
157157
<value>Remove deleted types and members from the declared API</value>
158158
</data>
159-
<data name="RemoveDeletedApiMessage" xml:space="preserve">
159+
<data name="RemoveDeletedPublicApiMessage" xml:space="preserve">
160160
<value>Symbol '{0}' is part of the declared API, but is either not public or could not be found</value>
161161
</data>
162-
<data name="RemoveDeletedApiDescription" xml:space="preserve">
162+
<data name="RemoveDeletedPublicApiDescription" xml:space="preserve">
163163
<value>When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes.</value>
164164
<comment>{Locked="*REMOVED*"}</comment>
165165
</data>
@@ -187,7 +187,7 @@
187187
<data name="DuplicateSymbolsInPublicApiFilesMessage" xml:space="preserve">
188188
<value>The symbol '{0}' appears more than once in the public API files</value>
189189
</data>
190-
<data name="PublicImplicitConstructorErrorMessageName" xml:space="preserve">
190+
<data name="ImplicitConstructorErrorMessageName" xml:space="preserve">
191191
<value>implicit constructor for '{0}'</value>
192192
</data>
193193
<data name="AvoidMultipleOverloadsWithOptionalParametersTitle" xml:space="preserve">
@@ -197,15 +197,15 @@
197197
<value>Symbol '{0}' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See '{1}' for details.</value>
198198
</data>
199199
<data name="OverloadWithOptionalParametersShouldHaveMostParametersTitle" xml:space="preserve">
200-
<value>Public API with optional parameter(s) should have the most parameters amongst its public overloads</value>
200+
<value>API with optional parameter(s) should have the most parameters amongst its public overloads</value>
201201
</data>
202202
<data name="OverloadWithOptionalParametersShouldHaveMostParametersMessage" xml:space="preserve">
203-
<value>Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details.</value>
203+
<value>'{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details.</value>
204204
</data>
205-
<data name="PublicImplicitGetAccessor" xml:space="preserve">
205+
<data name="ImplicitGetAccessor" xml:space="preserve">
206206
<value>implicit get-accessor for '{0}'</value>
207207
</data>
208-
<data name="PublicImplicitSetAccessor" xml:space="preserve">
208+
<data name="ImplicitSetAccessor" xml:space="preserve">
209209
<value>implicit set-accessor for '{0}'</value>
210210
</data>
211211
<data name="PublicApiFilesMissingTitle" xml:space="preserve">
@@ -214,34 +214,104 @@
214214
<data name="PublicApiFilesMissingMessage" xml:space="preserve">
215215
<value>The solution must contain two files with the type "AdditionalFiles": PublicAPI.Unshipped.txt and PublicAPI.Shipped.txt. At least one of these files is missing or has the wrong type.</value>
216216
</data>
217-
<data name="AddAllItemsInDocumentToThePublicApiTitle" xml:space="preserve">
218-
<value>Add all items in document '{0}' to the public API</value>
217+
<data name="AddAllItemsInDocumentToTheApiTitle" xml:space="preserve">
218+
<value>Add all items in document '{0}' to the API</value>
219219
</data>
220-
<data name="AddAllItemsInProjectToThePublicApiTitle" xml:space="preserve">
221-
<value>Add all items in project '{0}' to the public API</value>
220+
<data name="AddAllItemsInProjectToTheApiTitle" xml:space="preserve">
221+
<value>Add all items in project '{0}' to the API</value>
222222
</data>
223-
<data name="AddAllItemsInTheSolutionToThePublicApiTitle" xml:space="preserve">
224-
<value>Add all items in the solution to the public API</value>
223+
<data name="AddAllItemsInTheSolutionToTheApiTitle" xml:space="preserve">
224+
<value>Add all items in the solution to the API</value>
225225
</data>
226-
<data name="AnnotateAllItemsInDocumentToThePublicApiTitle" xml:space="preserve">
227-
<value>Annotate all items in document '{0}' in the public API</value>
226+
<data name="AnnotateAllItemsInDocumentToTheApiTitle" xml:space="preserve">
227+
<value>Annotate all items in document '{0}' in the API</value>
228228
</data>
229-
<data name="AnnotateAllItemsInProjectToThePublicApiTitle" xml:space="preserve">
230-
<value>Annotate all items in project '{0}' in the public API</value>
229+
<data name="AnnotateAllItemsInProjectToTheApiTitle" xml:space="preserve">
230+
<value>Annotate all items in project '{0}' in the API</value>
231231
</data>
232-
<data name="AnnotateAllItemsInTheSolutionToThePublicApiTitle" xml:space="preserve">
233-
<value>Annotate all items in the solution in the public API</value>
232+
<data name="AnnotateAllItemsInTheSolutionToTheApiTitle" xml:space="preserve">
233+
<value>Annotate all items in the solution in the API</value>
234234
</data>
235-
<data name="EnableNullableInProjectToThePublicApiTitle" xml:space="preserve">
236-
<value>Enable nullability annotations in the public API for project '{0}'</value>
235+
<data name="EnableNullableInProjectToTheApiTitle" xml:space="preserve">
236+
<value>Enable nullability annotations in the API for project '{0}'</value>
237237
</data>
238-
<data name="EnableNullableInTheSolutionToThePublicApiTitle" xml:space="preserve">
239-
<value>Enable nullability annotations in the public API for the solution</value>
238+
<data name="EnableNullableInTheSolutionToTheApiTitle" xml:space="preserve">
239+
<value>Enable nullability annotations in the API for the solution</value>
240240
</data>
241241
<data name="RemovedApiIsNotActuallyRemovedMessage" xml:space="preserve">
242242
<value>Symbol '{0}' is marked as removed but it isn't deleted in source code</value>
243243
</data>
244244
<data name="RemovedApiIsNotActuallyRemovedTitle" xml:space="preserve">
245-
<value>Public API is marked as removed but it exists in source code</value>
245+
<value>API is marked as removed but it exists in source code</value>
246+
</data>
247+
<data name="DeclareInternalApiTitle" xml:space="preserve">
248+
<value>Add internal types and members to the declared API</value>
249+
</data>
250+
<data name="DeclareInternalApiMessage" xml:space="preserve">
251+
<value>Symbol '{0}' is not part of the declared API</value>
252+
</data>
253+
<data name="DeclareInternalApiDescription" xml:space="preserve">
254+
<value>All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes.</value>
255+
</data>
256+
<data name="AnnotateInternalApiTitle" xml:space="preserve">
257+
<value>Annotate nullability of internal types and members in the declared API</value>
258+
</data>
259+
<data name="AnnotateInternalApiMessage" xml:space="preserve">
260+
<value>Symbol '{0}' is missing nullability annotations in the declared API</value>
261+
</data>
262+
<data name="AnnotateInternalApiDescription" xml:space="preserve">
263+
<value>All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes.</value>
264+
</data>
265+
<data name="ShouldAnnotateInternalApiFilesTitle" xml:space="preserve">
266+
<value>Enable tracking of nullability of reference types in the declared API</value>
267+
</data>
268+
<data name="ShouldAnnotateInternalApiFilesMessage" xml:space="preserve">
269+
<value>InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking.</value>
270+
</data>
271+
<data name="ShouldAnnotateInternalApiFilesDescription" xml:space="preserve">
272+
<value>InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line).</value>
273+
</data>
274+
<data name="ObliviousInternalApiTitle" xml:space="preserve">
275+
<value>Internal members should not use oblivious types</value>
276+
</data>
277+
<data name="ObliviousInternalApiMessage" xml:space="preserve">
278+
<value>Symbol '{0}' uses some oblivious reference types</value>
279+
</data>
280+
<data name="ObliviousInternalApiDescription" xml:space="preserve">
281+
<value>All internal members should use either nullable or non-nullable reference types, but no oblivious reference types.</value>
282+
</data>
283+
<data name="RemoveDeletedInternalApiTitle" xml:space="preserve">
284+
<value>Remove deleted types and members from the declared internal API</value>
285+
</data>
286+
<data name="RemoveDeletedInternalApiMessage" xml:space="preserve">
287+
<value>Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found</value>
288+
</data>
289+
<data name="RemoveDeletedInternalApiDescription" xml:space="preserve">
290+
<value>When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes.</value>
291+
<comment>{Locked="*REMOVED*"}</comment>
292+
</data>
293+
<data name="InternalApiFilesInvalidTitle" xml:space="preserve">
294+
<value>The contents of the internal API files are invalid</value>
295+
</data>
296+
<data name="InternalApiFilesInvalidMessage" xml:space="preserve">
297+
<value>The contents of the internal API files are invalid: {0}</value>
298+
</data>
299+
<data name="InternalApiFileMissingTitle" xml:space="preserve">
300+
<value>Missing shipped or unshipped internal API file</value>
301+
</data>
302+
<data name="InternalApiFileMissingMessage" xml:space="preserve">
303+
<value>Internal API file '{0}' is missing or not marked as an additional analyzer file</value>
304+
</data>
305+
<data name="DuplicateSymbolsInInternalApiFilesTitle" xml:space="preserve">
306+
<value>Do not duplicate symbols in internal API files</value>
307+
</data>
308+
<data name="DuplicateSymbolsInInternalApiFilesMessage" xml:space="preserve">
309+
<value>The symbol '{0}' appears more than once in the internal API files</value>
310+
</data>
311+
<data name="InternalApiFilesMissingTitle" xml:space="preserve">
312+
<value>One or both of the internal API files are missing</value>
313+
</data>
314+
<data name="InternalApiFilesMissingMessage" xml:space="preserve">
315+
<value>The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type.</value>
246316
</data>
247-
</root>
317+
</root>

src/PublicApiAnalyzers/Core/Analyzers/PublicApiFile.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ namespace Microsoft.CodeAnalysis.PublicApiAnalyzers
77
{
88
public readonly struct PublicApiFile
99
{
10-
public PublicApiFile(string path)
10+
public PublicApiFile(string path, bool isPublic)
1111
{
1212
var fileName = Path.GetFileName(path);
1313

14-
IsShipping = IsFile(fileName, DeclarePublicApiAnalyzer.ShippedFileNamePrefix);
15-
var isUnshippedFile = IsFile(fileName, DeclarePublicApiAnalyzer.UnshippedFileNamePrefix);
14+
IsShipping = IsFile(fileName, isPublic ? DeclarePublicApiAnalyzer.PublicShippedFileNamePrefix : DeclarePublicApiAnalyzer.InternalShippedFileNamePrefix);
15+
var isUnshippedFile = IsFile(fileName, isPublic ? DeclarePublicApiAnalyzer.PublicUnshippedFileNamePrefix : DeclarePublicApiAnalyzer.InternalUnshippedFileNamePrefix);
1616

1717
IsApiFile = IsShipping || isUnshippedFile;
1818
}

0 commit comments

Comments
 (0)