Skip to content
This repository was archived by the owner on Dec 12, 2020. It is now read-only.

Conversation

amis92
Copy link
Collaborator

@amis92 amis92 commented Jun 24, 2018

It's just an initial concept draft to start up a discussion

I've got an idea for a big enhancement: a feature that would enable many more scenarios for code generation in this framework, namely:

My proposal adds a new interface that has a method with the same parameter list as current ICodeGenerator.GenerateAsync, but returns Task<RichGenerationResult> which contains four syntax lists: Members, Usings, Externs and AttributeLists that get merged with those created by previous generators and then are added to the generated compilation unit.

There are no tests currently, but I will add them, if the design would be accepted.

@amis92
Copy link
Collaborator Author

amis92 commented Jun 26, 2018

@AArnott I've rebased onto master after merging #79. What do you think of the proposed enhancements? #Closed

@amis92
Copy link
Collaborator Author

amis92 commented Jul 3, 2018

@AArnott ping? What are your thoughts? #Closed

@amis92
Copy link
Collaborator Author

amis92 commented Jul 11, 2018

@AArnott pinging again. Any reaction? #Closed

Copy link
Owner

@AArnott AArnott left a comment

Choose a reason for hiding this comment

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

Sure, your direction seems fine.

Sorry for the slow reply.
I'm about to go on vacation for 3 weeks, starting next weekend. I'll try to be responsive before and after that point, but I may not be too responsive during that timeframe.


<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
<LangVersion>7.1</LangVersion>
Copy link
Owner

@AArnott AArnott Jul 16, 2018

Choose a reason for hiding this comment

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

Let's go ahead and shoot for 7.3. 😄 #Closed

amis92 added 2 commits August 13, 2018 18:02
* Bump C# lang version in main project to 7.3
* Rename variables in DocumentTransform to start with 'emitted' as original 'emittedMembers'
* Move old behavior of wrapping ICodeGeneration results with ancestor types into EnrichingCodeGeneratorProxy
* Unify calling code generators into calling IRichCodeGenerators, wrapping normal ones in the proxy class
@amis92
Copy link
Collaborator Author

amis92 commented Aug 13, 2018

@AArnott I've added tests, done some refactors and bumped lang ver to 7.3 as requested.

I think I'm done here. What's your take on this? #Closed

@amis92
Copy link
Collaborator Author

amis92 commented Aug 16, 2018

One major refactor I should maybe explain is the move of wrapping-member-in-ancestor logic; I've moved it into a separate nested class which I've named EnrichingCodeGeneratorProxy. It essentially hides that logic behind IRichCodeGenerator interface.

So the processing is now more streamlined: non-rich generators are now wrapped into Proxy class, and only the Rich generation is called in the TransformAsync foreach loop.

One other thing I've been uncertain, is: should the TransformationContext and RichGenerationResult have public constructors? Maybe we could offer some factory methods instead. That way we could reserve space for future changes/additions without breaking existing code.

@amis92
Copy link
Collaborator Author

amis92 commented Aug 20, 2018

@AArnott pinging for review :) #Closed

@AArnott
Copy link
Owner

AArnott commented Aug 20, 2018

Sorry... looking now.. #Resolved


private class EnrichingCodeGeneratorProxy : IRichCodeGenerator
{
public EnrichingCodeGeneratorProxy(ICodeGenerator codeGenerator)
Copy link
Owner

@AArnott AArnott Aug 20, 2018

Choose a reason for hiding this comment

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

codeGenerator [](start = 62, length = 13)

Since we dereference this later without checking, please add Requires.NotNull(codeGenerator, nameof(codeGenerator)); to this ctor. #Closed

@AArnott
Copy link
Owner

AArnott commented Aug 20, 2018

I don't see how a factory method will make it more future-proof than a ctor. We would presumably add more of either one as we add members. However, the fact that you're already using default parameters on the first "overload" may make it tricky to add more overloads with default parameters later. I'll leave more comments in the relevant files.


In reply to: 413479597 [](ancestors = 413479597)

SyntaxList<UsingDirectiveSyntax> usings = default,
SyntaxList<AttributeListSyntax> attributeLists = default,
SyntaxList<ExternAliasDirectiveSyntax> externs = default)
{
Copy link
Owner

@AArnott AArnott Aug 20, 2018

Choose a reason for hiding this comment

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

Instead of these ctors, which will be troublesome to version as we add more members, why not give the properties public setters and let them set whatever ones they want? #Closed

attributeLists = AttributeLists;
externs = Externs;
}
}
Copy link
Owner

@AArnott AArnott Aug 20, 2018

Choose a reason for hiding this comment

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

I'm not a fan of deconstruction unless it's very obvious what the members will be to the caller and what order they should come in (i.e. first and last name). As the members grow, their order in this list are basically arbitrary -- they look arbitrary right now. That leads to bugs in code when you add/refactor in this class but fail to update every caller (which is hard, since they don't actually call Deconstruct explicitly) and it happens to compile because the types between two reordered members remains the same.
It also requires that the caller explicitly name the variables when it would produce smaller, more readable code if they just dereferenced the property as it is defined in this struct each time. #Closed

Copy link
Owner

@AArnott AArnott left a comment

Choose a reason for hiding this comment

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

I'm going to make the few touch-ups I asked for, out of respect for how long you've waited for my review.

Thanks a bunch for your contribution!

string projectDirectory,
IEnumerable<UsingDirectiveSyntax> compilationUnitUsings,
IEnumerable<ExternAliasDirectiveSyntax> compilationUnitExterns)
{
Copy link
Owner

@AArnott AArnott Aug 20, 2018

Choose a reason for hiding this comment

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

While this is a technically breaking change, it should only break unit tests that may have been written for generators, which isn't as severe.
We could make this internal, but that would make mocking up those unit tests even harder. So I'm good with this change. #ByDesign

@AArnott AArnott merged commit 227430f into AArnott:master Aug 20, 2018
@amis92 amis92 deleted the feature/rich-generators branch August 20, 2018 14:26
@amis92
Copy link
Collaborator Author

amis92 commented Aug 20, 2018

I'm glad I could help! All the comments were valid and I see the point. I've got a little carried away on that immutability bandwagon. :)

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

Successfully merging this pull request may close these issues.

2 participants