-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Prepare GenAPI so it can be used for a new assembly diff generator #45389
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
Conversation
src/Compatibility/Microsoft.DotNet.ApiSymbolExtensions/Filtering/DocIdSymbolFilter.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/CSharpFileBuilder.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/CSharpFileBuilder.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/GenAPIConfiguration.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/Microsoft.DotNet.ApiSymbolExtensions/AssemblySymbolLoader.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/Microsoft.DotNet.ApiSymbolExtensions/Filtering/DocIdSymbolFilter.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/Microsoft.DotNet.ApiSymbolExtensions/Filtering/DocIdSymbolFilter.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/GenAPIConfiguration.cs
Outdated
Show resolved
Hide resolved
@@ -16,8 +16,9 @@ | |||
</ItemGroup> | |||
|
|||
<ItemGroup> | |||
<ProjectReference Include="$(RepoRoot)src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompatibility\Microsoft.DotNet.ApiCompatibility.csproj" /> | |||
<ProjectReference Include="$(RepoRoot)src\Compatibility\GenAPI\Microsoft.DotNet.GenAPI\Microsoft.DotNet.GenAPI.csproj" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
revert:
<ProjectReference Include="$(RepoRoot)src\Compatibility\GenAPI\Microsoft.DotNet.GenAPI\Microsoft.DotNet.GenAPI.csproj" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You found it! This is why I couldn't figure out where all the ApiCompat failures were coming from in the tests. It got lost in the weeds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the current source, I still see these two P2Ps which are wrong.
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/AssemblyLoaderFactory.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple small comments, would like for @ViktorHofer to weigh in on style / architecture before going deeper.
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/AssemblyLoaderFactory.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/CSharpAssemblyVisitor.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/SymbolFilterFactory.cs
Outdated
Show resolved
Hide resolved
39ce146
to
d8a3226
Compare
(IAssemblySymbolLoader loader, Dictionary<string, IAssemblySymbol> assemblySymbols) = AssemblyLoaderFactory.CreateFromFiles( | ||
assembliesPaths: Assemblies ?? throw new NullReferenceException("Assemblies cannot be null."), | ||
assemblyReferencesPaths: AssemblyReferences, | ||
RespectInternals); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the main design principles in the Compatibility tools is to keep the UI layer as thin as possible and let the business logic layer handle with the start-up and shutdown. The existing code base does this well by parsing arguments and calling into GenAPIApp
. The UI stack explicitly doesn't use lower level types like from Microsoft.CodeAnalysis
or ApiSymbolExtensions
.
...ibility/GenAPI/Microsoft.DotNet.GenAPI/SyntaxRewriter/TypeDeclarationCSharpSyntaxRewriter.cs
Outdated
Show resolved
Hide resolved
src/Compatibility/Microsoft.DotNet.ApiSymbolExtensions/AssemblySymbolLoader.cs
Outdated
Show resolved
Hide resolved
…stead of the whole config. Rename the config instance variables to something more meaningful instead of c or _c. Fix the build failure happening under #if NET.
…, split it into two separate classes.
…harpSyntaxRewriter
} | ||
|
||
/// <inheritdoc /> | ||
public SyntaxNode GetFormattedRootNodeForDocument(Document document) => document.GetSyntaxRootAsync().Result!.Rewrite(new SingleLineStatementCSharpSyntaxRewriter()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this actually use any instance state, or is it just a transformation on Document? Why does this live on the assembly visitor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed the class as suggested so the purpose of this method made more sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tossing the idea out there - now that you have both CSharpAssemblyDocumentGenerator and CSharpFileBuilder do you think it makes sense to have these two different types? Could we combine them back together and just have one that is used slightly differently depending on the caller? It might reduce the total number of names we have to come up with while still being meaningful and keeping the diff smaller.
|
||
namespace Microsoft.DotNet.GenAPI; | ||
|
||
public interface IAssemblyVisitor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you document this, and mention its purpose? Is it for testability - and if so, do you use that anywhere? For that matter I also see that IAssemblySymbolWriter
is an interface only ever used with a single type. @ViktorHofer do you think there is value in keeping these interfaces?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct me if I'm wrong, but we use interfaces in case we one day decide to provide similar support to Visual Basic code, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not certain, but if we did add VB support we could add the interface at that time? I tried to look back at the history and it was there from the start. I couldn't see anywhere we actually made use of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I 10000 also see that IAssemblySymbolWriter is an interface only ever used with a single type. @ViktorHofer do you think there is value in keeping these interfaces?
Yes, the general idea for IAssemblySymbolWriter
was to not depend on the specific implementation in the unit of code that depends on it (basically follow the Liskov Substitution Principle). Looks like GenAPIApp depends on the concrete type though so the interface doesn't serve much purpose today. There's probably room for improvement here and I would keep the interface.
…mblyVisitor class, remove its interface. Move the static methods from SymbolFilterFactory to CompositeSymbolFilter, and delete SymbolFilterFactory. Move TryGetRecordConstructor static extension method to a higher assembly. Move the NullableAttributes.cs dependency to the same higher assembly. Move ImplicitSymbolFilter to a higher assembly. Adjust the tests accordingly.
d8a3226
to
a7358fc
Compare
bool includeEffectivelyPrivateSymbols = true, | ||
bool includeExplicitInterfaceImplementationSymbols = true) | ||
{ | ||
DocIdSymbolFilter? docIdSymbolFilter = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CompositeSymbolFilter is one implementation of the ISymbolFilter interface and must not know about others, i.e. the DocIdSymbolFilter
. Even if this these methods are static, they don't belong here. That would violate the separation of concerns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll bring back the factory class. If there are methods that belong to a specific class, I'll put them there instead.
/// <param name="includeInternalSymbols">True to include internal API when reading assemblies from the <see cref="AssemblySymbolLoader"/> created.</param> | ||
public sealed class AssemblySymbolLoaderFactory(bool includeInternalSymbols = false) : IAssemblySymbolLoaderFactory | ||
public sealed class AssemblySymbolLoaderFactory(ILog logger, bool includeInternalSymbols = false) : IAssemblySymbolLoaderFactory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we name the field log
everywhere else, i.e.:
sdk/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Rules/AssemblyIdentityMustMatch.cs
Line 21 in cc260aa
private readonly ISuppressibleLog _log; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is getting quite big and complex. I think it would help if you would submit some of the non-controversial changes as one separate PR. Examples to include:
- AssemblySymbolLoader receiving the log instance
- The ctor change in DocIdSymbolFilter
- and the whitespace removals and typo fixes
I'll submit smaller PRs as this one is already full of merge conflicts. |
We intend to create a new tool to generate the monthly API diffs that will replace arcade's AsmDiff, which depends on Cci, an obsolete and unsupported library.
This PR makes the preliminary changes needed to be able to call GenAPI from yet another project besides GenAPI.Tool, GenAPI.Task and ApiCompat.
I made the following changes:
The diffing tool will mainly need the last point: being able to have the strings stored in streams to be able to do the comparisons afterwards.