Reputation: 16199
I am currently using the Dart Analyzer package to parse and analyze Dart files. Currently it is mostly working with the following code.
PhysicalResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
DartSdk sdk = new FolderBasedDartSdk(
resourceProvider, resourceProvider.getFolder('D:\\Dart\\dart-sdk'));
var resolvers = [
new DartUriResolver(sdk),
new ResourceUriResolver(resourceProvider)
];
AnalysisContextImpl context = AnalysisEngine.instance.createAnalysisContext()
..sourceFactory = new SourceFactory(resolvers);
Source source = new FileSource(resourceProvider.getFile(item.path));
ChangeSet changeSet = new ChangeSet()..addedSource(source);
context.applyChanges(changeSet);
LibraryElement libElement = context.computeLibraryElement(source);
CompilationUnit resolvedUnit =
context.resolveCompilationUnit(source, libElement);
var element = resolvedUnit.declaredElement;
But this element isn't getting all the information, if it implements or extends classes that are in a different file. I eventually found this
context.sourcesNeedingProcessing
Where it shows the additional files that are referenced from the dart file, but it seems like they need processing.
If I copy those existing classes, all into 1 file, I get all the information I need, so I know its particularly about getting these files and processing them into the context.
Upvotes: 0
Views: 653
Reputation: 16199
I added a PackageMapUriResolver as such
var resolvers = [
new DartUriResolver(sdk),
new ResourceUriResolver(resourceProvider),
packageResolver(resourceProvider, 'packageName', resourceProvider.getFolder('C:\\folderLocationOfPackage'))
];
Then in a separate file I created the packageResolver method.
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
PackageMapUriResolver packageResolver(
ResourceProvider provider, String packageName, Folder folder) {
Map<String, List<Folder>> packageMap = new Map<String, List<Folder>>();
packageMap.putIfAbsent(packageName, () => [folder]);
var resolver = new PackageMapUriResolver(provider, packageMap);
return resolver;
}
Upvotes: 1
Reputation: 96
Without seeing the code you're trying to analyze I can't be certain, but I suspect that the problem is that you haven't included a URI resolver for package:
URIs. It isn't necessary to add all of the needed files to the analysis context, you just need to tell it how to find any files referenced from the added files.
Unfortunately, building a resolver for package:
URIs is non-trivial. You need to create an instance of PackageMapUriResolver
. That in turn requires using the package_config
package to create an instance of Packages
, and then convert that into a map (an example of doing that can be found in ContextBuilder.convertPackagesToMap
).
That said, if you're using a recent enough version of the package you could use the newer API that we're designing. I believe that what you're trying to do would be achieved by the following code:
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
main() async {
ResolvedUnitResult result = await resolveFile(item.path);
CompilationUnit resolvedUnit = result.unit;
CompilationUnitElement element = resolvedUnit.declaredElement;
}
Future<ResolvedUnitResult> resolveFile(String path) async {
AnalysisContextCollection collection = new AnalysisContextCollection(
includedPaths: <String>[path],
resourceProvider: PhysicalResourceProvider.INSTANCE,
);
AnalysisContext context = collection.contextFor(path);
return await context.currentSession.getResolvedUnit(path);
}
The collection is able to do all of the work of configuring the contexts for you, simplifying the process of getting analysis results.
A couple of things to note. First, the AnalysisContext
referenced here is not the same class as the AnalysisContext
referenced in your sample code.
Second, if you're going to be resolving multiple files then it will potentially be more efficient if you can pass in all of the file paths when creating the AnalysisContextCollection
.
Upvotes: 5