Simplify C# syntax generators.#39077
Conversation
There was a problem hiding this comment.
Prevents people from calling WriteLine("") and having that actually emit pointless whitespace.
There was a problem hiding this comment.
Since that file seems to be in a proprietary part, I couldn't check the context, but provided msg is a string, would perhaps string.IsNullOrEmpty be more prudent?
There was a problem hiding this comment.
Since that file seems to be in a proprietary part,
I'm not sure what that means @tamlin-mike
would perhaps string.IsNullOrEmpty be more prudent?
Callers aren't passing in null here :)
There was a problem hiding this comment.
I'm not sure what that means
@CyrusNajmabadi Clicking the file link resulted in "We went looking everywhere, but couldn’t find those commits". Searching for that filename in the roslyn repo didn't show anything. That suggested to me it's in a proprietary non-public part of the roslyn repository only Microsoft and its apointees have access to.
Callers aren't passing in null here :)
If that can be assured with 100% certainty, now and forever, OK.
There was a problem hiding this comment.
Maybe make it a Debug.Assert( text != null ) ?
There was a problem hiding this comment.
That suggested to me it's in a proprietary non-public part of the roslyn repository only Microsoft and its apointees have access to.
I'm not MS, or an appointee of it :-)
The file can't be found due to quirks around how GitHub works with force-pushes. If you just view the pr changes, you'll see this change
There was a problem hiding this comment.
@AdamSpeight2008 I don't really see any value there. Thanks
There was a problem hiding this comment.
Functions that already exist and already emit a { and update the indentation for what is written.
There was a problem hiding this comment.
this file doesn't use any usings.
There was a problem hiding this comment.
Many WriteLines were removed or moved to make newlines more consistent between constructs.
|
@dotnet/roslyn-compiler Please consider reviewing and merging #37758 before merging this one. |
There was a problem hiding this comment.
common cases were improved to produce less code.
There was a problem hiding this comment.
updated to use => bodies and switch expressions.
There was a problem hiding this comment.
both calls passed 'false' for the first argument. removed hte argument and simplified the impl since htis is always false.
There was a problem hiding this comment.
boilerplate code like this removed all blank lines between members. They didn't really help readability of the generated code.
There was a problem hiding this comment.
simple functional updates/withers/etc. just moved to inline their values instead of needing to explicitly make all the temporaries.
There was a problem hiding this comment.
constructs like array initializers can have commas after every item. So this just simplified things by always emitting the comma. We do the same thing for switch expressions when we use them.
There was a problem hiding this comment.
we were inconsistent between single-line if checks, or an if with an indented next statement. I tried to consistently use the same pattern everywhere.
There was a problem hiding this comment.
Shouldn't the code produce be if ({0} is null) throw ?
There was a problem hiding this comment.
There is no operator overloading with these types.
There was a problem hiding this comment.
Doesn't @jaredpar say ... is null the definitive null check?
There was a problem hiding this comment.
i don't see this discussion as being valuable for the core issues ths PR is attempting to solve. If you really want to make this change feel free to submit your own PR here.
There was a problem hiding this comment.
special cases switches where we only have a single case. In that case (no pun intended) we only use an 'if' check for consistency with the null checks.
There was a problem hiding this comment.
we're already in the Microsoft.CodeAnalysis.CSharp.Syntax namespace. So this could be abbreviated. This also makes us more consistent with the rest of the file (where we do this already).
There was a problem hiding this comment.
remove errant blank spaces at the end of lines. i.e. after {3} .
There was a problem hiding this comment.
tried to keep single-expr properties always as =>.
|
📝 Commit 31e71f68dc29bb28e3704d46b1658e95702bda42 produces bad indentation which makes the commit impossible to review |
There was a problem hiding this comment.
simplified cases where we generate a switch that only contained index switch { _ => null; } into just => null;
There was a problem hiding this comment.
simple forwarding methods (like Visits/Accepts/etc.) just moved to => methods.
There was a problem hiding this comment.
first arg an unused constant.
There was a problem hiding this comment.
could consider making this a single line. i don't care much.
|
Commit 4dff45f94b2dc8ef56207b432d1cf91ed76e1bdf changes the generated code, but doesn't change the generator, indicating one of the reviews before or after it is not consistent. |
|
Tagging @dotnet/roslyn-compiler @RikkiGibson . It's such a pain having to work with SourceWriter. This is an attempt to make things more consistent and easy. I have other things like i'd like to do in the future. For example, i think it's really unpleasant how we handle lists of things and trying to determine how to best separate lists of things with whitespace. I think we could easily make some helpers here to make that easier and remove all the constant need for code to keep track of which list item it is on and so on. But i'd like to do that later. |
|
@CyrusNajmabadi It would be a huge help if you could work to be more consistent with synchronized commits. For example, if you look at #37758, you'll find that every commit in the pull request is consistent: the changes to the source generator always exactly match the changes in the generated code. If the commit didn't produce a reviewable (concise and understandable) change to the output, I updated the generator and code so it would be before trying to send it for review. |
I use VS as my git system. I simply tell it to commit. This inconsistency it can produce (where it seems to miss files) is something i've mentioned many times in the past. I do not know what to do about it, other than just avoid using it entirely and do thins from the command line. However, i was told to stop doing that and to use the built-in functionality because running from the command line could lead to significant perf issues in VS. From what i can tell, possibly due to my underpowered system, the VS git system just misses things. Maybe it's because it's processing stuff in the background, but the UI doesn't wait until the bg work is done. I honestly have no idea waht to do about this other than comitting, then checking if the commit is correct at every step. |
|
Because of the size of this diff, i will attempt to re-apply all my changes and try to get the vs-git plugin to work properly there. it's not fun doing this as it means going and checking my disk (and github) are correct after each commit. |
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
| Write( | ||
| $"public{(isNew ? " new " : " ")}{node.Name} With{StripPost(field.Name, "Opt")}({type} {CamelCase(field.Name)})" + | ||
| " => Update("); |
There was a problem hiding this comment.
Consider putting this Write on one line.
| { | ||
| return string.Format("default({0})", GetRedPropertyType(field)); | ||
| var type = GetRedPropertyType(field); | ||
| return type == "SyntaxTokenList" ? "default(SyntaxTokenList)" : "default"; |
There was a problem hiding this comment.
I'm actually not a fan of this change. There are lots of lines there's just a bunch of typeless default literals, which is even less info than there is now.
There was a problem hiding this comment.
Hrmm... i could return it. But i didn't think there was a lot of value in those 'defaults'.
There was a problem hiding this comment.
An alternative would be using named parameters, which I would be fine with.
|
Got to f4f0bec. |
| WriteLine(" ? new SyntaxToken(this, slot, {0}, {1})", GetChildPosition(i), GetChildIndex(i)); | ||
| WriteLine(" : default;"); | ||
| CloseBlock(); | ||
| WriteLine($"return slot != null ? new SyntaxToken(this, slot, {GetChildPosition(i)}, {GetChildIndex(i)}) : default;"); CloseBlock(); |
There was a problem hiding this comment.
Possible that you took care of this in a later commit, but that CloseBlock(); needs to go on a new line.
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
|
@CyrusNajmabadi left comments I would like to see addressed unresolved. |
|
@333fred to followup in next PR:
Doe that work for you? |
333fred
left a comment
There was a problem hiding this comment.
LGTM with followup PR to address formatting nits.
|
@jcouv want to take a look? |
|
@dotnet/roslyn-compiler @sharwell can someone else take a look? Thanks! |
|
Could we get a senior review for this please @dotnet/roslyn-compiler |
|
@jcouv Could you take a look? Thanks! :) Note: i've heard that this PR isn't great for codeflow. HOwever, each commit is necessary here :-/ The PR isn't so bad on github.com, as long as you disable whitespace. Thanks! |
| if (IsOptional(field)) | ||
| { | ||
| kinds.Add(new Kind { Name = "None" }); | ||
| } |
There was a problem hiding this comment.
nit: line break?
Hum, I guess it's okay. Many other instances in this file...
There was a problem hiding this comment.
yeah. won't fix for now :)
| } | ||
| else | ||
| { | ||
| WriteLine(" get {{ return new SyntaxToken(this, ((Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.{0})this.Green).{1}, {2}, {3}); }}", node.Name, CamelCase(field.Name), GetChildPosition(i), GetChildIndex(i)); | ||
| WriteLine(" => new SyntaxToken(this, ((Syntax.InternalSyntax.{0})this.Green).{1}, {2}, {3});", node.Name, CamelCase(field.Name), GetChildPosition(i), GetChildIndex(i)); |
There was a problem hiding this comment.
nit: is this space before => intentional? (same question a few lines below)
There was a problem hiding this comment.
yes, very much so. basically, we're emitting a property and we may emit it multiline or single line. so first we emit the header as something like public SyntaxToken Whatever (with no trailing spaces). Then the following code either appends => ... to it (with a leading space to get things looking good) or it appends a full accessor body with newlines and indentation.
There was a problem hiding this comment.
Ah, got it. I thought we were using newline+indentation.
jcouv
left a comment
There was a problem hiding this comment.
LGTM Thanks (iteration 80)
I would squash this change though
|
Thanks! |
|
Thank you! |
It's probably a good idea to review this PR one commit at a time.
This PR should also be reviewed with whitespace changes OFF. Entire commits will become "only whitespace changed" doing that.
This PR simplifies the implementation of our syntax generator by using the existing (but uncommonly used) functionality to indent/dedent/block pieces of code. Instead, most of our writing code had to manually insert spaces, making it super annoying to keep track of current indent and emit the write amount of spaces.
This has been a pain every time i've edited SourceWriter so i thought i would finally clean it up. While i was in there, I also updated how we emit a few constructs to:
=>,switch expressionsconditional exprs, and the like).