Target of URI doesn't exist

585 views
Skip to first unread message
Message has been deleted

Jens Horstmann

unread,
May 6, 2021, 10:37:19 AM5/6/21
to Dart Analyzer Discussion
I am using the semantic analyzer with AnalysisContextCollection with the following parameters:
  • includedPaths: <path>/flutter/packages/flutter
  • sdk: <path>/flutter/bin/cache/dart-sdk
The configuration seems to work and a several thousand classes are analysed. However type resolving for Constructor parameters is not working. For instance when the Container widget is analysed (the location is <path>/flutter/packages/flutter/lib/src/widgets/container.dart) most of the parameter's types are evaluated to dynamic. I think the most relevant error is:

Target of URI doesn't exist: 'package:flutter/foundation.dart'

I am assuming that the location of package:flutter/foundation.dart is <path>/flutter/packages/flutter/lib/foundation.dart.

These questions come to my mind:
  • How can I pinpoint the problem?
  • How can I make sure the analyzer finds these imports
  • Am I using the correct analyzer function? Currently I am using session.getUnitElement2 but I am unsure if this is the right approach. Furthermore I have a hard time understanding what each of the methods exposed by AnalysisSession do. 

Jens Horstmann

unread,
May 6, 2021, 10:53:32 AM5/6/21
to Dart Analyzer Discussion, Jens Horstmann
Since messages seems to b posted with a delay, I accidentally double posted. I will remove one of the posts.

After doing some more testing and investigating in the mean time, I now assume that the analyzer is only analyzing a library (which partly explains the getResolvedLibrary2 method). Assuming I am correct with this assumption, I am wondering if it is possible to analyze a whole package (like the flutter package/sdk) and if yes how i'd do this.

Thanks in advance. 

Brian Wilkerson

unread,
May 6, 2021, 11:01:32 AM5/6/21
to Dart Analyzer Discussion
I am assuming that the location of package:flutter/foundation.dart is <path>/flutter/packages/flutter/lib/foundation.dart.

That's correct.

How can I pinpoint the problem?

By asking here. :-) You just need to understand the way the analyzer works, which is largely what this group is here for.

How can I make sure the analyzer finds these imports?

When the analyzer needs to resolve a URI to a file location there are three options:
  • If the URI is a `dart:` URI, then the library is found in a known location in the sdk.
  • If the URI is a `package:` URI, then the analyzer looks in each of the parent directories containing the library for a file whose relative path is `.dart_tool/package_config.json`. That file contains a JSON encoding of a map from the name of the package (`flutter` in this case) to the path of the `lib` directory for that package (`<path>/flutter/packages/flutter/lib` in this case). Everything after the first `/` in the URI is then appended to the path to form the full path to the file.
  • If the URI is any other kind of URI, then the normal URI resolution rules are followed.
The most likely problem here is that the analyzer is unable to locate the `package_config.json` file and hence can't convert the URI into a file path.

By the way, the process of finding the `package_config.json` file happens at the time you create the `AnalysisContextCollection` so that it doesn't need to be repeated for each library you analyze. That, and the locations of the `analysis_options.yaml` files, is what determines how many analysis contexts get created in the collection.

Am I using the correct analyzer function? Currently I am using session.getUnitElement2 but I am unsure if this is the right approach.

That depends on what you're trying to do. The method `getUnitElement2` will return the results of fully analyzing the content of a single file, while the method `getResolvedLibrary2` will return the results of fully analyzing all of the files in a single library. Because of part files, libraries can sometimes consist of more than one file. For efficiency, the analyzer always analyzes all of the files in a library together, so if you use `getUnitElement2` for each of the files in a library you'll actually be analyzing the whole library multiple times. If the code you're analyzing doesn't use part files, then there's no difference between these two APIs. If you want to use `getResolvedLibrary2` then you'll need to use `getFile2` first to determine which files are library files and which are part files.

Furthermore I have a hard time understanding what each of the methods exposed by AnalysisSession do.

Sorry about that. Sounds like we need to enhance the documentation for those methods to make it more clear.

Also, not that there's some minimal information in the analyzer package's `doc/tutorial` directory that might help explain some of the APIs and how they're used.

--
You received this message because you are subscribed to the Google Groups "Dart Analyzer Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to analyzer-discu...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/analyzer-discuss/e45513e7-af03-4134-b776-af178f9aa135n%40dartlang.org.

