Skip to content
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

fix: Correctly support incremental source generation #62

Merged
merged 18 commits into from
Oct 16, 2024

Conversation

JKamsker
Copy link
Contributor

@JKamsker JKamsker commented Oct 8, 2024

Fixes #56 by removing the requirement of the sg to use the compilation

Copy link

@viceroypenguin viceroypenguin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits, some foundational issues - a good start, though.

Generator.Equals/AttributesMetadata.cs Outdated Show resolved Hide resolved
Generator.Equals.DynamicGenerationTests/UnitTest1.cs Outdated Show resolved Hide resolved
Generator.Equals/AttributesMetadata.cs Outdated Show resolved Hide resolved
Generator.Equals/AttributesMetadata.cs Outdated Show resolved Hide resolved
Generator.Equals/EqualsGenerator.cs Show resolved Hide resolved
Generator.Equals/EqualsGenerator.cs Outdated Show resolved Hide resolved
Generator.Equals/Generator.Equals.csproj Outdated Show resolved Hide resolved
Generator.Equals/Polyfill/IsExternalInit.cs Outdated Show resolved Hide resolved
@JKamsker
Copy link
Contributor Author

JKamsker commented Oct 8, 2024

TODO: Actually do transform

@JKamsker JKamsker changed the title Refactor Generator: Remove requirement for compilation [WIP] Refactor Generator: Remove requirement for compilation Oct 8, 2024
@diegofrata
Copy link
Owner

Hi guys! I just spotted this PR. I am happy to work w/ you on getting something merged if it will solve #56. Let me know once the code is a reviewable state.

@JKamsker JKamsker force-pushed the JKamsker/real_incremental_reduced branch from fd0ee6f to 5bd93fb Compare October 9, 2024 22:37
@JKamsker JKamsker force-pushed the JKamsker/real_incremental_reduced branch from 5bd93fb to ceb45e2 Compare October 9, 2024 22:39
@JKamsker JKamsker changed the title [WIP] Refactor Generator: Remove requirement for compilation Refactor Generator: Remove requirement for compilation Oct 9, 2024
@JKamsker
Copy link
Contributor Author

JKamsker commented Oct 9, 2024

Hey @diegofrata !

Glad you like it :)

I think this PR is ready for review :)

Generator.Equals/EqualsGenerator.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/EqualityTypeModelTransformer.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/EqualityTypeModelTransformer.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/EqualityTypeModelTransformer.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/EqualityTypeModelTransformer.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/EqualityTypeModelTransformer.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/EqualityTypeModelTransformer.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/EqualityTypeModel.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/AttributesMetadata.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/AttributeMetadata.cs Show resolved Hide resolved
@JKamsker JKamsker force-pushed the JKamsker/real_incremental_reduced branch from 652ba68 to cdff4c9 Compare October 10, 2024 13:56
Copy link

@viceroypenguin viceroypenguin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a lot already, and I don't want to tear down all of it.

Would also recommend looking at the following code for getting outer classes:

https://github.com/ImmediatePlatform/Immediate.Validations/blob/d66ecfeff03ba31bfe53bd126d72fc19c46352e1/src/Immediate.Validations.Generators/ValidateTargetTransformer.cs#L89-L105

.gitignore Outdated

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a personal preference, I do two things with regards to generated code:

  • Generator tests, which use CSharpGeneratorDriver.Create(generator).RunGeneratorsAndUpdateCompilation(..); and Verify; the RunGeneratorsAndUpdateCompilation(..) call to verify that both the original and generated code compile correctly, and Verify to store the generated output and require confirmation of any changes to the generated output.
  • Functional tests, which test the behavior of the generated code.
    • In these functional tests, I do not use EmitCompilerGeneratedFiles, since any generated code I may wish to review is already available via the generated tests.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opening the code in VS fully, I see that there are now four test projects. Only two are necessary, imo, using the above process.

It appears that SnapshotTests has the first bullet point, and Tests contain the functional tests. TopLevel is probably unnecessary, and I am uncertain what DynamicGeneration is supposed to add over the existing ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea i generally think the sln would require some form of restructuring. Ideally following your format (from eg Immediate.Validators).
But i would like to move that topic to another pr, since there is already another pr. Changing the folder structure would prolly require me to do everything in that other pr again 😅

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still did not answer why you added DynamicGeneration. The existing layout was fine, though TopLevel is probably unnecessary; adding DynamicGeneration is the question under concern here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea i wanted to generate and debug the generator without having to debug visual studio itslef.
In the other pr i need it to verify that the issue has been fixed https://github.com/diegofrata/Generator.Equals/blob/25d158fe365fc8ca43e08498ae6c95cf72d94142/Generator.Equals.DynamicGenerationTests/Issues/Issue-60-StringEquality-Enumerables.cs

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You do that by using <IsRoslynComponent /> and the correct launchSettings.json. Adding a new project entirely seems unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea removed the proj for now...

