-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Share common code involved into building dictionaries of members for namespace symbols #67933
Conversation
…bleArrayExtensions.AddToMultiValueDictionaryBuilder helper.
…ayExtensions and use from both compilers
@CyrusNajmabadi FYI |
@dotnet/roslyn-compiler Please review |
if (existingValueOrArray is ArrayBuilder<T> arrayBuilder) | ||
{ | ||
// Already a builder in the accumulator, just add to that. | ||
} | ||
else | ||
{ | ||
// Just a single value in the accumulator so far. Convert to using a builder. | ||
arrayBuilder = ArrayBuilder<T>.GetInstance(capacity: 2); |
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.
if (existingValueOrArray is ArrayBuilder<T> arrayBuilder) | |
{ | |
// Already a builder in the accumulator, just add to that. | |
} | |
else | |
{ | |
// Just a single value in the accumulator so far. Convert to using a builder. | |
arrayBuilder = ArrayBuilder<T>.GetInstance(capacity: 2); | |
if (existingValueOrArray is not ArrayBuilder<T> arrayBuilder) | |
{ | |
// Just a single value in the accumulator so far. Convert to using a builder. | |
arrayBuilder = ArrayBuilder<T>.GetInstance(capacity: 2); | |
``` #WontFix |
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 am not interested in changing style or or inverting if conditions. Do not see any value in that.
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 value is not needing a superfluous empty does-nothing body. That makes reviewing more difficult as there are more codepaths to reason about.
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.
That makes reviewing more difficult as there are more codepaths to reason about.
I disagree with that. In my opinion restructuring this code will make it harder to review this particular PR, in my opinion. And my goal is to make it as easy to review as possible.
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.
it was harder for me to reason about. i had to actually convince myself of what was going on because of the lack of use of better and clearer patterns. It's fine if that's not a concern of yours, but it's def a concern of mine (especially as someone who has had to work with this code a lot recently.
where TNamedTypeSymbol : class, TNamespaceOrTypeSymbol | ||
where TNamespaceSymbol : class, TNamespaceOrTypeSymbol |
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.
where TNamedTypeSymbol : class, TNamespaceOrTypeSymbol | |
where TNamespaceSymbol : class, TNamespaceOrTypeSymbol | |
where TNamedTypeSymbol : class, TNamespaceOrTypeSymbol | |
where TNamespaceSymbol : class, TNamespaceOrTypeSymbol |
are the class constraints necessary here if this depend on a type parameter already with that constraint? #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.
are the class constraints necessary here if this depend on a type parameter already with that constraint?
Yes, interfaces satisfy class
constraint. An interface as a constraint doesn't mean class
.
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.
my question is if restating the class constraint is necessary, or if that is picked up by the transitive type parameter constraint here.
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.
my question is if restating the class constraint is necessary, or if that is picked up by the transitive type parameter constraint here.
And I answered this question, I think. With an explanation why a class
constraint is not transitive.
var builder = value as ArrayBuilder<TNamespaceOrTypeSymbol>; | ||
if (builder != null) |
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.
var builder = value as ArrayBuilder<TNamespaceOrTypeSymbol>; | |
if (builder != null) | |
if (value in ArrayBuilder<TNamespaceOrTypeSymbol> builder) | |
``` #WontFix |
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 am not interested in changing style. Also, style changes are not welcome.
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.
it's not a style change. it's reduction in concept count. THere's no need for as + null + variable. A single concept does all of that in a clearer and less error prone fashion.
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.
It is a style change in my opinion. I see no value in the suggested change. If it is not broken, don't fix it.
hasNamespaces = true; | ||
break; | ||
} | ||
} |
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.
could just be var hasNamespaces = builder.Any(static n => n is TNamespaceSymbol);
#WontFix
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 am not interested in rewriting code that works.
? builder.ToImmutable() | ||
: ImmutableArray<TNamespaceOrTypeSymbol>.CastUp(builder.ToDowncastedImmutable<TNamedTypeSymbol>()); | ||
|
||
builder.Free(); |
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.
calling ToImmutable
followed by Free
dosen't allow for the optimization of moving the internal array to the immutable array without a copy that ToImmutableAndFree allows for. #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.
calling ToImmutable followed by Free dosen't allow for the optimization of moving the internal array to the immutable array without a copy that ToImmutableAndFree allows for.
This is an "extract common code" refactoring, I am not interested in changing what the code is doing and how it does that.
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 pointing out that the code you're extracting out has issues with it. Since you are working with the code now, it's a good time to actually address the problems in it. Otherwise, it's just kicking hte can down the road, and will require more effort and more reviews to take care of these things. best to just do it when our eyes are on this problem already. I trust that it's very simple to change this and get the code to remove problematic parts, and we can review in equally low amounts of time. Putting it in a separate commit is fine as well as it will make it easy to review.
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 pointing out that the code you're extracting out has issues with it.
This is definitely something to consider as a future improvement, I will open a follow-up issue.
Since you are working with the code now, it's a good time to actually address the problems in it.
I do not agree with that. I prefer to separate the 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 will open a follow-up issue.
} | ||
else | ||
{ | ||
dictionary.Add(kvp.Key, members.As<TNamedTypeSymbol>()); |
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 can skip the above loop and all the logic simply by doing an initial O(1) members.As<TNamedTypeSymbol>()
. If that succeeds, you know it is all named types and can use it. If it fails (i.e. you get a .IsDefault array bac), it means the client constructing map
saw a non-type in it. This avoid this code having to go redo the scan that was already done when map was built. #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.
you can skip the above loop and all the logic simply by doing an initial O(1) members.As().
This is definitely something to consider as a future improvement, I will open a follow-up issue. This PR is an "extract common code" refactoring, I am not interested in changing what the code is doing and how it does that.
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 will open a follow-up issue
@dotnet/roslyn-compiler Please review |
{ | ||
Debug.Assert(builder.Count > 1); | ||
bool hasNamespaces = false; | ||
for (int i = 0; (i < builder.Count) && !hasNamespaces; i++) |
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.
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.
Is this check needed?
This function is an existing code moved from C# compiler. It is not my goal to change what it is doing
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.
It looks like the body of the for
loop changed from NameToSymbolMapBuilder.CreateMap()
so the check here is no longer needed.
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.
It looks like the body of the for loop changed from
NameToSymbolMapBuilder.CreateMap()
so the check here is no longer needed.
That is fair
@dotnet/roslyn-compiler For the second review |
This a multi-step refactoring, might be easier to review commit by commit. Each commit has a title describing the purpose of each step.