Brian Wilkerson

unread,
May 6, 2021, 11:13:08 AM5/6/21
to Dart Analyzer Discussion
Since messages seems to b posted with a delay ...

Yes, this is a moderated group, so the first posting needs to be reviewed and approved before it appears on the group. Future postings don't need to be approved, so you shouldn't see any more delays.

Assuming I am correct with this assumption, I am wondering if it is possible to analyze a whole package (like the flutter package/sdk) and if yes how i'd do this.

Your assumption is correct, but the answer is no, there isn't currently any short API for analyzing the whole analysis context. I suppose we could add such a method, but at the moment the only way to analyze a whole package is to iterate over the analysis contexts in the collection, and for each context iterate over the files contained in that context, and then process each file (possibly by ignoring part files and just resolving whole libraries).

By the way, I misspoke earlier. The method `getUnitElement2` returns only the `CompilationUnitElement` for the file; the method `getResolvedUnit2` returns all of the information produced by the analyzer, including both the resolved AST structure as well as the `CompilationUnitElement`. Again, which one is appropriate depends on which analysis results you need, which in turn depends on what you're trying to accomplish. I'm happy to give advice if you want to share more information about what you're doing.

--
You received this message because you are subscribed to the Google Groups "Dart Analyzer Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to analyzer-discu...@dartlang.org.

Jens Horstmann

unread,
May 7, 2021, 12:39:19 AM5/7/21
to analyzer...@dartlang.org

When the analyzer needs to resolve a URI to a file location there are three options:
  • If the URI is a `dart:` URI, then the library is found in a known location in the sdk.
  • If the URI is a `package:` URI, then the analyzer looks in each of the parent directories containing the library for a file whose relative path is `.dart_tool/package_config.json`. That file contains a JSON encoding of a map from the name of the package (`flutter` in this case) to the path of the `lib` directory for that package (`<path>/flutter/packages/flutter/lib` in this case). Everything after the first `/` in the URI is then appended to the path to form the full path to the file.
  • If the URI is any other kind of URI, then the normal URI resolution rules are followed.
The most likely problem here is that the analyzer is unable to locate the `package_config.json` file and hence can't convert the URI into a file path.

By the way, the process of finding the `package_config.json` file happens at the time you create the `AnalysisContextCollection` so that it doesn't need to be repeated for each library you analyze. That, and the locations of the `analysis_options.yaml` files, is what determines how many analysis contexts get created in the collection.

Thanks for taking the time to explain these things in so much detail. I highly appreciate it. After I found documentation regarding the package documentation file (https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md) I was able to get the import of other packages working 😊

That depends on what you're trying to do. The method `getUnitElement2` will return the results of fully analyzing the content of a single file, while the method `getResolvedLibrary2` will return the results of fully analyzing all of the files in a single library. Because of part files, libraries can sometimes consist of more than one file. For efficiency, the analyzer always analyzes all of the files in a library together, so if you use `getUnitElement2` for each of the files in a library you'll actually be analyzing the whole library multiple times. If the code you're analyzing doesn't use part files, then there's no difference between these two APIs. If you want to use `getResolvedLibrary2` then you'll need to use `getFile2` first to determine which files are library files and which are part files.

Ok interesting - I think the approach with getResolvedLibrary would be better in my case to avoid analysing parts of the library multiple times. 

Sorry about that. Sounds like we need to enhance the documentation for those methods to make it more clear.

Also, not that there's some minimal information in the analyzer package's `doc/tutorial` directory that might help explain some of the APIs and how they're used.

Thanks again for explaining everything. The documentation in the analyser package was helpful, but hard to find and - to me - it feels some things are not documented at all. In my opinion the aspects you described would make a great contribution towards the documentation. However, if you are limited on time, I’d be happy to contribute with a PR on GitHub once I’ve finished my project and gathered a better understanding of the analyzer. 

Brian Wilkerson

unread,
May 7, 2021, 12:56:44 AM5/7/21
to Dart Analyzer Discussion
Contributions are always welcome, thanks.

--
You received this message because you are subscribed to the Google Groups "Dart Analyzer Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to analyzer-discu...@dartlang.org.
Reply all
Reply to author
Forward
0 new messages