-
Notifications
You must be signed in to change notification settings - Fork 59
Cannot reflect flutter/material.dart
URIs for Container
type
#305
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
Comments
I suspect that 'package:flutter/material.dart' is treated as a special case by the analyzer, and hence there is no access to the declarations in that library. I'm not sure why that would be necessary, but other platform libraries behave in a similar manner. I can't immediately experiment with the situation as described:
Did you get that error, too? Do you have an easy fix for it? |
I assume you're using an older version of the Flutter SDK than I am.. I just pushed a change to the main branch that lowers the
I just tried a couple more use cases ('Provider' from riverpod, 'Directory' from That said, I'm not 100% familiar with the implementation details of reflectable, but afaik the analyzer simply needs to be pointed to paths from which to create an AnalysisContextCollection and perform analysis. I would assume it's the responsibility of I would therefore suspect that the issue lies either in reflectable's implementation or (more likely) I appreciate your help looking into this! |
Thanks! @jakemac53, does it ring a bell that 'package:flutter/material.dart' may appear to be non-existing during code generation? |
Build scripts (and thus builders) can't import (even transitively) things from dart:ui, but they should be available to the analyzer, and we have some basic tests to that effect, but they only test I am not sure why package:flutter wouldn't work. |
Okay, thanks for that info. I may have found a root cause: Debugging the build script of a flutter-based package shows that visibleLibraries contains several hundred libraries, including On closer look, only ~25 of these 600+ I assume that reflectable may be generating each Type's qualified name and library uri solely based on the library name, which could explain why it fails to output a URI for Container (or any other Flutter type for that matter). I would expect that the source URI would be used throughout the generated code instead of library name, since library names are rarely defined and source URIs are always available. wdyt? |
About the version of flutter: The first thing I did was updating, yielding this:
With the new commit on r.NonGenericClassMirrorImpl(
r'Container',
r'.Container',
134217735,
1,
const prefix0.AnalyzerReflector(),
const <int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 37, 49],
...
<Type>[
prefix1.Color,
prefix2.Container,
int,
prefix5.Widget,
prefix6.AlignmentGeometry,
prefix7.EdgeInsetsGeometry,
prefix8.Decoration,
prefix9.BoxConstraints,
.... This shows that the We have some library mirrors, too: <m.LibraryMirror>[
r.LibraryMirrorImpl(
r'dart.ui',
Uri.parse(r'reflectable://0/dart.ui'),
const prefix0.AnalyzerReflector(),
const <int>[],
{},
{},
const [],
null),
r.LibraryMirrorImpl(
r'',
Uri.parse(r'reflectable://1/'),
const prefix0.AnalyzerReflector(),
const <int>[],
{},
{},
const [],
null)
], Again, the first constructor argument is the So everything seems to work as expected, except that the URIs do not look like the ones we have in an The reason for this is that a
Yes, most libraries omit the So we may not be able to find the URI which is used in an
Not solely the library name, because that wouldn't be unique, so you wouldn't be able to distinguish different libraries from each other. But the library name is included (basically, to improve the readability in the cases where there is a library name).
As mentioned, the source URI is not a unique string for each library. It would be very nice, however, if we could deliver a usable URI which would resolve to the relevant disk file. I'm not quite sure how that could be done. |
There is one way to get something which can be used to compute a 'package' URI, at least in some cases: String assetId;
try {
assetId = (await _resolver.assetIdForElement(library)).toString();
} catch (_) { assetId = '<Unresolvable>'; } which yields
for a library which can be imported using import 'package:test_reflectable/test/reflect_type_test.dart'; Reflectable could be extended with a new instance variable in each As usual, there's a trade-off: Do we wish to spend more space on the generated code in order to get this feature? Is it going to be controlled by a capability? What should we do if a library mirror is requested for a given library, but that library has an unresolvable |
For the specific use case I had in mind (identifying if a runtime DartType is equivalent to a compile-time Type), I was thinking something more along the lines of identifying a Type by the exact file that its declared in (not by export files, for reasons you alluded at re: multiple export files). This would even allow for any edge cases where a single package defines two different Container types. For example, the type In an early prototype of sidecar, I used build_runner to generate such URIs and was able to reliably use them to check types during runtime.. This was inspired by how Ultimately, I would expect this URI be generated for each |
That should be easy for non-generic classes: void main() {
dynamic d = 1; // We've completely forgotten the type of this object.
Type runtimeType = d.runtimeType;
if (runtimeType == int) { // Test whether the run-time type is `int`.
...
}
} If your design relies on getting one or more of those 'Equivalent' types in this case are defined here. Note that For generic types, the value of the I have no idea how you are using these type equivalence tests, but |
In your example, you're testing equality between a This line in this example AstVisitor class (from branch: feat/flutter_type_checkers) is able to reflect the type However, that same example code will fail at the Since Hope this helps clear things up! :) |
Yes, I couldn't see any other way to map
to the situation where we're performing some run-time type equivalence test (whether or not this is done using reflectable).
OK, so we're talking about compile-time, not run time. Interesting! But this sounds like the code generated by reflectable is used with the target program at all?:
Very interesting! 😄 But reflectable wasn't created in order to support this scenario, so it may or may not work very smoothly. I assume that your use case is checking flutter programs in relation to their use of Flutter declared entities (that is, classes and other declared entities that are "owned" by Flutter), possibly in order to emit diagnostic messages, possibly in order to generate code, or whatever, but in any case in order to work on the client program which is being analyzed by the analyzer. This also means that you'd (probably) use reflectable to generate the code for a specific version of Flutter, and then you wouldn't use reflectable at all with the 'main library' of the client program as the entry point. And then you want to re-connect the Analyzer representation of a given declared entity with a mirror which was generated by reflectable. Sounds like the approach using |
The upcoming release 4.0.5 contains code to obtain and use a URI from the associated |
This PR deletes the legacy tests (they contain non-null-safe code and cannot be executed in the future). The PR also adjusts the SDK bounds in order to prepare for Dart 3. The update revealed that one test, 'test_reflectable/test/new_instance_native_test.dart', performed a reflective invocation of the list constructor named `List`, which is no longer supported. The test was adjusted to call another constructor of `List`. Finally, this PR changes the computation of the `uri` of a `LibraryMirror` such that it uses the URI of the corresponding `AssetId` whenever possible. This should be helpful in the situation where there is a need to find the actual source code, as requested in #305. The change in the result returned by the `uri` getter may seem like a breaking change, but it is hardly breaking in practice because the result returned previously was essentially meaningless (using the scheme reflectable which is not used anywhere else, and consisting mostly of a number which reflected the numbering of libraries being loaded by the analyzer during code generation). The new behavior is tested in the updated version of 'reflect_type_test.dart'.
Hi all -
I'm creating an
analyzer
based utility package, to more-easily allow developers to create lint rules, quick assists, etc, and one of the individual proof-of-concepts I'm designing is a more intuitive API for interacting with AST utilities like type-checkers. For more context, you can check out sidecar (the aforementioned analyzer utility) and reflectable_flutter_analyzer (attempted PoC of a Flutter-based analyzer that uses reflectable package).As the title explains, I'm unable to reflect
flutter/material.dart
type URIs usingpackage:reflectable
, which are needed to perform runtime-checking of a URI match between an analyzer Element's source URI and the expected URI of the Type (e.g. Container). I have this working fordart.ui.Color
but it does not work forContainer
frompackage:flutter
:The above code incorrectly generates the following:
The text was updated successfully, but these errors were encountered: