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

Side by Side Diff: pkg/analyzer/tool/task_dependency_graph/generate.dart

Issue 1428673004: Rework codegen tools to avoid relying on CWD; integrate with task model graph. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « pkg/analyzer/tool/task_dependency_graph/check_test.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * This file contains code to output a description of tasks and their 6 * This file contains code to output a description of tasks and their
7 * dependencies in ".dot" format. Prior to running, the user should run "pub 7 * dependencies in ".dot" format. Prior to running, the user should run "pub
8 * get" in the analyzer directory to ensure that a "packages" folder exists. 8 * get" in the analyzer directory to ensure that a "packages" folder exists.
9 * 9 *
10 * TODO(paulberry): 10 * TODO(paulberry):
11 * - Add general.dart and html.dart for completeness. 11 * - Add general.dart and html.dart for completeness.
12 * - Use Graphviz's "record" feature to produce more compact output 12 * - Use Graphviz's "record" feature to produce more compact output
13 * (http://www.graphviz.org/content/node-shapes#record) 13 * (http://www.graphviz.org/content/node-shapes#record)
14 * - Produce a warning if a result descriptor is found which isn't the output 14 * - Produce a warning if a result descriptor is found which isn't the output
15 * of exactly one task. 15 * of exactly one task.
16 * - Convert this tool to use package_config to find the package map. 16 * - Convert this tool to use package_config to find the package map.
17 */ 17 */
18 library task_dependency_graph.generate; 18 library task_dependency_graph.generate;
19 19
20 import 'dart:io' hide File; 20 import 'dart:io' hide File;
21 import 'dart:io' as io; 21 import 'dart:io' as io;
22 22
23 import 'package:analyzer/analyzer.dart'; 23 import 'package:analyzer/analyzer.dart';
24 import 'package:analyzer/file_system/file_system.dart'; 24 import 'package:analyzer/file_system/file_system.dart';
25 import 'package:analyzer/file_system/physical_file_system.dart'; 25 import 'package:analyzer/file_system/physical_file_system.dart';
26 import 'package:analyzer/src/codegen/tools.dart';
26 import 'package:analyzer/src/generated/constant.dart'; 27 import 'package:analyzer/src/generated/constant.dart';
27 import 'package:analyzer/src/generated/element.dart'; 28 import 'package:analyzer/src/generated/element.dart';
28 import 'package:analyzer/src/generated/engine.dart'; 29 import 'package:analyzer/src/generated/engine.dart';
29 import 'package:analyzer/src/generated/java_io.dart'; 30 import 'package:analyzer/src/generated/java_io.dart';
30 import 'package:analyzer/src/generated/sdk.dart'; 31 import 'package:analyzer/src/generated/sdk.dart';
31 import 'package:analyzer/src/generated/sdk_io.dart'; 32 import 'package:analyzer/src/generated/sdk_io.dart';
32 import 'package:analyzer/src/generated/source.dart'; 33 import 'package:analyzer/src/generated/source.dart';
33 import 'package:analyzer/src/generated/source_io.dart'; 34 import 'package:analyzer/src/generated/source_io.dart';
34 import 'package:path/path.dart' as path; 35 import 'package:path/path.dart' as path;
36 import 'package:path/path.dart';
35 37
36 /** 38 /**
37 * Generate the target .dot file. 39 * Generate the target .dot file.
38 */ 40 */
39 main() { 41 main() {
40 new Driver().generateFile(); 42 String script = Platform.script.toFilePath(windows: Platform.isWindows);
43 String pkgPath = normalize(join(dirname(script), '..', '..'));
44 target.generate(pkgPath);
41 } 45 }
42 46
47 final GeneratedFile target = new GeneratedFile(
48 'tool/task_dependency_graph/tasks.dot',
49 (String pkgPath) => new Driver(pkgPath).generateFileContents());
50
43 typedef void GetterFinderCallback(PropertyAccessorElement element); 51 typedef void GetterFinderCallback(PropertyAccessorElement element);
44 52
45 class Driver { 53 class Driver {
46 PhysicalResourceProvider resourceProvider; 54 PhysicalResourceProvider resourceProvider;
47 AnalysisContext context; 55 AnalysisContext context;
48 InterfaceType resultDescriptorType; 56 InterfaceType resultDescriptorType;
49 InterfaceType listOfResultDescriptorType; 57 InterfaceType listOfResultDescriptorType;
50 ClassElement enginePluginClass; 58 ClassElement enginePluginClass;
51 CompilationUnitElement taskUnitElement; 59 CompilationUnitElement taskUnitElement;
52 InterfaceType extensionPointIdType; 60 InterfaceType extensionPointIdType;
53 final String rootDir; 61 final String rootDir;
54 62
55 Driver() 63 Driver(String pkgPath) : rootDir = new Directory(pkgPath).absolute.path;
56 : rootDir =
57 findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
58 64
59 /** 65 /**
60 * Get an [io.File] object corresponding to the file in which the generated 66 * Get an [io.File] object corresponding to the file in which the generated
61 * graph should be output. 67 * graph should be output.
62 */ 68 */
63 io.File get file => new io.File( 69 io.File get file => new io.File(
64 path.join(rootDir, 'tool', 'task_dependency_graph', 'tasks.dot')); 70 path.join(rootDir, 'tool', 'task_dependency_graph', 'tasks.dot'));
65 71
66 /** 72 /**
67 * Determine if the output [file] contains the expected contents.
68 */
69 bool checkFile() {
70 String expectedContents = generateFileContents();
71 String actualContents = file.readAsStringSync();
72 // Normalize Windows line endings to Unix line endings so that the
73 // comparison doesn't fail on Windows.
74 actualContents = actualContents.replaceAll('\r\n', '\n');
75 return expectedContents == actualContents;
76 }
77
78 /**
79 * Starting at [node], find all calls to registerExtension() which refer to 73 * Starting at [node], find all calls to registerExtension() which refer to
80 * the given [extensionIdVariable], and execute [callback] for the associated 74 * the given [extensionIdVariable], and execute [callback] for the associated
81 * result descriptors. 75 * result descriptors.
82 */ 76 */
83 void findExtensions(AstNode node, TopLevelVariableElement extensionIdVariable, 77 void findExtensions(AstNode node, TopLevelVariableElement extensionIdVariable,
84 void callback(descriptorName)) { 78 void callback(descriptorName)) {
85 Set<PropertyAccessorElement> resultDescriptors = 79 Set<PropertyAccessorElement> resultDescriptors =
86 new Set<PropertyAccessorElement>(); 80 new Set<PropertyAccessorElement>();
87 node.accept(new ExtensionFinder( 81 node.accept(new ExtensionFinder(
88 resultDescriptorType, extensionIdVariable, resultDescriptors.add)); 82 resultDescriptorType, extensionIdVariable, resultDescriptors.add));
(...skipping 27 matching lines...) Expand all
116 AstNode node, void callback(String descriptorName)) { 110 AstNode node, void callback(String descriptorName)) {
117 Set<PropertyAccessorElement> resultDescriptors = 111 Set<PropertyAccessorElement> resultDescriptors =
118 new Set<PropertyAccessorElement>(); 112 new Set<PropertyAccessorElement>();
119 node.accept(new GetterFinder(resultDescriptorType, resultDescriptors.add)); 113 node.accept(new GetterFinder(resultDescriptorType, resultDescriptors.add));
120 for (PropertyAccessorElement resultDescriptor in resultDescriptors) { 114 for (PropertyAccessorElement resultDescriptor in resultDescriptors) {
121 callback(resultDescriptor.name); 115 callback(resultDescriptor.name);
122 } 116 }
123 } 117 }
124 118
125 /** 119 /**
126 * Generate the task dependency graph and write it to the output [file].
127 */
128 void generateFile() {
129 String fileContents = generateFileContents();
130 file.writeAsStringSync(fileContents);
131 }
132
133 /**
134 * Generate the task dependency graph and return it as a [String]. 120 * Generate the task dependency graph and return it as a [String].
135 */ 121 */
136 String generateFileContents() { 122 String generateFileContents() {
137 List<String> lines = <String>[]; 123 List<String> lines = <String>[];
138 resourceProvider = PhysicalResourceProvider.INSTANCE; 124 resourceProvider = PhysicalResourceProvider.INSTANCE;
139 DartSdk sdk = DirectoryBasedDartSdk.defaultSdk; 125 DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
140 context = AnalysisEngine.instance.createAnalysisContext(); 126 context = AnalysisEngine.instance.createAnalysisContext();
141 String packageRootPath; 127 String packageRootPath;
142 if (Platform.packageRoot.isNotEmpty) { 128 if (Platform.packageRoot.isNotEmpty) {
143 packageRootPath = Platform.packageRoot; 129 packageRootPath = Platform.packageRoot;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 in taskUnitElement.topLevelVariables) { 247 in taskUnitElement.topLevelVariables) {
262 if (variable.name == extensionPointId) { 248 if (variable.name == extensionPointId) {
263 return variable; 249 return variable;
264 } 250 }
265 } 251 }
266 } 252 }
267 } 253 }
268 throw new Exception( 254 throw new Exception(
269 'Could not find extension ID corresponding to $resultListGetterName'); 255 'Could not find extension ID corresponding to $resultListGetterName');
270 } 256 }
271
272 /**
273 * Find the root directory of the analyzer package by proceeding
274 * upward to the 'tool' dir, and then going up one more directory.
275 */
276 static String findRoot(String pathname) {
277 while (path.basename(pathname) != 'tool') {
278 String parent = path.dirname(pathname);
279 if (parent.length >= pathname.length) {
280 throw new Exception("Can't find root directory");
281 }
282 pathname = parent;
283 }
284 return path.dirname(pathname);
285 }
286 } 257 }
287 258
288 /** 259 /**
289 * Visitor that finds calls that register extension points. Specifically, we 260 * Visitor that finds calls that register extension points. Specifically, we
290 * look for calls of the form `method(extensionIdVariable, resultDescriptor)`, 261 * look for calls of the form `method(extensionIdVariable, resultDescriptor)`,
291 * where `resultDescriptor` has type [resultDescriptorType], and we pass the 262 * where `resultDescriptor` has type [resultDescriptorType], and we pass the
292 * corresponding result descriptor names to [callback]. 263 * corresponding result descriptor names to [callback].
293 */ 264 */
294 class ExtensionFinder extends GeneralizingAstVisitor { 265 class ExtensionFinder extends GeneralizingAstVisitor {
295 final InterfaceType resultDescriptorType; 266 final InterfaceType resultDescriptorType;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 @override 309 @override
339 visitIdentifier(Identifier node) { 310 visitIdentifier(Identifier node) {
340 Element element = node.staticElement; 311 Element element = node.staticElement;
341 if (element is PropertyAccessorElement && 312 if (element is PropertyAccessorElement &&
342 element.isGetter && 313 element.isGetter &&
343 element.returnType.isSubtypeOf(type)) { 314 element.returnType.isSubtypeOf(type)) {
344 callback(element); 315 callback(element);
345 } 316 }
346 } 317 }
347 } 318 }
OLDNEW
« no previous file with comments | « pkg/analyzer/tool/task_dependency_graph/check_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698