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

Unified Diff: pkg/analyzer/tool/task_dependency_graph.dart

Issue 1408743006: Rework task model graphing to work on buildbots. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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/tool/task_dependency_graph/check_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/tool/task_dependency_graph.dart
diff --git a/pkg/analyzer/tool/task_dependency_graph.dart b/pkg/analyzer/tool/task_dependency_graph.dart
deleted file mode 100644
index ec28f5213b7825591388e306b8fa958a291faee6..0000000000000000000000000000000000000000
--- a/pkg/analyzer/tool/task_dependency_graph.dart
+++ /dev/null
@@ -1,297 +0,0 @@
-// 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.
-
-/**
- * This file contains code to output a description of tasks and their
- * dependencies in ".dot" format. Prior to running, the user should run "pub
- * get" in the analyzer directory to ensure that a "packages" folder exists.
- *
- * The ".dot" file is output to standard out. To convert it to a pdf, store it
- * in a file (e.g. "tasks.dot"), and post-process it with
- * "dot tasks.dot -Tpdf -O".
- *
- * TODO(paulberry):
- * - Add general.dart and html.dart for completeness.
- * - Use Graphviz's "record" feature to produce more compact output
- * (http://www.graphviz.org/content/node-shapes#record)
- * - Produce a warning if a result descriptor is found which isn't the output
- * of exactly one task.
- * - Convert this tool to use package_config to find the package map.
- */
-library task_dependency_graph;
-
-import 'dart:io' hide File;
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:path/path.dart' as path;
-
-main() {
- new Driver().run();
-}
-
-typedef void GetterFinderCallback(PropertyAccessorElement element);
-
-class Driver {
- PhysicalResourceProvider resourceProvider;
- AnalysisContext context;
- InterfaceType resultDescriptorType;
- InterfaceType listOfResultDescriptorType;
- ClassElement enginePluginClass;
- CompilationUnitElement taskUnitElement;
- InterfaceType extensionPointIdType;
- String rootDir;
-
- /**
- * Starting at [node], find all calls to registerExtension() which refer to
- * the given [extensionIdVariable], and execute [callback] for the associated
- * result descriptors.
- */
- void findExtensions(AstNode node, TopLevelVariableElement extensionIdVariable,
- void callback(descriptorName)) {
- Set<PropertyAccessorElement> resultDescriptors =
- new Set<PropertyAccessorElement>();
- node.accept(new ExtensionFinder(
- resultDescriptorType, extensionIdVariable, resultDescriptors.add));
- for (PropertyAccessorElement resultDescriptor in resultDescriptors) {
- callback(resultDescriptor.name);
- }
- }
-
- /**
- * Starting at [node], find all references to a getter of type
- * `List<ResultDescriptor>`, and execute [callback] on the getter names.
- */
- void findResultDescriptorLists(
- AstNode node, void callback(String descriptorListName)) {
- Set<PropertyAccessorElement> resultDescriptorLists =
- new Set<PropertyAccessorElement>();
- node.accept(new GetterFinder(
- listOfResultDescriptorType, resultDescriptorLists.add));
- for (PropertyAccessorElement resultDescriptorList
- in resultDescriptorLists) {
- // We only care about result descriptor lists associated with getters in
- // the engine plugin class.
- if (resultDescriptorList.enclosingElement != enginePluginClass) {
- continue;
- }
- callback(resultDescriptorList.name);
- }
- }
-
- void findResultDescriptors(
- AstNode node, void callback(String descriptorName)) {
- Set<PropertyAccessorElement> resultDescriptors =
- new Set<PropertyAccessorElement>();
- node.accept(new GetterFinder(resultDescriptorType, resultDescriptors.add));
- for (PropertyAccessorElement resultDescriptor in resultDescriptors) {
- callback(resultDescriptor.name);
- }
- }
-
- /**
- * Find the root directory of the analyzer package by proceeding
- * upward to the 'tool' dir, and then going up one more directory.
- */
- String findRoot(String pathname) {
- while (path.basename(pathname) != 'tool') {
- String parent = path.dirname(pathname);
- if (parent.length >= pathname.length) {
- throw new Exception("Can't find root directory");
- }
- pathname = parent;
- }
- return path.dirname(pathname);
- }
-
- CompilationUnit getUnit(Source source) =>
- context.resolveCompilationUnit2(source, source);
-
- void run() {
- rootDir = findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
- resourceProvider = PhysicalResourceProvider.INSTANCE;
- DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
- context = AnalysisEngine.instance.createAnalysisContext();
- JavaFile packagesDir = new JavaFile(path.join(rootDir, 'packages'));
- List<UriResolver> uriResolvers = [
- new DartUriResolver(sdk),
- new PackageUriResolver(<JavaFile>[packagesDir]),
- new FileUriResolver()
- ];
- context.sourceFactory = new SourceFactory(uriResolvers);
- Source dartDartSource =
- setupSource(path.join('lib', 'src', 'task', 'dart.dart'));
- Source taskSource = setupSource(path.join('lib', 'plugin', 'task.dart'));
- Source modelSource = setupSource(path.join('lib', 'task', 'model.dart'));
- Source enginePluginSource =
- setupSource(path.join('lib', 'src', 'plugin', 'engine_plugin.dart'));
- CompilationUnitElement modelElement = getUnit(modelSource).element;
- InterfaceType analysisTaskType = modelElement.getType('AnalysisTask').type;
- DartType dynamicType = context.typeProvider.dynamicType;
- resultDescriptorType = modelElement
- .getType('ResultDescriptor')
- .type
- .substitute4([dynamicType]);
- listOfResultDescriptorType =
- context.typeProvider.listType.substitute4([resultDescriptorType]);
- CompilationUnitElement enginePluginUnitElement =
- getUnit(enginePluginSource).element;
- enginePluginClass = enginePluginUnitElement.getType('EnginePlugin');
- extensionPointIdType =
- enginePluginUnitElement.getType('ExtensionPointId').type;
- CompilationUnit dartDartUnit = getUnit(dartDartSource);
- CompilationUnitElement dartDartUnitElement = dartDartUnit.element;
- CompilationUnit taskUnit = getUnit(taskSource);
- taskUnitElement = taskUnit.element;
- print('digraph G {');
- Set<String> results = new Set<String>();
- Set<String> resultLists = new Set<String>();
- for (ClassElement cls in dartDartUnitElement.types) {
- if (!cls.isAbstract && cls.type.isSubtypeOf(analysisTaskType)) {
- String task = cls.name;
- // TODO(paulberry): node is deprecated. What am I supposed to do
- // instead?
- AstNode buildInputsAst = cls.getMethod('buildInputs').node;
- findResultDescriptors(buildInputsAst, (String input) {
- results.add(input);
- print(' $input -> $task');
- });
- findResultDescriptorLists(buildInputsAst, (String input) {
- resultLists.add(input);
- print(' $input -> $task');
- });
- findResultDescriptors(cls.getField('DESCRIPTOR').node, (String output) {
- results.add(output);
- print(' $task -> $output');
- });
- }
- }
- AstNode enginePluginAst = enginePluginUnitElement.node;
- for (String resultList in resultLists) {
- print(' $resultList [shape=hexagon]');
- TopLevelVariableElement extensionIdVariable = _getExtensionId(resultList);
- findExtensions(enginePluginAst, extensionIdVariable, (String extension) {
- results.add(extension);
- print(' $extension -> $resultList');
- });
- }
- for (String result in results) {
- print(' $result [shape=box]');
- }
- print('}');
- }
-
- Source setupSource(String filename) {
- String filePath = path.join(rootDir, filename);
- File file = resourceProvider.getResource(filePath);
- Source source = file.createSource();
- Uri restoredUri = context.sourceFactory.restoreUri(source);
- if (restoredUri != null) {
- source = file.createSource(restoredUri);
- }
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- context.applyChanges(changeSet);
- return source;
- }
-
- /**
- * Find the result list getter having name [resultListGetterName] in the
- * [EnginePlugin] class, and use the [ExtensionPointId] annotation on that
- * getter to find the associated [TopLevelVariableElement] which can be used
- * to register extensions for that getter.
- */
- TopLevelVariableElement _getExtensionId(String resultListGetterName) {
- PropertyAccessorElement getter =
- enginePluginClass.getGetter(resultListGetterName);
- for (ElementAnnotation annotation in getter.metadata) {
- // TODO(paulberry): we should be using part of the public API rather than
- // just casting to ElementAnnotationImpl.
- ElementAnnotationImpl annotationImpl = annotation;
- DartObjectImpl annotationValue = annotationImpl.evaluationResult.value;
- if (annotationValue.type.isSubtypeOf(extensionPointIdType)) {
- String extensionPointId =
- annotationValue.fields['extensionPointId'].value;
- for (TopLevelVariableElement variable
- in taskUnitElement.topLevelVariables) {
- if (variable.name == extensionPointId) {
- return variable;
- }
- }
- }
- }
- throw new Exception(
- 'Could not find extension ID corresponding to $resultListGetterName');
- }
-}
-
-/**
- * Visitor that finds calls that register extension points. Specifically, we
- * look for calls of the form `method(extensionIdVariable, resultDescriptor)`,
- * where `resultDescriptor` has type [resultDescriptorType], and we pass the
- * corresponding result descriptor names to [callback].
- */
-class ExtensionFinder extends GeneralizingAstVisitor {
- final InterfaceType resultDescriptorType;
- final TopLevelVariableElement extensionIdVariable;
- final GetterFinderCallback callback;
-
- ExtensionFinder(
- this.resultDescriptorType, this.extensionIdVariable, this.callback);
-
- @override
- visitIdentifier(Identifier node) {
- Element element = node.staticElement;
- if (element is PropertyAccessorElement &&
- element.isGetter &&
- element.variable == extensionIdVariable) {
- AstNode parent = node.parent;
- if (parent is ArgumentList &&
- parent.arguments.length == 2 &&
- parent.arguments[0] == node) {
- Expression extension = parent.arguments[1];
- if (extension is Identifier) {
- Element element = extension.staticElement;
- if (element is PropertyAccessorElement &&
- element.isGetter &&
- element.returnType.isSubtypeOf(resultDescriptorType)) {
- callback(element);
- return;
- }
- }
- }
- throw new Exception('Could not decode extension setup: $parent');
- }
- }
-}
-
-/**
- * Visitor that finds references to getters having a specific type (or a
- * subtype of that type)
- */
-class GetterFinder extends GeneralizingAstVisitor {
- final InterfaceType type;
- final GetterFinderCallback callback;
-
- GetterFinder(this.type, this.callback);
-
- @override
- visitIdentifier(Identifier node) {
- Element element = node.staticElement;
- if (element is PropertyAccessorElement &&
- element.isGetter &&
- element.returnType.isSubtypeOf(type)) {
- callback(element);
- }
- }
-}
« no previous file with comments | « no previous file | pkg/analyzer/tool/task_dependency_graph/check_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698