X Tutup
Skip to content

Commit f80321f

Browse files
author
Tim Blasi
committed
feat(dart/transform): Bail early for files with no deferred libraries
In `DeferredRewriter` if we can determine that there are no `deferred` libraries imported, bail early to avoid parsing the entire file.
1 parent 8f91ff8 commit f80321f

File tree

2 files changed

+39
-22
lines changed

2 files changed

+39
-22
lines changed

modules_dart/transform/lib/src/transform/deferred_rewriter/rewriter.dart

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,62 @@ import 'package:quiver/iterables.dart' as it;
1414
class Rewriter {
1515
final AssetId _entryPoint;
1616
final AssetReader _reader;
17+
final _FindDeferredLibraries _visitor;
1718

18-
Rewriter(this._entryPoint, this._reader);
19+
Rewriter(AssetId entryPoint, AssetReader reader)
20+
: _entryPoint = entryPoint,
21+
_reader = reader,
22+
_visitor = new _FindDeferredLibraries(reader, entryPoint);
1923

20-
/// Rewrites the provided code by finding all the deferred library imports
21-
/// and loadLibrary invocations. Then it removes any libraries that don't
22-
/// require angular codegen. For the remaining libraries it rewrites the
23-
/// import to the corresponding ng_dep file, and chains a future which
24-
/// first initializes the library.
24+
/// Rewrites `loadLibrary` calls to initialize libraries once loaded.
25+
///
26+
/// 1. Finds all the deferred library imports and loadLibrary invocations in
27+
/// `_entryPoint`
28+
/// 2. Removes any libraries that don't require angular codegen.
29+
/// 3. For the remaining libraries, rewrites the import to the corresponding
30+
/// `ng_deps.dart` file.
31+
/// 4. Chains a future to the `loadLibrary` call which initializes the
32+
/// library.
2533
///
2634
/// To the extent possible, this method does not change line numbers or
2735
/// offsets in the provided code to facilitate debugging via source maps.
2836
Future<String> rewrite() async {
2937
var code = await _reader.readAsString(_entryPoint);
30-
var node = parseCompilationUnit(code);
38+
39+
// If we can determine there are no deferred libraries, avoid parsing the
40+
// entire file and bail early.
41+
var onlyDirectives = parseDirectives(code, name: _entryPoint.path);
42+
if (onlyDirectives == null) return null;
43+
onlyDirectives.directives.accept(_visitor);
44+
if (_visitor.deferredImports.isEmpty) return null;
45+
46+
var node = parseCompilationUnit(code, name: _entryPoint.path);
3147
if (node == null) return null;
3248

3349
return logElapsedAsync(() async {
34-
var visitor = new _FindDeferredLibraries(_reader, _entryPoint);
35-
node.accept(visitor);
50+
node.declarations.accept(_visitor);
3651
// Look to see if we found any deferred libraries
37-
if (!visitor.hasDeferredLibrariesToRewrite()) return null;
52+
if (!_visitor.hasDeferredLibrariesToRewrite()) return null;
3853
// Remove any libraries that don't need angular codegen.
39-
await visitor.cull();
54+
await _visitor.cull();
4055
// Check again if there are any deferred libraries.
41-
if (!visitor.hasDeferredLibrariesToRewrite()) return null;
56+
if (!_visitor.hasDeferredLibrariesToRewrite()) return null;
4257

4358
var compare = (AstNode a, AstNode b) => a.offset - b.offset;
44-
visitor.deferredImports.sort(compare);
45-
visitor.loadLibraryInvocations.sort(compare);
59+
_visitor.deferredImports.sort(compare);
60+
_visitor.loadLibraryInvocations.sort(compare);
4661

4762
var buf = new StringBuffer();
4863
var idx =
49-
visitor.deferredImports.fold(0, (int lastIdx, ImportDirective node) {
64+
_visitor.deferredImports.fold(0, (int lastIdx, ImportDirective node) {
5065
buf.write(code.substring(lastIdx, node.offset));
5166

5267
var import = code.substring(node.offset, node.end);
5368
buf.write(import.replaceFirst('.dart', DEPS_EXTENSION));
5469
return node.end;
5570
});
5671

57-
idx = visitor.loadLibraryInvocations.fold(idx,
72+
idx = _visitor.loadLibraryInvocations.fold(idx,
5873
(int lastIdx, MethodInvocation node) {
5974
buf.write(code.substring(lastIdx, node.offset));
6075
var value = node.realTarget as SimpleIdentifier;

modules_dart/transform/test/transform/deferred_rewriter/all_tests.dart

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ void _testRewriteDeferredLibraries(String name, String inputPath) {
4444
path.dirname(inputPath), 'expected', path.basename(inputPath));
4545
var expectedId = _assetIdForPath(expectedPath);
4646

47-
var output = await rewriteDeferredLibraries(reader, inputId);
48-
var input = await reader.readAsString(expectedId);
49-
if (input == null) {
50-
// Null input signals no output. Ensure that is true.
51-
expect(output).toBeNull();
47+
var actualOutput = await rewriteDeferredLibraries(reader, inputId);
48+
var expectedOutput = await reader.readAsString(expectedId);
49+
if (expectedOutput == null) {
50+
// Null expectedOutput signals no output. Ensure that is true.
51+
expect(actualOutput).toBeNull();
5252
} else {
53-
expect(formatter.format(output)).toEqual(formatter.format(input));
53+
expect(actualOutput).toBeNotNull();
54+
expect(formatter.format(actualOutput))
55+
.toEqual(formatter.format(expectedOutput));
5456
}
5557
}, log: new RecordingLogger());
5658
});

0 commit comments

Comments
 (0)
X Tutup