Skip to content

Commit 6839e0d

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Migration: create a simple client of the migration API for early testing.
Change-Id: I889f7b80fdbb8dbddd8174812ddaca013cf272e3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112361 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent 3d9a356 commit 6839e0d

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
// This is a hacked-together client of the NNBD migration API, intended for
6+
// early testing of the migration process. It runs a small hardcoded set of
7+
// packages through the migration engine and outputs statistics about the
8+
// result of migration, as well as categories (and counts) of exceptions that
9+
// occurred.
10+
11+
import 'dart:io';
12+
13+
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
14+
import 'package:analyzer_plugin/protocol/protocol_common.dart';
15+
import 'package:nnbd_migration/nnbd_migration.dart';
16+
17+
main() async {
18+
var rootUri = Platform.script.resolve('../../..');
19+
var listener = _Listener();
20+
for (var testPath in [
21+
'third_party/pkg/charcode',
22+
'third_party/pkg/collection',
23+
'third_party/pkg/logging',
24+
'pkg/meta',
25+
'third_party/pkg/path',
26+
'third_party/pkg/term_glyph',
27+
// 'third_party/pkg/typed_data', - TODO(paulberry): fatal exception
28+
'third_party/pkg/async',
29+
'third_party/pkg/source_span',
30+
'third_party/pkg/stack_trace',
31+
'third_party/pkg/matcher',
32+
'third_party/pkg/stream_channel',
33+
'third_party/pkg/boolean_selector',
34+
'third_party/pkg/test/pkgs/test_api',
35+
]) {
36+
print('Migrating $testPath');
37+
var testUri = rootUri.resolve(testPath);
38+
var contextCollection =
39+
AnalysisContextCollection(includedPaths: [testUri.toFilePath()]);
40+
var context = contextCollection.contexts.single;
41+
var files = context.contextRoot
42+
.analyzedFiles()
43+
.where((s) => s.endsWith('.dart'))
44+
.toList();
45+
print(' ${files.length} files found');
46+
var migration = NullabilityMigration(listener, permissive: true);
47+
for (var file in files) {
48+
var resolvedUnit = await context.currentSession.getResolvedUnit(file);
49+
migration.prepareInput(resolvedUnit);
50+
}
51+
for (var file in files) {
52+
var resolvedUnit = await context.currentSession.getResolvedUnit(file);
53+
migration.processInput(resolvedUnit);
54+
}
55+
migration.finish();
56+
}
57+
print('${listener.numTypesMadeNullable} types made nullable');
58+
print('${listener.numNullChecksAdded} null checks added');
59+
print('${listener.numMetaImportsAdded} meta imports added');
60+
print('${listener.numRequiredAnnotationsAdded} required annotations added');
61+
print('${listener.numDeadCodeSegmentsFound} dead code segments found');
62+
print('${listener.numExceptions} exceptions in '
63+
'${listener.groupedExceptions.length} categories');
64+
print('Exception categories:');
65+
var sortedExceptions = listener.groupedExceptions.entries.toList();
66+
sortedExceptions.sort((e1, e2) => e2.value.length.compareTo(e1.value.length));
67+
for (var entry in sortedExceptions) {
68+
print(' ${entry.key} (x${entry.value.length})');
69+
}
70+
}
71+
72+
class _Listener implements NullabilityMigrationListener {
73+
final groupedExceptions = <String, List<String>>{};
74+
75+
int numExceptions = 0;
76+
77+
int numTypesMadeNullable = 0;
78+
79+
int numNullChecksAdded = 0;
80+
81+
int numMetaImportsAdded = 0;
82+
83+
int numRequiredAnnotationsAdded = 0;
84+
85+
int numDeadCodeSegmentsFound = 0;
86+
87+
@override
88+
void addDetail(String detail) {
89+
var breakLocation = detail.indexOf('\n\n');
90+
if (breakLocation == -1)
91+
throw StateError('Could not decode exception $detail');
92+
var stackTrace = detail.substring(breakLocation + 2).split('\n');
93+
var category = _classifyStackTrace(stackTrace);
94+
(groupedExceptions[category] ??= []).add(detail);
95+
++numExceptions;
96+
}
97+
98+
@override
99+
void addEdit(SingleNullabilityFix fix, SourceEdit edit) {
100+
if (edit.replacement == '?' && edit.length == 0) {
101+
++numTypesMadeNullable;
102+
} else if (edit.replacement == '!' && edit.length == 0) {
103+
++numNullChecksAdded;
104+
} else if (edit.replacement == "import 'package:meta/meta.dart';\n" &&
105+
edit.length == 0) {
106+
++numMetaImportsAdded;
107+
} else if (edit.replacement == '@required ' && edit.length == 0) {
108+
++numRequiredAnnotationsAdded;
109+
} else if ((edit.replacement == '/* ' ||
110+
edit.replacement == ' /*' ||
111+
edit.replacement == '; /*') &&
112+
edit.length == 0) {
113+
++numDeadCodeSegmentsFound;
114+
} else if ((edit.replacement == '*/ ' || edit.replacement == ' */') &&
115+
edit.length == 0) {
116+
// Already counted
117+
} else {
118+
print('addEdit($fix, $edit)');
119+
}
120+
}
121+
122+
@override
123+
void addFix(SingleNullabilityFix fix) {}
124+
125+
String _classifyStackTrace(List<String> stackTrace) {
126+
for (var entry in stackTrace) {
127+
if (entry.contains('EdgeBuilder._unimplemented')) continue;
128+
if (entry.contains('_AssertionError._doThrowNew')) continue;
129+
if (entry.contains('_AssertionError._throwNew')) continue;
130+
if (entry.contains('NodeBuilder._unimplemented')) continue;
131+
if (entry.contains('Object.noSuchMethod')) continue;
132+
if (entry.contains('List.[] (dart:core-patch/growable_array.dart')) {
133+
continue;
134+
}
135+
return entry;
136+
}
137+
return '???';
138+
}
139+
}

0 commit comments

Comments
 (0)