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

Side by Side Diff: pkg/front_end/lib/src/incremental/unlinked_unit.dart

Issue 2939823002: Extract computing UnlinkedUnit(s) and cache them in ByteStore. (Closed)
Patch Set: Created 3 years, 6 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2017, 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 import 'dart:typed_data';
6
7 import 'package:front_end/src/base/api_signature.dart';
8 import 'package:front_end/src/fasta/parser/listener.dart' show Listener;
9 import 'package:front_end/src/fasta/parser/parser.dart' show Parser, optional;
10 import 'package:front_end/src/fasta/parser/top_level_parser.dart';
11 import 'package:front_end/src/fasta/scanner.dart';
12 import 'package:front_end/src/fasta/scanner/token_constants.dart'
13 show STRING_TOKEN;
14 import 'package:front_end/src/fasta/source/directive_listener.dart';
15 import 'package:front_end/src/incremental/format.dart';
16
17 /// Compute the [UnlinkedUnitBuilder] for the [content].
18 UnlinkedUnitBuilder computeUnlinkedUnit(List<int> salt, List<int> content) {
19 // Scan the content.
20 ScannerResult scanResult = _scan(content);
21 Token token = scanResult.tokens;
22
23 // Parse directives.
24 var listener = new DirectiveListener();
25 new TopLevelParser(listener).parseUnit(token);
Paul Berry 2017/06/13 21:49:46 It seems wasteful that we call `parseUnit` here an
scheglov 2017/06/13 22:03:21 Well, yes, we waste something. But in general TopL
26
27 // Parse to record function bodies.
28 var parser = new _BodySkippingParser();
29 parser.parseUnit(token);
30
31 ApiSignature apiSignature = new ApiSignature();
32 apiSignature.addBytes(salt);
33
34 // Iterate over tokens and skip bodies.
35 Iterator<_BodyRange> bodyIterator = parser.bodyRanges.iterator;
36 bodyIterator.moveNext();
37 for (; token.kind != EOF_TOKEN; token = token.next) {
38 // Move to the body range that ends after the token.
39 while (bodyIterator.current != null &&
40 bodyIterator.current.last < token.charOffset) {
41 bodyIterator.moveNext();
42 }
43 // If the current body range starts before or at the token, skip it.
44 if (bodyIterator.current != null &&
45 bodyIterator.current.first <= token.charOffset) {
46 continue;
47 }
48 // The token is outside of a function body, add it.
49 apiSignature.addString(token.lexeme);
50 }
51
52 return new UnlinkedUnitBuilder(
53 apiSignature: apiSignature.toByteList(),
54 imports: listener.imports.map(_toUnlinkedNamespaceDirective).toList(),
55 exports: listener.exports.map(_toUnlinkedNamespaceDirective).toList(),
56 parts: listener.parts.toList(),
57 hasMixinApplication: parser.hasMixin);
58 }
59
60 /// Exclude all `native 'xyz';` token sequences.
61 void _excludeNativeClauses(Token token) {
Paul Berry 2017/06/13 21:49:46 This seems like an unnecessarily fragile hack. Ca
scheglov 2017/06/13 22:03:21 Unfortunately my understanding is that position of
Paul Berry 2017/06/14 12:20:52 Ok, I will have a discussion with Peter about this
Siggi Cherem (dart-lang) 2017/06/14 22:37:38 FWIW - in our perf scripts we take the other appro
scheglov 2017/06/14 23:20:34 OK, I see how this is done for parsing directives.
62 for (; token.kind != EOF_TOKEN; token = token.next) {
63 if (optional('native', token) &&
64 token.next.kind == STRING_TOKEN &&
65 optional(';', token.next.next)) {
66 token.previous.next = token.next.next;
67 }
68 }
69 }
70
71 /// Scan the content of the file.
72 ScannerResult _scan(List<int> content) {
73 var zeroTerminatedBytes = new Uint8List(content.length + 1);
74 zeroTerminatedBytes.setRange(0, content.length, content);
75 ScannerResult result = scan(zeroTerminatedBytes);
76 _excludeNativeClauses(result.tokens);
77 return result;
78 }
79
80 /// Convert [NamespaceCombinator] into [UnlinkedCombinatorBuilder].
81 UnlinkedCombinatorBuilder _toUnlinkedCombinator(NamespaceCombinator c) =>
82 new UnlinkedCombinatorBuilder(isShow: c.isShow, names: c.names.toList());
83
84 /// Convert [NamespaceDirective] into [UnlinkedNamespaceDirectiveBuilder].
85 UnlinkedNamespaceDirectiveBuilder _toUnlinkedNamespaceDirective(
86 NamespaceDirective directive) =>
87 new UnlinkedNamespaceDirectiveBuilder(
88 uri: directive.uri,
89 combinators: directive.combinators.map(_toUnlinkedCombinator).toList());
90
91 /// The char range of a function body.
92 class _BodyRange {
93 /// The char offset of the first token in the range.
94 final int first;
95
96 /// The char offset of the last token in the range.
97 final int last;
98
99 _BodyRange(this.first, this.last);
100
101 @override
102 String toString() => '[$first, $last]';
103 }
104
105 /// The [Parser] that skips function bodies and remembers their token ranges.
106 class _BodySkippingParser extends Parser {
107 bool hasMixin = false;
108 final List<_BodyRange> bodyRanges = [];
109
110 _BodySkippingParser() : super(new Listener());
111
112 @override
113 Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
ahe 2017/08/07 14:05:13 This feature is already provided by ClassMemberPar
114 if (identical('{', token.lexeme)) {
115 Token close = skipBlock(token);
116 bodyRanges.add(new _BodyRange(token.charOffset, close.charOffset));
117 return close;
118 }
119 return super.parseFunctionBody(token, isExpression, allowAbstract);
120 }
121
122 Token parseMixinApplication(Token token) {
ahe 2017/08/07 14:05:13 You should be able to collect this information via
123 hasMixin = true;
124 return super.parseMixinApplication(token);
125 }
126 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/incremental/file_state.dart ('k') | pkg/front_end/lib/src/incremental_kernel_generator_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698