Add new API Compilation.IsAssignableTo(fromType, toType)#26719
Add new API Compilation.IsAssignableTo(fromType, toType)#26719gafter wants to merge 10 commits intodotnet:masterfrom
Conversation
We also remove the similar internal method from ISemanticFactsService Fixes dotnet#9461
|
Code change looks fine. But as per the issue discussion, i would want an exhaustive matrix here. i.e. have every type of type on the rows, and every type of type on hte columns, and check them all against each other (with expected positive/negative cases filled in for each intersection). If that reveals no problems, then this seems fine to me :) |
|
There is an extension method opportunity here. fromType.IsAssignableTo(toType, compilation)^ reads natural to me. If there is a way to dig out the compilation from the type symbol to avoid passing in compilation it would be sweet. |
| /// Returns true if there is an implicit (C#) or widening (VB) conversion from | ||
| /// <paramref name="fromType"/> to <paramref name="toType"/>. | ||
| /// </summary> | ||
| public abstract bool IsAssignableTo(ITypeSymbol fromType, ITypeSymbol toType); |
There was a problem hiding this comment.
IsAssignableTo [](start = 29, length = 14)
The name sounds very similar to a well known API Type.IsAssignableFrom, but according to the doc comment doesn't quite match the behavior. This could be a source of big confusion for consumers and as a result a source of misuse of the API. #Resolved
There was a problem hiding this comment.
Consider renaming to "IsSafeToConvertTo", "SafeConversionExists",or something similar.
In reply to: 186800542 [](ancestors = 186800542)
There was a problem hiding this comment.
I like IsAssignableTo, short & clear. #Resolved
There was a problem hiding this comment.
Also the fact that in VB a widening conversion is not a requirement for things to be assignable should be taken into consideration when choosing the name of this API #Resolved
There was a problem hiding this comment.
@AlekseyTs can you give some examples? it would be super helpful for getting everyone understanding this space better. Thanks! #Resolved
There was a problem hiding this comment.
What does that mean though? In particular, what do you define "implicit" as. And i'm with Aleksey, what does this mean in VB? #Resolved
There was a problem hiding this comment.
I'm willing to look through the links, but it would be useful to have primary use cases where the feature can describe precisely the sort of question it is trying to ask (in a non-self referential fashion). i.e. we shouldn't say "teh feature is trying to know if it's an implicit conversion". We should say "teh feature is trying to decide if applying the conversion at runtime would succeed or not". #Resolved
There was a problem hiding this comment.
For example, VB says this: "Implicit conversions occur without any special syntax". Is it true then that .isWidening is the right impl to answer that question? To me, it looks like no. For example:
If permissive semantics are being used, all widening and narrowing conversions (in other words, all conversions) may occur implicitly.
#Resolved
There was a problem hiding this comment.
There are places in C# where non-implicit conversions occur implicitly (e.g. in a foreach loop). I'll make sure the doc comments are clear.
In reply to: 186879526 [](ancestors = 186879526)
There was a problem hiding this comment.
Since we now have a team for deciding public CodeAnalysis API changes, I'll submit this question to that group. (and point them to this thread for context)
In reply to: 186923887 [](ancestors = 186923887,186879526)
| /// Returns true if there is an implicit conversion from | ||
| /// <paramref name="fromType"/> to <paramref name="toType"/>. | ||
| /// </summary> | ||
| public override bool IsAssignableTo(ITypeSymbol fromType, ITypeSymbol toType) |
There was a problem hiding this comment.
public override bool IsAssignableTo(ITypeSymbol fromType, ITypeSymbol toType) [](start = 8, length = 77)
Consider moving this method next to the ClassifyConversion that is calls. #ByDesign
There was a problem hiding this comment.
I'd prefer to keep it in the region that correctly describes its place in the hierarchy.
In reply to: 186801079 [](ancestors = 186801079)
| ''' Returns true if there is a widening conversion from | ||
| ''' <paramref name="fromType"/> to <paramref name="toType"/>. | ||
| ''' </summary> | ||
| Public Overrides Function IsAssignableTo(fromType As ITypeSymbol, toType As ITypeSymbol) As Boolean |
There was a problem hiding this comment.
Public Overrides Function IsAssignableTo(fromType As ITypeSymbol, toType As ITypeSymbol) As Boolean [](start = 8, length = 99)
Same suggestion as for C# #ByDesign
There was a problem hiding this comment.
| // <auto-generated> | ||
| // This code was generated by a tool. | ||
| // Runtime Version:4.0.30319.34011 | ||
| // Runtime Version:4.0.30319.42000 |
There was a problem hiding this comment.
This file doesn't have any meaningful changes, consider reverting #Resolved
|
Done with review pass (iteration 1) |
|
This is a super helpful API - I think we have more than 10 such operation/symbol analyzers in FxCop analyzers package that need C# and VB implementations just to get this functionality. I will file a separate issue to track adding IOperation support for this. |
|
This PR is pending review and suggestions by the CodeAnalysis API team, half of which are at Build now. Until they are back this is on hold. |
|
I renamed it to |
| /// either <paramref name="fromType"/> or <paramref name="toType"/> is null, or | ||
| /// if no such conversion exists. | ||
| /// </summary> | ||
| public abstract bool HasImplicitConversion(ITypeSymbol fromType, ITypeSymbol toType); |
There was a problem hiding this comment.
So, i'm on the fence about this entire PR :) mainly because of how many different ways it seems to be able to determine this sort of thing. i.e. we have:
CommonCompilation.HasImplicitConversion, then we have:
CSharpCompilation/BasicComplation.ClassifyConversion, then we have
IOperation.IConversionOperation/CommonConversion
My main issue is that it feels like this doesn't go far enough. For example, what if i wanted ot ask "Is there a reference conversion between these two types?" Now i'm back where i started.
Please don't shoot me, but i think my preference here would be that instead of having this API we take the following two steps:
- Move a ClassifyCommonConversion call down to Compilation (and have it return a CommonConversion).
- Add 'IsImplicit' to CommonConversion and document (like here) that it means 'implicit' for C# and 'widening' for VB.
This would seem to solve the motivating scenario, as someone could call compilation.ClassifyCommonConversion(...).IsImplicit, but it would also still expose all the rest of hte information while being consistent with teh types/shapes we use elsewhere for talking about this stuff.
With this, we could still have HasImplicitConversion. But it could just be an extension method on Compilation, that called hte ClassifyCommonConversion helper.
Thoughts, @gafter? This PR feels a bit too "one-off" to me. I think we should go for a more generalized approach that fits in better with the shape of our API elsewhere. #Resolved
There was a problem hiding this comment.
I think this is a great suggestion. I will investigate more. #Resolved
There was a problem hiding this comment.
Note: one unfortunate issue here is with naming. We can't actually have "ClassifyConversion" on Compilatoin as that would now shadow the extensions we have for the language specific ClassifyConversion extensions. Hence why it would be called ClassifyCommonConversion instead. But i feel like that's not too bad, especially given the different types of results actually returned. #Resolved
CyrusNajmabadi
left a comment
There was a problem hiding this comment.
In terms of exposing the HasImplicitConversoin method, i think this PR is fine. However... i've given feedback that i think overall we could still answer that questoin in a more general and cleaner fashion. Thanks!
|
@CyrusNajmabadi Please have a look at this revised proposed API. What do you think? |
| namespace Microsoft.CodeAnalysis.Test.Utilities | ||
| { | ||
| public static class CompilationExtensions | ||
| public static class CompilationExtensions2 |
There was a problem hiding this comment.
Rather than 2, can we do TestCompilationExtensions? Suffixing 2 feels wrong. #Resolved
There was a problem hiding this comment.
Or CompilationTestExtensions #Resolved
|
Review of approved API moved to #27093 |
We also remove the similar internal method from ISemanticFactsService
Fixes #9461
/cc @CyrusNajmabadi for preliminary review