Index: third_party/pkg/angular/lib/tools/template_cache_generator.dart |
diff --git a/third_party/pkg/angular/lib/tools/template_cache_generator.dart b/third_party/pkg/angular/lib/tools/template_cache_generator.dart |
index 3c896b8c35ffd72c7d8b9aef0c122c5a0a3ce933..28167465f27a428d3887ab42bbbb20e291013ec4 100644 |
--- a/third_party/pkg/angular/lib/tools/template_cache_generator.dart |
+++ b/third_party/pkg/angular/lib/tools/template_cache_generator.dart |
@@ -7,6 +7,7 @@ import 'dart:collection'; |
import 'package:analyzer/src/generated/ast.dart'; |
import 'package:analyzer/src/generated/source.dart'; |
import 'package:analyzer/src/generated/element.dart'; |
+import 'package:args/args.dart'; |
import 'package:di/generator.dart'; |
const String PACKAGE_PREFIX = 'package:'; |
@@ -21,64 +22,129 @@ primeTemplateCache(TemplateCache tc) { |
'''; |
const String FILE_FOOTER = '}'; |
-const SYSTEM_PACKAGE_ROOT = '%SYSTEM_PACKAGE_ROOT%'; |
- |
-main(args) { |
- if (args.length < 4) { |
- print('Usage: templace_cache_generator path_to_entry_point sdk_path ' |
- 'output package_root1,package_root2,...|$SYSTEM_PACKAGE_ROOT ' |
- 'patternUrl1,rewriteTo1;patternUrl2,rewriteTo2 ' |
- 'blacklistClass1,blacklistClass2'); |
- exit(1); |
- } |
- |
- var entryPoint = args[0]; |
- var sdkPath = args[1]; |
- var output = args[2]; |
- var outputLibrary = args[3]; |
- var packageRoots = args[4] == SYSTEM_PACKAGE_ROOT ? |
- [Platform.packageRoot] : args[4].split(','); |
- Map<RegExp, String> urlRewriters = parseUrlRemapping(args[5]); |
- Set<String> blacklistedClasses = (args.length > 6) |
- ? new Set.from(args[6].split(',')) |
- : new Set(); |
- |
- print('sdkPath: $sdkPath'); |
- print('entryPoint: $entryPoint'); |
- print('output: $output'); |
- print('outputLibrary: $outputLibrary'); |
- print('packageRoots: $packageRoots'); |
- print('url rewritters: ' + args[5]); |
- print('blacklistedClasses: ' + blacklistedClasses.join(', ')); |
+main(List arguments) { |
+ Options options = parseArgs(arguments); |
+ if (options.verbose) { |
+ print('entryPoint: ${options.entryPoint}'); |
+ print('outputLibrary: ${options.outputLibrary}'); |
+ print('output: ${options.output}'); |
+ print('sdk-path: ${options.sdkPath}'); |
+ print('package-root: ${options.packageRoots.join(",")}'); |
+ print('template-root: ${options.templateRoots.join(",")}'); |
+ var rewrites = options.urlRewrites.keys |
+ .map((k) => '${k.pattern},${options.urlRewrites[k]}') |
+ .join(';'); |
+ print('url-rewrites: $rewrites'); |
+ print('skip-classes: ${options.skippedClasses.join(",")}'); |
+ } |
Map<String, String> templates = {}; |
- var c = new SourceCrawler(sdkPath, packageRoots); |
- var visitor = |
- new TemplateCollectingVisitor(templates, blacklistedClasses, c); |
- c.crawl(entryPoint, |
+ var c = new SourceCrawler(options.sdkPath, options.packageRoots); |
+ var visitor = new TemplateCollectingVisitor(templates, options.skippedClasses, |
+ c, options.templateRoots); |
+ c.crawl(options.entryPoint, |
(CompilationUnitElement compilationUnit, SourceFile source) => |
visitor(compilationUnit, source.canonicalPath)); |
- var sink = new File(output).openWrite(); |
+ var sink; |
+ if (options.output == '-') { |
+ sink = stdout; |
+ } else { |
+ var f = new File(options.output)..createSync(recursive: true); |
+ sink = f.openWrite(); |
+ } |
return printTemplateCache( |
- templates, urlRewriters, outputLibrary, sink).then((_) { |
- return sink.flush(); |
- }); |
+ templates, options.urlRewrites, options.outputLibrary, sink) |
+ .then((_) => sink.flush()); |
} |
-Map<RegExp, String> parseUrlRemapping(String argument) { |
- Map<RegExp, String> result = new LinkedHashMap(); |
- if (argument.isEmpty) { |
- return result; |
+class Options { |
+ String entryPoint; |
+ String outputLibrary; |
+ String sdkPath; |
+ List<String> packageRoots; |
+ List<String> templateRoots; |
+ String output; |
+ Map<RegExp, String> urlRewrites; |
+ Set<String> skippedClasses; |
+ bool verbose; |
+} |
+ |
+Options parseArgs(List arguments) { |
+ var parser = new ArgParser() |
+ ..addOption('sdk-path', abbr: 's', |
+ defaultsTo: Platform.environment['DART_SDK'], |
+ help: 'Dart SDK Path') |
+ ..addOption('package-root', abbr: 'p', defaultsTo: Platform.packageRoot, |
+ help: 'comma-separated list of package roots') |
+ ..addOption('template-root', abbr: 't', defaultsTo: '.', |
+ help: 'comma-separated list of paths from which templates with' |
+ 'absolute paths can be fetched') |
+ ..addOption('out', abbr: 'o', defaultsTo: '-', |
+ help: 'output file or "-" for stdout') |
+ ..addOption('url-rewrites', abbr: 'u', |
+ help: 'semicolon-separated list of URL rewrite rules, of the form: ' |
+ 'patternUrl,rewriteTo') |
+ ..addOption('skip-classes', abbr: 'b', |
+ help: 'comma-separated list of classes to skip templating') |
+ ..addFlag('verbose', abbr: 'v', help: 'verbose output') |
+ ..addFlag('help', abbr: 'h', negatable: false, help: 'show this help'); |
+ |
+ printUsage() { |
+ print('Usage: dart template_cache_generator.dart ' |
+ '--sdk-path=path [OPTION...] entryPoint libraryName'); |
+ print(parser.getUsage()); |
} |
- argument.split(";").forEach((String pair) { |
- List<String> remapping = pair.split(","); |
- result[new RegExp(remapping[0])] = remapping[1]; |
- }); |
- return result; |
+ fail(message) { |
+ print('Error: $message\n'); |
+ printUsage(); |
+ exit(1); |
+ } |
+ |
+ var args; |
+ try { |
+ args = parser.parse(arguments); |
+ } catch (e) { |
+ fail('failed to parse arguments'); |
+ } |
+ |
+ if (args['help']) { |
+ printUsage(); |
+ exit(0); |
+ } |
+ |
+ if (args['sdk-path'] == null) { |
+ fail('--sdk-path must be specified'); |
+ } |
+ |
+ var options = new Options(); |
+ options.sdkPath = args['sdk-path']; |
+ options.packageRoots = args['package-root'].split(','); |
+ options.templateRoots = args['template-root'].split(','); |
+ options.output = args['out']; |
+ if (args['url-rewrites'] != null) { |
+ options.urlRewrites = new LinkedHashMap.fromIterable( |
+ args['url-rewrites'].split(';').map((p) => p.split(',')), |
+ key: (p) => new RegExp(p[0]), |
+ value: (p) => p[1]); |
+ } else { |
+ options.urlRewrites = {}; |
+ } |
+ if (args['skip-classes'] != null) { |
+ options.skippedClasses = new Set.from(args['skip-classes'].split(',')); |
+ } else { |
+ options.skippedClasses = new Set(); |
+ } |
+ options.verbose = args['verbose']; |
+ if (args.rest.length != 2) { |
+ fail('unexpected arguments: ${args.rest.join(' ')}'); |
+ } |
+ options.entryPoint = args.rest[0]; |
+ options.outputLibrary = args.rest[1]; |
+ return options; |
} |
printTemplateCache(Map<String, String> templateKeyMap, |
@@ -112,13 +178,22 @@ printTemplateCache(Map<String, String> templateKeyMap, |
class TemplateCollectingVisitor { |
Map<String, String> templates; |
- Set<String> blacklistedClasses; |
+ Set<String> skippedClasses; |
SourceCrawler sourceCrawler; |
+ List<String> templateRoots; |
+ |
+ TemplateCollectingVisitor(this.templates, this.skippedClasses, |
+ this.sourceCrawler, this.templateRoots); |
- TemplateCollectingVisitor(this.templates, this.blacklistedClasses, |
- this.sourceCrawler); |
+ void call(CompilationUnitElement cue, String srcPath) { |
+ processDeclarations(cue, srcPath); |
+ |
+ cue.enclosingElement.parts.forEach((CompilationUnitElement part) { |
+ processDeclarations(part, srcPath); |
+ }); |
+ } |
- call(CompilationUnitElement cue, String srcPath) { |
+ void processDeclarations(CompilationUnitElement cue, String srcPath) { |
CompilationUnit cu = sourceCrawler.context |
.resolveCompilationUnit(cue.source, cue.library); |
cu.declarations.forEach((CompilationUnitMember declaration) { |
@@ -129,25 +204,25 @@ class TemplateCollectingVisitor { |
bool cache = true; |
clazz.metadata.forEach((Annotation ann) { |
if (ann.arguments == null) return; // Ignore non-class annotations. |
- if (blacklistedClasses.contains(clazz.name.name)) return; |
+ if (skippedClasses.contains(clazz.name.name)) return; |
switch (ann.name.name) { |
- case 'NgComponent': |
- extractNgComponentMetadata(ann, cacheUris); break; |
+ case 'Component': |
+ extractComponentMetadata(ann, cacheUris); break; |
case 'NgTemplateCache': |
cache = extractNgTemplateCache(ann, cacheUris); break; |
} |
}); |
if (cache && cacheUris.isNotEmpty) { |
- var srcDirUri = new Uri.file(srcPath); |
Source currentSrcDir = sourceCrawler.context.sourceFactory |
- .resolveUri2(null, srcDirUri); |
- cacheUris..sort()..forEach((uri) => storeUriAsset(uri, currentSrcDir)); |
+ .resolveUri(null, 'file://$srcPath'); |
+ cacheUris..sort()..forEach( |
+ (uri) => storeUriAsset(uri, currentSrcDir, templateRoots)); |
} |
}); |
} |
- void extractNgComponentMetadata(Annotation ann, List<String> cacheUris) { |
+ void extractComponentMetadata(Annotation ann, List<String> cacheUris) { |
ann.arguments.arguments.forEach((Expression arg) { |
if (arg is NamedExpression) { |
NamedExpression namedArg = arg; |
@@ -166,8 +241,7 @@ class TemplateCollectingVisitor { |
}); |
} |
- bool extractNgTemplateCache( |
- Annotation ann, List<String> cacheUris) { |
+ bool extractNgTemplateCache(Annotation ann, List<String> cacheUris) { |
bool cache = true; |
ann.arguments.arguments.forEach((Expression arg) { |
if (arg is NamedExpression) { |
@@ -186,8 +260,8 @@ class TemplateCollectingVisitor { |
return cache; |
} |
- void storeUriAsset(String uri, Source srcPath) { |
- String assetFileLocation = findAssetFileLocation(uri, srcPath); |
+ void storeUriAsset(String uri, Source srcPath, templateRoots) { |
+ String assetFileLocation = findAssetLocation(uri, srcPath, templateRoots); |
if (assetFileLocation == null) { |
print("Could not find asset for uri: $uri"); |
} else { |
@@ -195,10 +269,12 @@ class TemplateCollectingVisitor { |
} |
} |
- String findAssetFileLocation(String uri, Source srcPath) { |
+ String findAssetLocation(String uri, Source srcPath, List<String> |
+ templateRoots) { |
if (uri.startsWith('/')) { |
- // Absolute Path from working directory. |
- return '.${uri}'; |
+ var paths = templateRoots.map((r) => '$r/$uri'); |
+ return paths.firstWhere((p) => new File(p).existsSync(), |
+ orElse: () => paths.first); |
} |
// Otherwise let the sourceFactory resolve for packages, and relative paths. |
Source source = sourceCrawler.context.sourceFactory |