| // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| library web_components.build.html_import_recorder_inliner; |
| |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| import 'package:initialize/transformer.dart'; |
| import 'package:path/path.dart' as path; |
| import '../src/normalize_path.dart'; |
| |
| /// [InitializerPlugin] for @HtmlImport annotations. This records all paths |
| /// seen, normalizes them relative to the entry point, and records the values in |
| /// [importPaths]. |
| /// |
| /// Note: This does nothing with the paths on its own, a separate step needs to |
| /// add the imports to the entry point document. |
| class HtmlImportAnnotationRecorder implements InitializerPlugin { |
| /// All the normalized import paths that were seen. |
| final Set<String> importPaths = new Set<String>(); |
| |
| HtmlImportAnnotationRecorder(); |
| |
| /// Applies to anything named `HtmlImport` which annotates a library. |
| bool shouldApply(InitializerPluginData pluginData) { |
| var annotationElement = pluginData.initializer.annotationNode.element; |
| var logger = pluginData.logger; |
| DartType type; |
| if (annotationElement is ConstructorElement) { |
| type = annotationElement.returnType; |
| } else if (annotationElement is PropertyAccessorElement) { |
| type = annotationElement.variable.propagatedType; |
| if (type == null) { |
| type = pluginData.resolver |
| .evaluateConstant(annotationElement.library, |
| pluginData.initializer.annotationNode.name) |
| .value |
| .type; |
| } |
| } else { |
| logger.error('Unsupported annotation type. Only constructors and ' |
| 'properties are supported as initializers.'); |
| return false; |
| } |
| if (type.name != 'HtmlImport') return false; |
| if (pluginData.initializer.targetElement is! LibraryElement) { |
| logger.error('Invalid HtmlImport annotation on non-library element.'); |
| return false; |
| } |
| return true; |
| } |
| |
| /// Records the normalized url and returns [null] so that no [InitEntry] will |
| /// be created. |
| String apply(InitializerPluginData pluginData) { |
| var bootstrapId = pluginData.bootstrapId; |
| var logger = pluginData.logger; |
| var annotation = pluginData.initializer.annotationNode; |
| var annotationElement = pluginData.initializer.annotationElement; |
| var element = pluginData.initializer.targetElement as LibraryElement; |
| var resolver = pluginData.resolver; |
| |
| var originalImportPath; |
| if (annotationElement.element is PropertyAccessorElement) { |
| originalImportPath = resolver |
| .evaluateConstant(element.library, annotation.name) |
| .value |
| .fields['filePath'] |
| .toStringValue(); |
| } else { |
| assert(annotationElement.element is ConstructorElement); |
| originalImportPath = resolver |
| .evaluateConstant( |
| element.library, annotation.arguments.arguments.first) |
| .value |
| .toStringValue(); |
| } |
| |
| var libPath; |
| var segments = element.source.uri.pathSegments; |
| var package = segments[0]; |
| if (bootstrapId.package == package && |
| bootstrapId.path.startsWith('${segments[1]}/')) { |
| package = null; |
| libPath = path.url.relative( |
| path.url.joinAll(segments.getRange(1, segments.length)), |
| from: path.url.dirname(path.url.join(bootstrapId.path))); |
| } else if (segments[1] == 'lib') { |
| libPath = path.url.joinAll(segments.getRange(2, segments.length)); |
| } else { |
| logger.error('Unable to import `${element.source.uri.path}` from ' |
| '${bootstrapId}.'); |
| return null; |
| } |
| |
| importPaths |
| .add(normalizeHtmlImportPath(originalImportPath, package, libPath)); |
| |
| // Don't emit an InitEntry. |
| return null; |
| } |
| } |