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

Unified Diff: tools/dom/tools/api_diff.dart

Issue 14750010: Adding utility to display API differences between dart2js and dartium DOM libraries. Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 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 | « pkg/analyzer_experimental/lib/src/generated/constant.dart ('k') | tools/dom/tools/dummy.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/dom/tools/api_diff.dart
diff --git a/tools/dom/tools/api_diff.dart b/tools/dom/tools/api_diff.dart
new file mode 100644
index 0000000000000000000000000000000000000000..5ff1a583346b3d5ce5b84ec1ec909c98141af8f5
--- /dev/null
+++ b/tools/dom/tools/api_diff.dart
@@ -0,0 +1,259 @@
+// Copyright (c) 2013, 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.
+
+/**
+ * Utility for displaying the public API difference between two different
+ * libraries.
+ *
+ * This is intended to display divergence between html_dart2js and html_dartium.
+ */
+library api_diff;
+
+import 'dart:io';
+import '../../../pkg/analyzer_experimental/lib/src/generated/ast.dart';
+import '../../../pkg/analyzer_experimental/lib/src/generated/element.dart';
+import '../../../pkg/analyzer_experimental/lib/src/generated/engine.dart';
+import '../../../pkg/analyzer_experimental/lib/src/generated/java_io.dart';
+import '../../../pkg/analyzer_experimental/lib/src/generated/sdk.dart' show DartSdk;
+import '../../../pkg/analyzer_experimental/lib/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
+import '../../../pkg/analyzer_experimental/lib/src/generated/source_io.dart';
+import '../../../pkg/args/lib/args.dart';
+
+void main() {
+ final args = new Options().arguments;
+
+ var parser = new ArgParser();
+ parser.addOption('a',
+ help: 'file a',
+ defaultsTo: '../../../sdk/lib/html/dart2js/html_dart2js.dart');
+ parser.addOption('b',
+ help: 'file b',
+ defaultsTo: '../../../sdk/lib/html/dartium/html_dartium.dart');
+
+ parser.addOption('path_to_sdk',
+ help: 'Path to the Dart SDK',
+ defaultsTo: '../../../sdk/');
+
+ void showUsage(parser) {
+ print('Usage: api_diff [options...]');
+ print(parser.getUsage());
+ }
+
+ try {
+ var results = parser.parse(args);
+
+ var diffs = diff(results['path_to_sdk'], results['a'], results['b']);
+ for (var diff in diffs) {
+ print(diff);
+ }
+ } on FormatException catch (e) {
+ print(e);
+ showUsage(parser);
+ exit(1);
+ }
+}
+
+List<String> diff(String sdkDir, String pathA, String pathB) {
+ var sdkPath = new Path(Directory.current.path)
+ .join(new Path(sdkDir))
+ .canonicalize()
+ .toString();
+
+ JavaSystemIO.setProperty("com.google.dart.sdk", sdkPath);
+ var dartSdk = DirectoryBasedDartSdk.defaultSdk;
+
+ var libraryA = _openLibrary(dartSdk, pathA);
+ var libraryB = _openLibrary(dartSdk, pathB);
+ var client = _openLibrary(dartSdk, 'dummy.dart').enclosingElement;
+
+ var context = new _DiffContext(libraryA, libraryB, client);
+ context.run();
+
+ return context.diffs;
+}
+
+Element openLibrary(DartSdk sdk, String libraryFile) {
+ AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+ context.sourceFactory =
+ new SourceFactory.con2([new DartUriResolver(sdk), new FileUriResolver()]);
+ var source = new FileBasedSource.con1(
+ context.sourceFactory, new JavaFile(libraryFile));
+
+ var changeSet = new ChangeSet();
+ changeSet.added(source);
+ context.applyChanges(changeSet);
+ var libElement = context.computeLibraryElement(source);
+
+ var resolvedUnit = context.resolveCompilationUnit(source, libElement);
+
+ return resolvedUnit.element;
+}
+
+CompilationUnitElement _openLibrary(DartSdk sdk, String libraryFile) {
+ var context = AnalysisEngine.instance.createAnalysisContext();
+ context.sourceFactory =
+ new SourceFactory.con2([new DartUriResolver(sdk), new FileUriResolver()]);
+ var source = new FileBasedSource.con1(context.sourceFactory,
+ new JavaFile(libraryFile));
+
+ var changeSet = new ChangeSet();
+ changeSet.added(source);
+ context.applyChanges(changeSet);
+ var libElement = context.computeLibraryElement(source);
+
+ var resolvedUnit = context.resolveCompilationUnit(source, libElement);
+ return resolvedUnit.element;
+}
+
+class _DiffContext {
+ final CompilationUnitElement libraryA;
+ final CompilationUnitElement libraryB;
+ final LibraryElement client;
+ final List<Element> contextA = <Element>[];
+ final List<Element> contextB = <Element>[];
+ final List<String> diffs = <String>[];
+
+ _DiffContext(this.libraryA, this.libraryB, this.client) {
+ }
+
+ void run() {
+ diff(libraryA, libraryB);
+ }
+
+ void add(List<Element> context, String msg) {
+ var location = printContext(context);
+ diffs.add('$location: $msg');
+ }
+
+ String printContext(List<Element> context) {
+ var name = '';
+ for (var element in context) {
+ if (element is LibraryElement) {
+ name = element.name;
+ } else if (element is ClassElement) {
+ name = '$name:${element.name}';
+ } else if (element is CompilationUnitElement) {
+ name = element.name;
+ } else {
+ name = '$name.${element.name}';
+ }
+ }
+ return name;
+ }
+
+ void diff(Element a, Element b) {
+ if ((b != null && !b.isAccessibleIn(client)) ||
+ (a != null && !a.isAccessibleIn(client))) {
+ return;
+ }
+ if (a == null) {
+ if (b.kind == ElementKind.CONSTRUCTOR &&
+ (b.parameters.length == 0 || b.name != 'internal')) {
+ return;
+ }
+ add(contextA, 'missing ${b.kind.displayName} ${b.name}');
+ return;
+ } else if (b == null) {
+ if (a.kind == ElementKind.CONSTRUCTOR &&
+ (a.parameters.length == 0 || a.name != 'internal')) {
+ return;
+ }
+ add(contextB, 'missing ${a.kind.displayName} ${a.name}');
+ return;
+ }
+
+ if (a.kind != b.kind) {
+ add(contextA,
+ 'kinds differ (${a.kind.displayName}, ${a.kind.displayName}');
+ return;
+ }
+
+ contextA.add(a);
+ contextB.add(b);
+
+ if (a is ClassElement) {
+ diffClass(a, b);
+ } else if (a is CompilationUnitElement) {
+ diffCompilationUnits(a, b);
+ } else if (a is MethodElement) {
+ diffMethods(a, b);
+ } else if (a is FieldElement) {
+ diffFields(a, b);
+ } else if (a is ParameterElement) {
+ diffParameters(a, b);
+ } else if (a is ConstructorElement) {
+ diffConstructors(a, b);
+ } else if (a is FunctionElement) {
+ diffExecutables(a, b);
+ } else {
+ print('unknown type: ${a.kind}');
+ }
+
+ contextA.removeLast();
+ contextB.removeLast();
+ }
+
+ void diffLists(List<Element> a, List<Element> b) {
+ var allNames = new Set.from(a.map((e) => e.name)).union(
+ new Set.from(b.map((e) => e.name)));
+
+ for (var name in allNames) {
+ var elementA = getElement(a, name);
+ var elementB = getElement(b, name);
+
+ diff(elementA, elementB);
+ }
+ }
+
+ Element getElement(List<Element> elements, String name) {
+ return elements.firstWhere((e) => e.name == name,
+ orElse: () => null);
+ }
+
+ void diffCompilationUnits(CompilationUnitElement a,
+ CompilationUnitElement b) {
+ diffLists(a.types, b.types);
+
+ diffLists(a.topLevelVariables, b.topLevelVariables);
+ diffLists(a.functions, b.functions);
+ }
+
+ void diffClass(ClassElement a, ClassElement b) {
+ diffLists(a.fields, b.fields);
+ diffLists(a.methods, b.methods);
+ diffLists(a.constructors, b.constructors);
+ }
+
+ void diffExecutables(MethodElement a, MethodElement b) {
+ diffLists(a.parameters, b.parameters);
+ }
+
+ void diffMethods(MethodElement a, MethodElement b) {
+ diffExecutables(a, b);
+ }
+
+ void diffFields(FieldElement a, FieldElement b) {
+ }
+
+ void diffParameters(ParameterElement a, ParameterElement b) {
+ if (a.parameterKind != b.parameterKind) {
+ add(contextA, 'kinds differ (${a.parameterKind}, ${b.parameterKind})');
+ return;
+ }
+ if (a.type.toString() != b.type.toString()) {
+ add(contextA, 'types differ (${a.type}, ${b.type})');
+ return;
+ }
+ }
+
+ void diffConstructors(ConstructorElement a, ConstructorElement b) {
+ if (a.isConst() != b.isConst()) {
+ add(contextA, 'constness differ');
+ return;
+ }
+
+ diffExecutables(a, b);
+ }
+}
+
« no previous file with comments | « pkg/analyzer_experimental/lib/src/generated/constant.dart ('k') | tools/dom/tools/dummy.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698