-
Notifications
You must be signed in to change notification settings - Fork 160
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
There is no way to generate a mock of Foo<Bar>
if Bar
is a type parameter bound
#559
Comments
Yeah I think we can't tell in the element model if T was instantiated to its bound, or if it's bound was provided directly. |
One way to support this would be to add a flag which sends an explicit signal to mockito code-gen to "make this non-generic." Something like |
Yeah, that would be a possible workaround but it really feels wrong that user has to tell us this explicitly. Why would I (as an user) even care I instantiate it with the exact bound? I would argue that since I found another workaround BTW: we can do |
Agreed.
Yeah, agreed. |
I don't understand why you need to distinguish. Both |
When a user wants to say, "I want to generate a mock class for
However, with an annotation like that, there is no way to specify whether they want a generic mock ( (Long story) We currently assume they want a generic one, because who wants |
Can you add a parameter to |
That is my idea above 😄 |
Yes, almost. I just thought (randomly) to ask explicitly for generic. Now, I can rationalize it by saying that It seems that what we need it a reference to a class, and pass it to |
Yes, I agree that it makes more sense to get the instantiated class by default and only make it generic if asked explicitly (with almost the same argument, see my comment), but that's a breaking API change. Well, maybe we can break the new |
Assuming `Foo` is declared as `class Foo<T extends Bar> { /* ... */ }`, there is indeed no way to take apart `Foo` from `Foo<Bar>` once it gets into the analyzer internals and becomes an `InterfaceType`. The AST still preserve this information though but we are not looking at the annotation AST, instead we utilize the `computeContantValue` that gives us `DartObject` that is easier to work with but now `Foo` and `Foo<Bar>` are smashed together. It appears to me that there is currently even no public API to get the AST for the annotation, so I had to cheat with ```dart (annotation as ElementAnnotationImpl).annotationAst ``` to get the actual AST. When we can use it to just check the presence of type arguments and pass the results down. This is still rather unclean, not using the best practice and doesn't work in all cases where constant evaluation does. For example, with constant evaluation one can declared `MockSpec` as a constant outside of the annotation and then use it, but it breaks with direct AST access. I haven't found any other examples so far. Not being able to use `MockSpec`s defined as constants doesn't really look like a big deal though: there is no reasonable way to use a `MockSpec` instance more than once anyway, I think. On the positive side, this change fixes the bug without changing the API. Fixes #559 and #563. Also opens a way for fixing #562. PiperOrigin-RevId: 467867637
Assuming `Foo` is declared as `class Foo<T extends Bar> { /* ... */ }`, there is indeed no way to take apart `Foo` from `Foo<Bar>` once it gets into the analyzer internals and becomes an `InterfaceType`. The AST still preserve this information though but we are not looking at the annotation AST, instead we utilize the `computeContantValue` that gives us `DartObject` that is easier to work with but now `Foo` and `Foo<Bar>` are smashed together. It appears to me that there is currently even no public API to get the AST for the annotation, so I had to cheat with ```dart (annotation as ElementAnnotationImpl).annotationAst ``` to get the actual AST. When we can use it to just check the presence of type arguments and pass the results down. This is still rather unclean, not using the best practice and doesn't work in all cases where constant evaluation does. For example, with constant evaluation one can declared `MockSpec` as a constant outside of the annotation and then use it, but it breaks with direct AST access. I haven't found any other examples so far. Not being able to use `MockSpec`s defined as constants doesn't really look like a big deal though: there is no reasonable way to use a `MockSpec` instance more than once anyway, I think. On the positive side, this change fixes the bug without changing the API. Fixes #559 and #563. Also opens a way for fixing #562. PiperOrigin-RevId: 467867637
Assuming `Foo` is declared as `class Foo<T extends Bar> { /* ... */ }`, there is indeed no way to take apart `Foo` from `Foo<Bar>` once it gets into the analyzer internals and becomes an `InterfaceType`. The AST still preserve this information though but we are not looking at the annotation AST, instead we utilize the `computeContantValue` that gives us `DartObject` that is easier to work with but now `Foo` and `Foo<Bar>` are smashed together. It appears to me that there is currently even no public API to get the AST for the annotation, so I had to cheat with ```dart (annotation as ElementAnnotationImpl).annotationAst ``` to get the actual AST. When we can use it to just check the presence of type arguments and pass the results down. This is still rather unclean, not using the best practice and doesn't work in all cases where constant evaluation does. For example, with constant evaluation one can declared `MockSpec` as a constant outside of the annotation and then use it, but it breaks with direct AST access. I haven't found any other examples so far. Not being able to use `MockSpec`s defined as constants doesn't really look like a big deal though: there is no reasonable way to use a `MockSpec` instance more than once anyway, I think. On the positive side, this change fixes the bug without changing the API. Fixes #559 and #563. Also opens a way for fixing #562. PiperOrigin-RevId: 467867637
Assume we have
This is supposed to work without
unsupportedMembers
sinceT
gets instantiated to the concrete typeBar
, but the codegen can't actually take apartFoo<Bar>
from justFoo
(analyzer limitation?), so it assumes it'sFoo
and generates a mock for the generic type, even though an instantiated version was requested, requiring to addunsupportedMembers
orfallbackGenerators
.The text was updated successfully, but these errors were encountered: