-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add initial version of ApiCompatibility #16817
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
86b7b93
Add initial version of ApiCompatibility
safern c54dac8
Add headers and cleanup usings
safern 244e603
Fix tests on non-Windows
safern 59bdddd
Add docs, small fixes and cleanup
safern a70fd12
More PR Feedback
safern 516c653
Merge remote-tracking branch 'dotnet/main' into InitialApiCompat
safern c88e924
PR Feedback
safern File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,7 +19,8 @@ obj/ | |
|
|
||
| *.binlog | ||
|
|
||
| sdk.sln.DotSettings.user | ||
| # User specific files | ||
| *.user | ||
|
|
||
| # Debian and python stuff | ||
| *.dsc | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
src/Compatibility/Microsoft.DotNet.ApiCompatibility/Abstractions/CompatDifference.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| // Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| using Microsoft.CodeAnalysis; | ||
| using System; | ||
|
|
||
| namespace Microsoft.DotNet.ApiCompatibility.Abstractions | ||
| { | ||
| /// <summary> | ||
| /// Class representing a difference of compatibility, containing detailed information about it. | ||
| /// </summary> | ||
| public class CompatDifference : IDiagnostic, IEquatable<CompatDifference> | ||
| { | ||
| /// <summary> | ||
| /// The Diagnostic ID for this difference. | ||
| /// </summary> | ||
| public string DiagnosticId { get; } | ||
|
|
||
| /// <summary> | ||
| /// The <see cref="DifferenceType"/>. | ||
| /// </summary> | ||
| public DifferenceType Type { get; } | ||
|
|
||
| /// <summary> | ||
| /// A diagnostic message for the difference. | ||
| /// </summary> | ||
| public virtual string Message { get; } | ||
|
|
||
| /// <summary> | ||
| /// A unique ID in order to identify the API that the difference was raised for. | ||
| /// </summary> | ||
| public string ReferenceId { get; } | ||
|
|
||
| private CompatDifference() { } | ||
|
|
||
| /// <summary> | ||
| /// Instantiate a new object representing the compatibility difference. | ||
| /// </summary> | ||
| /// <param name="id"><see cref="string"/> representing the diagnostic ID.</param> | ||
| /// <param name="message"><see cref="string"/> message describing the difference.</param> | ||
| /// <param name="type"><see cref="DifferenceType"/> to describe the type of the difference.</param> | ||
| /// <param name="member"><see cref="ISymbol"/> for which the difference is associated to.</param> | ||
| public CompatDifference(string diagnosticId, string message, DifferenceType type, ISymbol member) | ||
| : this(diagnosticId, message, type, member?.GetDocumentationCommentId()) | ||
| { | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Instantiate a new object representing the compatibility difference. | ||
| /// </summary> | ||
| /// <param name="id"><see cref="string"/> representing the diagnostic ID.</param> | ||
| /// <param name="message"><see cref="string"/> message describing the difference.</param> | ||
| /// <param name="type"><see cref="DifferenceType"/> to describe the type of the difference.</param> | ||
| /// <param name="memberId"><see cref="string"/> containing the member ID for which the difference is associated to.</param> | ||
| public CompatDifference(string diagnosticId, string message, DifferenceType type, string memberId) | ||
| { | ||
| DiagnosticId = diagnosticId ?? throw new ArgumentNullException(nameof(diagnosticId)); | ||
| Message = message ?? throw new ArgumentNullException(nameof(message)); | ||
| Type = type; | ||
| ReferenceId = memberId ?? throw new ArgumentNullException(nameof(memberId)); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Evaluates whether the current object is equal to another <see cref="CompatDifference"/>. | ||
| /// </summary> | ||
| /// <param name="other"><see cref="CompatDifference"/> to compare against.</param> | ||
| /// <returns>True if equals, False if different.</returns> | ||
| public bool Equals(CompatDifference other) => | ||
| other != null && | ||
| Type == other.Type && | ||
| DiagnosticId.Equals(other.DiagnosticId, StringComparison.OrdinalIgnoreCase) && | ||
| ReferenceId.Equals(other.ReferenceId, StringComparison.OrdinalIgnoreCase) && | ||
| Message.Equals(other.Message, StringComparison.OrdinalIgnoreCase); | ||
|
|
||
| /// <summary> | ||
| /// Gets the hashcode that reperesents this instance. | ||
| /// </summary> | ||
| /// <returns>Unique <see cref="int"/> based on the properties' values of the instance.</returns> | ||
| public override int GetHashCode() => | ||
| HashCode.Combine(ReferenceId, DiagnosticId, Message, Type); | ||
|
|
||
| /// <summary> | ||
| /// Gets a <see cref="string"/> representation of the difference. | ||
| /// </summary> | ||
| /// <returns><see cref="string"/> describing the difference.</returns> | ||
| public override string ToString() => $"{DiagnosticId} : {Message}"; | ||
| } | ||
| } | ||
15 changes: 15 additions & 0 deletions
15
src/Compatibility/Microsoft.DotNet.ApiCompatibility/Abstractions/DifferenceType.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| namespace Microsoft.DotNet.ApiCompatibility.Abstractions | ||
| { | ||
| /// <summary> | ||
| /// Enum representing the different type of differences available. | ||
| /// </summary> | ||
| public enum DifferenceType | ||
| { | ||
| Changed, | ||
| Added, | ||
| Removed | ||
| } | ||
| } |
20 changes: 20 additions & 0 deletions
20
src/Compatibility/Microsoft.DotNet.ApiCompatibility/Abstractions/Filtering/ISymbolFilter.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| using Microsoft.CodeAnalysis; | ||
|
|
||
| namespace Microsoft.DotNet.ApiCompatibility.Abstractions | ||
| { | ||
| /// <summary> | ||
| /// Provides a mechanism to filter <see cref="ISymbol"/> when building the <see cref="ElementMapper{T}"/>. | ||
| /// </summary> | ||
| public interface ISymbolFilter | ||
| { | ||
| /// <summary> | ||
| /// Determines whether the <see cref="ISymbol"/> should be included. | ||
| /// </summary> | ||
| /// <param name="symbol"><see cref="ISymbol"/> to evaluate.</param> | ||
| /// <returns>True to include the <paramref name="symbol"/> or false to filter it out.</returns> | ||
| bool Include(ISymbol symbol); | ||
| } | ||
| } |
23 changes: 23 additions & 0 deletions
23
...icrosoft.DotNet.ApiCompatibility/Abstractions/Filtering/SymbolAccessibilityBasedFilter.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| using Microsoft.CodeAnalysis; | ||
|
|
||
| namespace Microsoft.DotNet.ApiCompatibility.Abstractions | ||
| { | ||
| internal class SymbolAccessibilityBasedFilter : ISymbolFilter | ||
| { | ||
| private readonly bool _includeInternalSymbols; | ||
|
|
||
| internal SymbolAccessibilityBasedFilter(bool includeInternalSymbols) | ||
| { | ||
| _includeInternalSymbols = includeInternalSymbols; | ||
| } | ||
|
|
||
| public bool Include(ISymbol symbol) => | ||
| symbol.DeclaredAccessibility == Accessibility.Public || | ||
| symbol.DeclaredAccessibility == Accessibility.Protected || | ||
| symbol.DeclaredAccessibility == Accessibility.ProtectedOrInternal || | ||
| (_includeInternalSymbols && symbol.DeclaredAccessibility != Accessibility.Private); | ||
| } | ||
| } |
21 changes: 21 additions & 0 deletions
21
src/Compatibility/Microsoft.DotNet.ApiCompatibility/Abstractions/IDiagnostic.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| namespace Microsoft.DotNet.ApiCompatibility.Abstractions | ||
| { | ||
| /// <summary> | ||
| /// Interface that describes a diagnostic. | ||
| /// </summary> | ||
| public interface IDiagnostic | ||
| { | ||
| /// <summary> | ||
| /// String representing the diagnostic ID. | ||
| /// </summary> | ||
| string DiagnosticId { get; } | ||
|
|
||
| /// <summary> | ||
| /// String representing the ID for the object that the diagnostic was created for. | ||
| /// </summary> | ||
| string ReferenceId { get; } | ||
| } | ||
| } |
21 changes: 21 additions & 0 deletions
21
src/Compatibility/Microsoft.DotNet.ApiCompatibility/Abstractions/IRuleRunner.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information.s | ||
|
|
||
| using System.Collections.Generic; | ||
|
|
||
| namespace Microsoft.DotNet.ApiCompatibility.Abstractions | ||
| { | ||
| /// <summary> | ||
| /// Interface for rule drivers to implement in order to be used returned by the <see cref="IRuleRunnerFactory"/> | ||
| /// </summary> | ||
| public interface IRuleRunner | ||
| { | ||
| /// <summary> | ||
| /// Runs the registered rules on the mapper. | ||
| /// </summary> | ||
| /// <typeparam name="T">The underlying type on the mapper.</typeparam> | ||
| /// <param name="mapper">The mapper to run the rules on.</param> | ||
| /// <returns></returns> | ||
| IEnumerable<CompatDifference> Run<T>(ElementMapper<T> mapper); | ||
| } | ||
| } |
13 changes: 13 additions & 0 deletions
13
src/Compatibility/Microsoft.DotNet.ApiCompatibility/Abstractions/IRuleRunnerFactory.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information.s | ||
|
|
||
| namespace Microsoft.DotNet.ApiCompatibility.Abstractions | ||
| { | ||
| /// <summary> | ||
| /// The factory to create the driver that the differ should use based on the <see cref="ComparingSettings"/>. | ||
| /// </summary> | ||
| public interface IRuleRunnerFactory | ||
| { | ||
| IRuleRunner GetRuleRunner(); | ||
| } | ||
| } |
121 changes: 121 additions & 0 deletions
121
src/Compatibility/Microsoft.DotNet.ApiCompatibility/Abstractions/MapperVisitor.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| // Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| using System; | ||
|
|
||
| namespace Microsoft.DotNet.ApiCompatibility.Abstractions | ||
| { | ||
| /// <summary> | ||
| /// Class that implements a visitor pattern to visit the tree for a given mapper. | ||
| /// </summary> | ||
| public class MapperVisitor | ||
| { | ||
| /// <summary> | ||
| /// Visits the tree for the given <see cref="ElementMapper{T}"/>. | ||
| /// </summary> | ||
| /// <typeparam name="T">Underlying type for the objects that the mapper holds.</typeparam> | ||
| /// <param name="mapper"><see cref="ElementMapper{T}"/> to visit.</param> | ||
| public void Visit<T>(ElementMapper<T> mapper) | ||
| { | ||
| if (mapper is AssemblySetMapper assemblySetMapper) | ||
| { | ||
| Visit(assemblySetMapper); | ||
| } | ||
| else if (mapper is AssemblyMapper assemblyMapper) | ||
| { | ||
| Visit(assemblyMapper); | ||
| } | ||
| else if (mapper is NamespaceMapper nsMapper) | ||
| { | ||
| Visit(nsMapper); | ||
| } | ||
| else if (mapper is TypeMapper typeMapper) | ||
| { | ||
| Visit(typeMapper); | ||
| } | ||
| else if (mapper is MemberMapper memberMapper) | ||
| { | ||
| Visit(memberMapper); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Visits the <see cref="AssemblySetMapper"/> and visits each <see cref="AssemblyMapper"/> in the mapper. | ||
| /// </summary> | ||
| /// <param name="mapper">The <see cref="AssemblySetMapper"/> to visit.</param> | ||
| public virtual void Visit(AssemblySetMapper mapper) | ||
| { | ||
| if (mapper == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(mapper)); | ||
| } | ||
|
|
||
| foreach (AssemblyMapper assembly in mapper.GetAssemblies()) | ||
safern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| Visit(assembly); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Visits the <see cref="AssemblyMapper"/> and visits each <see cref="NamespaceMapper"/> in the mapper. | ||
| /// </summary> | ||
| /// <param name="mapper">The <see cref="AssemblyMapper"/> to visit.</param> | ||
| public virtual void Visit(AssemblyMapper mapper) | ||
| { | ||
| if (mapper == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(mapper)); | ||
| } | ||
|
|
||
| foreach (NamespaceMapper nsMapper in mapper.GetNamespaces()) | ||
| { | ||
| Visit(nsMapper); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Visits the <see cref="NamespaceMapper"/> and visits each <see cref="TypeMapper"/> in the mapper. | ||
| /// </summary> | ||
| /// <param name="mapper">The <see cref="NamespaceMapper"/> to visit.</param> | ||
| public virtual void Visit(NamespaceMapper mapper) | ||
| { | ||
| if (mapper == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(mapper)); | ||
| } | ||
|
|
||
| foreach (TypeMapper type in mapper.GetTypes()) | ||
| { | ||
| Visit(type); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Visits the <see cref="TypeMapper"/> and visits the nested types and members in the mapper. | ||
| /// </summary> | ||
| /// <param name="mapper">The <see cref="TypeMapper"/> to visit.</param> | ||
| public virtual void Visit(TypeMapper mapper) | ||
| { | ||
| if (mapper == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(mapper)); | ||
| } | ||
|
|
||
| foreach (TypeMapper type in mapper.GetNestedTypes()) | ||
| { | ||
| Visit(type); | ||
| } | ||
|
|
||
| foreach (MemberMapper member in mapper.GetMembers()) | ||
| { | ||
| Visit(member); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Visits the <see cref="MemberMapper"/>. | ||
| /// </summary> | ||
| /// <param name="mapper">The <see cref="MemberMapper"/> to visit.</param> | ||
| public virtual void Visit(MemberMapper mapper) { } | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.