Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Unified Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1659523003: Make a DirectiveElementBuilder class for use by BuildDirectiveElementsTask. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/task/dart.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/resolver.dart
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 986637df213cc38e82c087e1342251828a6a5b0c..7c481af3a66a2cb53a281842451ae76aeda05a9b 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -23,6 +23,7 @@ import 'package:analyzer/src/generated/error_verifier.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/static_type_analyzer.dart';
import 'package:analyzer/src/generated/type_system.dart';
@@ -2651,6 +2652,235 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
}
/**
+ * Instances of the class `DirectiveElementBuilder` build elements for top
+ * level library directives.
+ */
+class DirectiveElementBuilder extends SimpleAstVisitor<Object> {
Brian Wilkerson 2016/02/02 14:58:16 Consider moving this into it's own file, such as l
Paul Berry 2016/02/02 17:50:54 Done.
+ /**
+ * The analysis context within which directive elements are being built.
+ */
+ final AnalysisContext context;
+
+ /**
+ * The library element for which directive elements are being built.
+ */
+ final LibraryElementImpl libraryElement;
+
+ /**
+ * Map from sources imported by this library to their corresponding library
+ * elements.
+ */
+ final Map<Source, LibraryElement> importLibraryMap;
+
+ /**
+ * Map from sources imported by this library to their corresponding source
+ * kinds.
+ */
+ final Map<Source, SourceKind> importSourceKindMap;
+
+ /**
+ * Map from sources exported by this library to their corresponding library
+ * elements.
+ */
+ final Map<Source, LibraryElement> exportLibraryMap;
+
+ /**
+ * Map from sources exported by this library to their corresponding source
+ * kinds.
+ */
+ final Map<Source, SourceKind> exportSourceKindMap;
+
+ /**
+ * The [ImportElement]s created so far.
+ */
+ final List<ImportElement> imports = <ImportElement>[];
+
+ /**
+ * The [ExportElement]s created so far.
+ */
+ final List<ExportElement> exports = <ExportElement>[];
+
+ /**
+ * The errors found while building directive elements.
+ */
+ final List<AnalysisError> errors = <AnalysisError>[];
+
+ /**
+ * Map from prefix names to their corresponding elements.
+ */
+ final HashMap<String, PrefixElementImpl> nameToPrefixMap =
+ new HashMap<String, PrefixElementImpl>();
+
+ /**
+ * Indicates whether an explicit import of `dart:core` has been found.
+ */
+ bool explicitlyImportsCore = false;
+
+ DirectiveElementBuilder(
+ this.context,
+ this.libraryElement,
+ this.importLibraryMap,
+ this.importSourceKindMap,
+ this.exportLibraryMap,
+ this.exportSourceKindMap);
+
+ @override
+ Object visitCompilationUnit(CompilationUnit node) {
+ //
+ // Resolve directives.
+ //
+ for (Directive directive in node.directives) {
+ directive.accept(this);
+ }
+ //
+ // Ensure "dart:core" import.
+ //
+ Source librarySource = libraryElement.source;
+ Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
+ if (!explicitlyImportsCore && coreLibrarySource != librarySource) {
+ ImportElementImpl importElement = new ImportElementImpl(-1);
+ importElement.importedLibrary = importLibraryMap[coreLibrarySource];
+ importElement.synthetic = true;
+ imports.add(importElement);
+ }
+ //
+ // Populate the library element.
+ //
+ libraryElement.imports = imports;
+ libraryElement.exports = exports;
+ return null;
+ }
+
+ @override
+ Object visitExportDirective(ExportDirective node) {
+ Source exportedSource = node.source;
+ if (exportedSource != null && context.exists(exportedSource)) {
+ // The exported source will be null if the URI in the export
+ // directive was invalid.
+ LibraryElement exportedLibrary = exportLibraryMap[exportedSource];
+ if (exportedLibrary != null) {
+ ExportElementImpl exportElement = new ExportElementImpl(node.offset);
+ StringLiteral uriLiteral = node.uri;
+ if (uriLiteral != null) {
+ exportElement.uriOffset = uriLiteral.offset;
+ exportElement.uriEnd = uriLiteral.end;
+ }
+ exportElement.uri = node.uriContent;
+ exportElement.combinators = _buildCombinators(node);
+ exportElement.exportedLibrary = exportedLibrary;
+ _setDoc(exportElement, node);
+ node.element = exportElement;
+ exports.add(exportElement);
+ if (exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
+ errors.add(new AnalysisError(
+ exportedSource,
+ uriLiteral.offset,
+ uriLiteral.length,
+ CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+ [uriLiteral.toSource()]));
+ }
+ }
+ }
+ return null;
+ }
+
+ @override
+ Object visitImportDirective(ImportDirective node) {
+ String uriContent = node.uriContent;
+ if (DartUriResolver.isDartExtUri(uriContent)) {
+ libraryElement.hasExtUri = true;
+ }
+ Source importedSource = node.source;
+ if (importedSource != null && context.exists(importedSource)) {
+ // The imported source will be null if the URI in the import
+ // directive was invalid.
+ LibraryElement importedLibrary = importLibraryMap[importedSource];
+ if (importedLibrary != null) {
+ if (importedLibrary.isDartCore) {
+ explicitlyImportsCore = true;
+ }
+ ImportElementImpl importElement = new ImportElementImpl(node.offset);
+ StringLiteral uriLiteral = node.uri;
+ if (uriLiteral != null) {
+ importElement.uriOffset = uriLiteral.offset;
+ importElement.uriEnd = uriLiteral.end;
+ }
+ importElement.uri = uriContent;
+ importElement.deferred = node.deferredKeyword != null;
+ importElement.combinators = _buildCombinators(node);
+ importElement.importedLibrary = importedLibrary;
+ _setDoc(importElement, node);
+ SimpleIdentifier prefixNode = node.prefix;
+ if (prefixNode != null) {
+ importElement.prefixOffset = prefixNode.offset;
+ String prefixName = prefixNode.name;
+ PrefixElementImpl prefix = nameToPrefixMap[prefixName];
+ if (prefix == null) {
+ prefix = new PrefixElementImpl.forNode(prefixNode);
+ nameToPrefixMap[prefixName] = prefix;
+ }
+ importElement.prefix = prefix;
+ prefixNode.staticElement = prefix;
+ }
+ node.element = importElement;
+ imports.add(importElement);
+ if (importSourceKindMap[importedSource] != SourceKind.LIBRARY) {
+ ErrorCode errorCode = (importElement.isDeferred
+ ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
+ : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
+ errors.add(new AnalysisError(importedSource, uriLiteral.offset,
+ uriLiteral.length, errorCode, [uriLiteral.toSource()]));
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * If the given [node] has a documentation comment, remember its content
+ * and range into the given [element].
+ */
+ void _setDoc(ElementImpl element, AnnotatedNode node) {
+ Comment comment = node.documentationComment;
+ if (comment != null && comment.isDocumentation) {
+ element.documentationComment =
+ comment.tokens.map((Token t) => t.lexeme).join('\n');
+ element.setDocRange(comment.offset, comment.length);
+ }
+ }
+
+ /**
+ * Build the element model representing the combinators declared by
+ * the given [directive].
+ */
+ static List<NamespaceCombinator> _buildCombinators(
+ NamespaceDirective directive) {
+ List<NamespaceCombinator> combinators = <NamespaceCombinator>[];
+ for (Combinator combinator in directive.combinators) {
+ if (combinator is ShowCombinator) {
Brian Wilkerson 2016/02/02 14:58:16 Would it make sense to use the visitor pattern her
Paul Berry 2016/02/02 17:50:53 Done.
+ ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
+ show.offset = combinator.offset;
+ show.end = combinator.end;
+ show.shownNames = _getIdentifiers(combinator.shownNames);
+ combinators.add(show);
+ } else if (combinator is HideCombinator) {
+ HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
+ hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
+ combinators.add(hide);
+ }
+ }
+ return combinators;
+ }
+
+ /**
+ * Return the lexical identifiers associated with the given [identifiers].
+ */
+ static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) {
+ return identifiers.map((identifier) => identifier.name).toList();
+ }
+}
+
+/**
* Instances of the class `ElementBuilder` traverse an AST structure and build the element
* model representing the AST structure.
*/
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/task/dart.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698