-
Notifications
You must be signed in to change notification settings - Fork 12
/
widget_surveyor.dart
88 lines (71 loc) 路 2.15 KB
/
widget_surveyor.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:surveyor/src/analysis.dart';
import 'package:surveyor/src/driver.dart';
import 'package:surveyor/src/visitors.dart';
/// Gathers and displays widget 2-grams.
///
/// Run like so:
///
/// dart bin/widget_surveyor.dart <source dir>
main(List<String> args) async {
var driver = Driver.forArgs(args);
driver.visitor = WidgetCollector();
await driver.analyze();
}
class TwoGram implements Comparable<TwoGram> {
String parent;
String child;
TwoGram(DartType parent, DartType child)
: parent = parent?.name ?? 'null',
child = child?.name ?? 'null';
@override
int get hashCode => child.hashCode * 13 + parent.hashCode;
@override
bool operator ==(other) =>
other is TwoGram && other.child == child && other.parent == parent;
@override
int compareTo(TwoGram other) =>
child.compareTo(other.child) * 2 + parent.compareTo(other.parent);
@override
String toString() => '$child->$parent';
}
class TwoGrams {
Map<TwoGram, int> map = <TwoGram, int>{};
void add(TwoGram twoGram) {
map.update(twoGram, (v) => v + 1, ifAbsent: () => 1);
}
@override
String toString() {
var sb = StringBuffer();
for (var entry in map.entries.toList()
..sort((a, b) => a.key.compareTo(b.key))) {
sb.writeln('${entry.key} : ${entry.value}');
}
return sb.toString();
}
}
class WidgetCollector extends RecursiveAstVisitor implements PostVisitCallback {
TwoGrams twoGrams = TwoGrams();
DartType previousEnclosingWidget;
DartType enclosingWidget;
@override
void onVisitFinished() {
print('2 Grams:');
print(twoGrams);
}
@override
visitInstanceCreationExpression(InstanceCreationExpression node) {
final type = node.staticType;
if (isWidgetType(type)) {
twoGrams.add(TwoGram(enclosingWidget, type));
previousEnclosingWidget = enclosingWidget;
enclosingWidget = type;
}
// Visit children.
super.visitInstanceCreationExpression(node);
// Reset parent.
enclosingWidget = previousEnclosingWidget;
}
}