Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit efb530a

Browse files
add new options to cli
1 parent 661e9b8 commit efb530a

File tree

2 files changed

+66
-14
lines changed

2 files changed

+66
-14
lines changed

tools/const_finder/bin/main.dart

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,46 @@ void main(List<String> args) {
5555
..addFlag('help',
5656
abbr: 'h',
5757
negatable: false,
58-
help: 'Print usage and exit');
58+
help: 'Print usage and exit')
59+
..addMultiOption('ignored-class-name',
60+
help: 'The name of a class whose containing constant instances that '
61+
'should not be retained. This is useful in situations--such as '
62+
'the web--where unused constants are not tree shaken from dill '
63+
'files.\n\nNote: each provided class name must pair with an '
64+
'invocation of "--ignored-class-library-uri" and appear in the '
65+
'same order.',
66+
valueHelp: 'Icons')
67+
..addMultiOption('ignored-class-library-uri',
68+
help: 'The package: URI of a class to ignore.\n\nNote: each provided '
69+
'class name must pair with an invocation of '
70+
'"--ignored-class-name" and appear in the same order.',
71+
valueHelp: 'package:flutter/src/material/icons.dart');
5972

6073
final ArgResults argResults = parser.parse(args);
61-
T getArg<T>(String name) => argResults[name] as T;
74+
T getArg<T>(String name) {
75+
try {
76+
return argResults[name] as T;
77+
} catch (err) {
78+
stderr.writeln('Parsing error trying to parse the argument "$name"');
79+
rethrow;
80+
}
81+
}
6282

6383
if (getArg<bool>('help')) {
6484
stdout.writeln(parser.usage);
6585
exit(0);
6686
}
6787

88+
final List<List<String>> ignoredClasses = _pairIgnoredClassNamesAndUris(
89+
getArg<Object?>('ignored-class-name'),
90+
getArg<Object?>('ignored-class-library-uri'),
91+
);
92+
6893
final ConstFinder finder = ConstFinder(
6994
kernelFilePath: getArg<String>('kernel-file'),
7095
classLibraryUri: getArg<String>('class-library-uri'),
7196
className: getArg<String>('class-name'),
97+
ignoredClasses: ignoredClasses,
7298
);
7399

74100
final JsonEncoder encoder = getArg<bool>('pretty')
@@ -77,3 +103,38 @@ void main(List<String> args) {
77103

78104
stdout.writeln(encoder.convert(finder.findInstances()));
79105
}
106+
107+
List<List<String>> _pairIgnoredClassNamesAndUris(Object? names, Object? uris) {
108+
// If the user provided neither option then we will not ignore any classes.
109+
if (names == null && uris == null) {
110+
return const <List<String>>[];
111+
}
112+
// If the user provided one of the options but not the other, than this is a
113+
// error!
114+
if (names == null || uris == null) {
115+
stderr.writeln(
116+
'To ignore specific classes, both "--ignored-class-name" AND '
117+
'"--ignored-class-library-uri" must be provided in order to uniquely '
118+
'identify the class.',
119+
);
120+
exit(1);
121+
}
122+
123+
names = names as List<String>;
124+
uris = uris as List<String>;
125+
final List<List<String>> pairs = <List<String>>[];
126+
127+
if (names.length != uris.length) {
128+
stderr.writeln(
129+
'"--ignored-class-name" was provided ${names.length} time(s) but '
130+
'"--ignored-class-library-uri" was provided ${uris.length} time(s). '
131+
'Each ignored class name must be paired with exactly one ignored class '
132+
'library uri, provided in the same order.',
133+
);
134+
exit(1);
135+
}
136+
for (int i = 0; i < names.length; i++) {
137+
pairs.add(<String>[uris[i], names[i]]);
138+
}
139+
return pairs;
140+
}

tools/const_finder/lib/const_finder.dart

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class _ConstVisitor extends RecursiveVisitor<void> {
9999
@override
100100
void visitInstanceConstantReference(InstanceConstant node) {
101101
super.visitInstanceConstantReference(node);
102-
if (!_matches(node.classNode)) {
102+
if (!_matches(node.classNode) || inIgnoredClass) {
103103
return;
104104
}
105105

@@ -111,20 +111,12 @@ class _ConstVisitor extends RecursiveVisitor<void> {
111111
final PrimitiveConstant<dynamic> value = kvp.value as PrimitiveConstant<dynamic>;
112112
instance[kvp.key.asField.name.text] = value.value;
113113
}
114-
if (!inIgnoredClass) {
115-
if (_visitedInstances.add(instance.toString())) {
116-
if (instance['stringValue'] == 'unused1') {
117-
throw 'whoops';
118-
}
119-
constantInstances.add(instance);
120-
}
114+
if (_visitedInstances.add(instance.toString())) {
115+
constantInstances.add(instance);
121116
}
122117
}
123118
}
124119

125-
/// For debugging.
126-
Library? lastLibrary;
127-
128120
/// A kernel AST visitor that finds const references.
129121
class ConstFinder {
130122
/// Creates a new ConstFinder class. All arguments are required and must not
@@ -149,7 +141,6 @@ class ConstFinder {
149141
Map<String, dynamic> findInstances() {
150142
_visitor._visitedInstances.clear();
151143
for (final Library library in loadComponentFromBinary(_visitor.kernelFilePath).libraries) {
152-
lastLibrary = library;
153144
library.visitChildren(_visitor);
154145
}
155146
return <String, dynamic>{

0 commit comments

Comments
 (0)