-
Notifications
You must be signed in to change notification settings - Fork 22
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
immutability fixes #958
immutability fixes #958
Conversation
* require application of all [ConditionallyImmutable.OnlyIf] type paramters * a [ConditionallyImmutable] type should not be able to extend/implement an [Immutable] one Fixes: #956
for( int i = 0; i < baseTypeInfo.Type.TypeArguments.Length && !parameterUsed; i++ ) { | ||
ITypeSymbol typeArgument = baseTypeInfo.Type.TypeArguments[ i ]; | ||
if( !SymbolEqualityComparer.Default.Equals( typeParameter, typeArgument ) ) { | ||
continue; |
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.
So this would emit a diagnostic for IMyReadOnlyDictionary
right?
[ConditionallyImmutable]
class MyKeyValuePair<
[ConditionallyImmutable.OnlyIf]TKey,
[ConditionallyImmutable.OnlyIf]TValue
> {}
[ConditionallyImmutable]
interface IMyReadOnlyCollection<
[ConditionallyImmutable.OnlyIf]T
> {}
[ConditionallyImmutable]
interface IMyReadOnlyDictionary<
[ConditionallyImmutable.OnlyIf]TKey,
[ConditionallyImmutable.OnlyIf]TValue
> : IMyReadOnlyCollection<KeyValuePair<TKey, TValue>> {}
because TKey
"isn't used" in the type arguments to IMyReadOnlyCollection
, right?
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.
Yeah, it would
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 thinking a recursive search?
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.
Ok -- you agree that the above is safe/we would like it to be accepted in an ideal world, right?
Not saying its a problem with this PR, just wrapping my head around the issue
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.
Ok -- you agree that the above is safe/we would like it to be accepted right?
Yep
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 thinking a recursive search?
Something like that but I think it's a maybe a little fancy.
I think what we want to know is, are we (IMyReadOnlyDictionary
) "at least" as immutable as all of the interfaces (base class) we implement (derive from)? "At least" meaning that any time the broader type gets judged as immutable we also do...
I think the reason its safe here is IMyReadOnlyCollection<T>
is only immutable when T is, ok so recursively we need to care about when KeyValuePair<TKey, TValue> is... again recursively we look at that and see we have conditionals on TKey and TValue....
If we accumulate all those conditionals then I think we want to say OK, are the set of conditionals from my equal to (or a superset of?) the conditionals from my type parameters?
I'm not quite sure though, still thinking about it.
for( int i = 0; i < baseTypeInfo.Type.TypeArguments.Length && !parameterUsed; i++ ) { | ||
ITypeSymbol typeArgument = baseTypeInfo.Type.TypeArguments[ i ]; | ||
if( !SymbolEqualityComparer.Default.Equals( typeParameter, typeArgument ) ) { | ||
continue; | ||
} | ||
|
||
ITypeParameterSymbol baseTypeParameter = baseTypeInfo.Type.TypeParameters[ i ]; | ||
if( baseTypeInfo.ConditionalTypeParameters.Contains( baseTypeParameter, SymbolEqualityComparer.Default ) ) { | ||
parameterUsed = 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.
We talked on Zoom about how this chunk could be a helper and that helper would change if we implemented the more powerful logic here (recursive/whatever)
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.
We talked on zoom about reorganizing this a bit (to cut down on state/nesting) but didn't get anywhere fantastic
EDIT: we're looking at a big tuple switch and that looks promising; if it pans out this approval still stands
src/D2L.CodeStyle.Analyzers/Immutability/ImmutableAttributeConsistencyChecker.cs
Show resolved
Hide resolved
src/D2L.CodeStyle.Analyzers/Immutability/ImmutableAttributeConsistencyChecker.cs
Show resolved
Hide resolved
src/D2L.CodeStyle.Analyzers/Immutability/ImmutableAttributeConsistencyChecker.cs
Show resolved
Hide resolved
Co-authored-by: Jacob Parker <[email protected]>
…sistencyChecker.cs Co-authored-by: Jacob Parker <[email protected]>
src/D2L.CodeStyle.Analyzers/Immutability/ImmutableAttributeConsistencyChecker.cs
Show resolved
Hide resolved
baseTypeInfo.Type.GetFullTypeName() | ||
) | ||
); | ||
return; |
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.
We talked about how we could drop this return if the diagnostic was on typeParameter
instead, like we could emit multiple diagnostics instead. I dno, consider it since this is a new diagnostic anyway
src/D2L.CodeStyle.Analyzers/Immutability/ImmutableAttributeConsistencyChecker.cs
Outdated
Show resolved
Hide resolved
src/D2L.CodeStyle.Analyzers/Immutability/ImmutableAttributeConsistencyChecker.cs
Outdated
Show resolved
Hide resolved
…sistencyChecker.cs Co-authored-by: Jacob Parker <[email protected]>
Fixes: #956