* @return the element representing the resolved library
* @throws AnalysisException if the library could not be resolved for some reason
*/
public LibraryElement resolveLibrary(Source librarySource, boolean fullAnalysis)
throws AnalysisException {
InstrumentationBuilder instrumentation = Instrumentation.builder("dart.engine.LibraryResolver.resolveLibrary");
try {
instrumentation.metric("fullAnalysis", fullAnalysis);
instrumentation.data("fullName", librarySource.getFullName());
//
// Create the objects representing the library being resolved and the core library.
//
Library targetLibrary = createLibrary(librarySource);
coreLibrary = libraryMap.get(coreLibrarySource);
if (coreLibrary == null) {
// This will be true unless the library being analyzed is the core library.
coreLibrary = createLibraryOrNull(coreLibrarySource);
if (coreLibrary == null) {
LibraryResolver2.missingCoreLibrary(analysisContext, coreLibrarySource);
}
}
instrumentation.metric("createLibrary", "complete");
//
// Compute the set of libraries that need to be resolved together.
//
computeLibraryDependencies(targetLibrary);
librariesInCycles = computeLibrariesInCycles(targetLibrary);
//
// Build the element models representing the libraries being resolved. This is done in three
// steps:
//
// 1. Build the basic element models without making any connections between elements other
// than the basic parent/child relationships. This includes building the elements
// representing the libraries, but excludes members defined in enums.
// 2. Build the elements for the import and export directives. This requires that we have the
// elements built for the referenced libraries, but because of the possibility of circular
// references needs to happen after all of the library elements have been created.
// 3. Build the members in enum declarations.
// 4. Build the rest of the type model by connecting superclasses, mixins, and interfaces. This
// requires that we be able to compute the names visible in the libraries being resolved,
// which in turn requires that we have resolved the import directives.
//
buildElementModels();
instrumentation.metric("buildElementModels", "complete");
LibraryElement coreElement = coreLibrary.getLibraryElement();
if (coreElement == null) {
throw new AnalysisException("Could not resolve dart:core");
}
buildDirectiveModels();
instrumentation.metric("buildDirectiveModels", "complete");
typeProvider = new TypeProviderImpl(coreElement);
buildEnumMembers();
buildTypeHierarchies();
instrumentation.metric("buildTypeHierarchies", "complete");
//
// Perform resolution and type analysis.
//
// TODO(brianwilkerson) Decide whether we want to resolve all of the libraries or whether we
// want to only resolve the target library. The advantage to resolving everything is that we
// have already done part of the work so we'll avoid duplicated effort. The disadvantage of
// resolving everything is that we might do extra work that we don't really care about. Another
// possibility is to add a parameter to this method and punt the decision to the clients.
//
//if (analyzeAll) {
resolveReferencesAndTypes();
instrumentation.metric("resolveReferencesAndTypes", "complete");
//} else {
// resolveReferencesAndTypes(targetLibrary);
//}
performConstantEvaluation();
instrumentation.metric("performConstantEvaluation", "complete");
instrumentation.metric("librariesInCycles", librariesInCycles.size());
for (Library lib : librariesInCycles) {
instrumentation.metric(
"librariesInCycles-CompilationUnitSources-Size",
lib.getCompilationUnitSources().size());
}
return targetLibrary.getLibraryElement();
} finally {
instrumentation.log(15); //Log if >= than 15ms
}
}