Generator.Equals.Tests/Structs/CustomEquality.cs Outdated Show resolved Hide resolved
Generator.Equals.Tests/Structs/UnorderedEquality.Sample.cs Outdated Show resolved Hide resolved
Generator.Equals.DynamicGenerationTests/UnitTest1.cs Outdated Show resolved Hide resolved
Generator.Equals/SymbolHelpers.cs Outdated Show resolved Hide resolved
Generator.Equals/SymbolHelpers.cs Show resolved Hide resolved
Generator.Equals/Extensions/SymbolExtensions.cs Outdated Show resolved Hide resolved
Generator.Equals/Extensions/SymbolExtensions.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/ComparableImmutableArray.cs Outdated Show resolved Hide resolved
@JKamsker
Copy link
Contributor Author

Would also recommend looking at the following code for getting outer classes:

https://github.com/ImmediatePlatform/Immediate.Validations/blob/d66ecfeff03ba31bfe53bd126d72fc19c46352e1/src/Immediate.Validations.Generators/ValidateTargetTransformer.cs#L89-L105

I think we also need namespaces.

@JKamsker JKamsker force-pushed the JKamsker/real_incremental_reduced branch from f7b98e2 to cacd1dd Compare October 11, 2024 10:27
@JKamsker
Copy link
Contributor Author

JKamsker commented Oct 11, 2024

So to sum up, a major restructuring is necessary but it should be done in a separate pr imho.

@diegofrata Can you also have a look? :D

Copy link
Owner

@diegofrata diegofrata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay, startup life is not easy. This is a bit of a beast but it looks great! Thanks for this refactoring, it is a lot better and a lot more maintainable.

I tried to not comment on style in general, the exception being null-checks, which I agree with other commenters that it's too non-idiomatic and that's coming from someone who hates explicit modifiers but tolerates it because it's the preference of the majority. :-) Sorry!

A couple of things that still need discussion before merging are:

  • Is .NET 8 required here? If so, projects targeting .NET 6.0 need an update, as does the GitHub Action (that should be straight-forward)
  • Would be nice if package versions between the different test projects were in sync, with the addition of the DynamicGeneration test project.
  • I don't have a Windows machine at hand anymore, so can't check if .NET Framework 4.8 is still working after this PR and sadly I don't have an action for that. If you're on Windows, could you test it?

Let me know if you need any assistance w/ any of these things! Once again, thanks for taking the time to work on this project.

Generator.Equals/Models/AttributeMetadataExtensions.cs Outdated Show resolved Hide resolved
Generator.Equals/Models/AttributeMetadataExtensions.cs Outdated Show resolved Hide resolved
Generator.Equals/Extensions/AttributeDataExtensions.cs Outdated Show resolved Hide resolved
Generator.Equals/Generators/RecordEqualityGenerator.cs Outdated Show resolved Hide resolved
Generator.Equals.DynamicGenerationTests/Base_Assertions.cs Outdated Show resolved Hide resolved
if (equatableAttributeData is null || !attributesMetadata.Equatable.Equals(equatableAttributeData.AttributeClass))
{
// TODO: Report diagnostic
// throw new Exception("Expected exactly one EquatableAttribute.");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be cool to see diagnostic report in these places rather than silently failing. Do you think you can get that in?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't have the resources to research it but it seems like its alot of additional work since the reporting would be happening somewhere completely different

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will reiterate that generators cannot safely report diagnostics and still be incremental. Diagnostics should be reported by a matching analyzer.

However, I agree that silently failing is not intuitive for the user. Silently fail here and write an analyzer to report the failure.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@viceroypenguin do you have any pointers to read on this? I have been a bit out of the loop with generators since I first wrote this. Information was always a bit spread out on this topic.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha. The cookbook didn't leave me any wiser. I will just consider myself happy with being told "not to do it inside an incremental generator" for now and do a bit of reading later.

For reference, I have not implemented analyzers before (obviously), and this link was helpful to me:
https://www.thinktecture.com/en/net/roslyn-source-generators-analyzers-code-fixes/

@JKamsker I think we might want to add some analyzers at some point but I don't see it as a blocker for this PR given the package already does not have one.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want an example of working set of Generator/Analyzer/CodeFix, please feel free to check out my source-generator packages:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have created an issue for this #65

Generator.Equals/Models/EqualityTypeModelTransformer.cs Outdated Show resolved Hide resolved
@diegofrata
Copy link
Owner

@JKamsker re-request a review from me once you're done and then we can try and get it merged.

@JKamsker
Copy link
Contributor Author

To avoid making this pr even bigger, i have created 2 new issues:

@JKamsker
Copy link
Contributor Author

  • Removed test project
  • Upgraded to net 8.0

@diegofrata diegofrata changed the title Refactor Generator: Remove requirement for compilation fix: Correctly support incremental source generation Oct 16, 2024
@diegofrata diegofrata merged commit f945469 into diegofrata:main Oct 16, 2024
1 check passed
@diegofrata
Copy link
Owner

Incredible work! Thanks a lot @JKamsker. I will try to get some automatic test running for NET 4.8 later today to ensure it is supported going forward.

@diegofrata
Copy link
Owner

And also thanks to @viceroypenguin @333fred for insightful comments.

@diegofrata
Copy link
Owner

@JKamsker pre-release 3.2.0-alpha1 is out. I will ask some colleagues to test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Probably, the generator is not incremental
4 participants