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

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

Issue 2928393004: Add FileState.hasMixin/hasMixinLibrary properties. (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
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:typed_data'; 6 import 'dart:typed_data';
7 7
8 import 'package:crypto/crypto.dart'; 8 import 'package:crypto/crypto.dart';
9 import 'package:front_end/file_system.dart'; 9 import 'package:front_end/file_system.dart';
10 import 'package:front_end/src/base/api_signature.dart'; 10 import 'package:front_end/src/base/api_signature.dart';
(...skipping 26 matching lines...) Expand all
37 37
38 /// The absolute URI of the file. 38 /// The absolute URI of the file.
39 final Uri uri; 39 final Uri uri;
40 40
41 /// The resolved URI of the file in the file system. 41 /// The resolved URI of the file in the file system.
42 final Uri fileUri; 42 final Uri fileUri;
43 43
44 bool _exists; 44 bool _exists;
45 List<int> _content; 45 List<int> _content;
46 List<int> _contentHash; 46 List<int> _contentHash;
47 bool _hasMixin;
47 List<int> _apiSignature; 48 List<int> _apiSignature;
48 49
49 List<NamespaceExport> _exports; 50 List<NamespaceExport> _exports;
50 List<FileState> _importedLibraries; 51 List<FileState> _importedLibraries;
51 List<FileState> _exportedLibraries; 52 List<FileState> _exportedLibraries;
52 List<FileState> _partFiles; 53 List<FileState> _partFiles;
53 54
54 Set<FileState> _directReferencedFiles = new Set<FileState>(); 55 Set<FileState> _directReferencedFiles = new Set<FileState>();
55 List<FileState> _directReferencedLibraries = <FileState>[]; 56 List<FileState> _directReferencedLibraries = <FileState>[];
56 57
(...skipping 21 matching lines...) Expand all
78 79
79 /// The list of the libraries exported by this library. 80 /// The list of the libraries exported by this library.
80 List<FileState> get exportedLibraries => _exportedLibraries; 81 List<FileState> get exportedLibraries => _exportedLibraries;
81 82
82 /// The list of the exported files with combinators. 83 /// The list of the exported files with combinators.
83 List<NamespaceExport> get exports => _exports; 84 List<NamespaceExport> get exports => _exports;
84 85
85 @override 86 @override
86 int get hashCode => uri.hashCode; 87 int get hashCode => uri.hashCode;
87 88
89 /// Whether the file has a mixin application.
90 bool get hasMixin => _hasMixin;
ahe 2017/06/12 19:22:03 Rename to hasMixinApplication? I think it's import
scheglov 2017/06/12 19:43:18 Yeah, I actually named it initially this way. But
91
92 /// Whether a unit of the library has a mixin application.
93 bool get hasMixinLibrary {
ahe 2017/06/12 19:22:03 hasMixinApplicationLibrary? But how about this: r
94 return _hasMixin || _partFiles.any((part) => part._hasMixin);
95 }
96
88 /// The list of the libraries imported by this library. 97 /// The list of the libraries imported by this library.
89 List<FileState> get importedLibraries => _importedLibraries; 98 List<FileState> get importedLibraries => _importedLibraries;
90 99
91 /// The list of files this library file references as parts. 100 /// The list of files this library file references as parts.
92 List<FileState> get partFiles => _partFiles; 101 List<FileState> get partFiles => _partFiles;
93 102
94 /// Return topologically sorted cycles of dependencies for this library. 103 /// Return topologically sorted cycles of dependencies for this library.
95 List<LibraryCycle> get topologicalOrder { 104 List<LibraryCycle> get topologicalOrder {
96 var libraryWalker = new _LibraryWalker(); 105 var libraryWalker = new _LibraryWalker();
97 libraryWalker.walk(libraryWalker.getNode(this)); 106 libraryWalker.walk(libraryWalker.getNode(this));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 _content = new Uint8List(0); 140 _content = new Uint8List(0);
132 _exists = false; 141 _exists = false;
133 } 142 }
134 143
135 // Compute the content hash. 144 // Compute the content hash.
136 _contentHash = md5.convert(_content).bytes; 145 _contentHash = md5.convert(_content).bytes;
137 146
138 // Scan the content. 147 // Scan the content.
139 ScannerResult scanResult = _scan(); 148 ScannerResult scanResult = _scan();
140 149
141 // Compute the API signature. 150 // Compute syntactic properties.
142 _apiSignature = _computeApiSignature(scanResult.tokens); 151 _computeSyntacticProperties(scanResult.tokens);
143 152
144 // Parse directives. 153 // Parse directives.
145 var listener = new _DirectiveListenerWithNative(); 154 var listener = new _DirectiveListenerWithNative();
146 new TopLevelParser(listener).parseUnit(scanResult.tokens); 155 new TopLevelParser(listener).parseUnit(scanResult.tokens);
147 156
148 // Build the graph. 157 // Build the graph.
149 _importedLibraries = <FileState>[]; 158 _importedLibraries = <FileState>[];
150 _exportedLibraries = <FileState>[]; 159 _exportedLibraries = <FileState>[];
151 _partFiles = <FileState>[]; 160 _partFiles = <FileState>[];
152 _exports = <NamespaceExport>[]; 161 _exports = <NamespaceExport>[];
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 if (uri.toString() != 'dart:core') return; 212 if (uri.toString() != 'dart:core') return;
204 for (String uri in new VmTarget(null).extraRequiredLibraries) { 213 for (String uri in new VmTarget(null).extraRequiredLibraries) {
205 FileState file = await _getFileForRelativeUri(uri); 214 FileState file = await _getFileForRelativeUri(uri);
206 // TODO(scheglov) add error handling 215 // TODO(scheglov) add error handling
207 if (file != null) { 216 if (file != null) {
208 _importedLibraries.add(file); 217 _importedLibraries.add(file);
209 } 218 }
210 } 219 }
211 } 220 }
212 221
213 /// Compute and return the API signature of the file. 222 /// Compute syntactic properties of the file: [_apiSignature] and [_hasMixin].
214 /// 223 ///
215 /// The signature is based on non-comment tokens of the file outside 224 /// The signature is based on non-comment tokens of the file outside
216 /// of function bodies. 225 /// of function bodies.
217 List<int> _computeApiSignature(Token token) { 226 void _computeSyntacticProperties(Token token) {
218 var parser = new _BodySkippingParser(); 227 var parser = new _BodySkippingParser();
219 parser.parseUnit(token); 228 parser.parseUnit(token);
220 229
230 _hasMixin = parser.hasMixin;
231
221 ApiSignature apiSignature = new ApiSignature(); 232 ApiSignature apiSignature = new ApiSignature();
222 apiSignature.addBytes(_fsState._salt); 233 apiSignature.addBytes(_fsState._salt);
223 234
224 // Iterate over tokens and skip bodies. 235 // Iterate over tokens and skip bodies.
225 Iterator<_BodyRange> bodyIterator = parser.bodyRanges.iterator; 236 Iterator<_BodyRange> bodyIterator = parser.bodyRanges.iterator;
226 bodyIterator.moveNext(); 237 bodyIterator.moveNext();
227 for (; token.kind != EOF_TOKEN; token = token.next) { 238 for (; token.kind != EOF_TOKEN; token = token.next) {
228 // Move to the body range that ends after the token. 239 // Move to the body range that ends after the token.
229 while (bodyIterator.current != null && 240 while (bodyIterator.current != null &&
230 bodyIterator.current.last < token.charOffset) { 241 bodyIterator.current.last < token.charOffset) {
231 bodyIterator.moveNext(); 242 bodyIterator.moveNext();
232 } 243 }
233 // If the current body range starts before or at the token, skip it. 244 // If the current body range starts before or at the token, skip it.
234 if (bodyIterator.current != null && 245 if (bodyIterator.current != null &&
235 bodyIterator.current.first <= token.charOffset) { 246 bodyIterator.current.first <= token.charOffset) {
236 continue; 247 continue;
237 } 248 }
238 // The token is outside of a function body, add it. 249 // The token is outside of a function body, add it.
239 apiSignature.addString(token.lexeme); 250 apiSignature.addString(token.lexeme);
240 } 251 }
241 252
242 return apiSignature.toByteList(); 253 // Store the API signature.
254 _apiSignature = apiSignature.toByteList();
243 } 255 }
244 256
245 /// Exclude all `native 'xyz';` token sequences. 257 /// Exclude all `native 'xyz';` token sequences.
246 void _excludeNativeClauses(Token token) { 258 void _excludeNativeClauses(Token token) {
247 for (; token.kind != EOF_TOKEN; token = token.next) { 259 for (; token.kind != EOF_TOKEN; token = token.next) {
248 if (optional('native', token) && 260 if (optional('native', token) &&
249 token.next.kind == STRING_TOKEN && 261 token.next.kind == STRING_TOKEN &&
250 optional(';', token.next.next)) { 262 optional(';', token.next.next)) {
251 token.previous.next = token.next.next; 263 token.previous.next = token.next.next;
252 } 264 }
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 final int last; 444 final int last;
433 445
434 _BodyRange(this.first, this.last); 446 _BodyRange(this.first, this.last);
435 447
436 @override 448 @override
437 String toString() => '[$first, $last]'; 449 String toString() => '[$first, $last]';
438 } 450 }
439 451
440 /// The [Parser] that skips function bodies and remembers their token ranges. 452 /// The [Parser] that skips function bodies and remembers their token ranges.
441 class _BodySkippingParser extends Parser { 453 class _BodySkippingParser extends Parser {
454 bool hasMixin = false;
442 final List<_BodyRange> bodyRanges = []; 455 final List<_BodyRange> bodyRanges = [];
443 456
444 _BodySkippingParser() : super(new Listener()); 457 _BodySkippingParser() : super(new Listener());
445 458
446 @override 459 @override
447 Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) { 460 Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
448 if (identical('{', token.lexeme)) { 461 if (identical('{', token.lexeme)) {
449 Token close = skipBlock(token); 462 Token close = skipBlock(token);
450 bodyRanges.add(new _BodyRange(token.charOffset, close.charOffset)); 463 bodyRanges.add(new _BodyRange(token.charOffset, close.charOffset));
451 return close; 464 return close;
452 } 465 }
453 return super.parseFunctionBody(token, isExpression, allowAbstract); 466 return super.parseFunctionBody(token, isExpression, allowAbstract);
454 } 467 }
468
469 Token parseMixinApplication(Token token) {
470 hasMixin = true;
471 return super.parseMixinApplication(token);
472 }
455 } 473 }
456 474
457 /// [DirectiveListener] that skips native clauses. 475 /// [DirectiveListener] that skips native clauses.
458 class _DirectiveListenerWithNative extends DirectiveListener { 476 class _DirectiveListenerWithNative extends DirectiveListener {
459 @override 477 @override
460 Token handleNativeClause(Token token) => skipNativeClause(token); 478 Token handleNativeClause(Token token) => skipNativeClause(token);
461 } 479 }
462 480
463 /// [FileSystemState] based implementation of [FileSystem]. 481 /// [FileSystemState] based implementation of [FileSystem].
464 /// It provides a consistent view on the known file system state. 482 /// It provides a consistent view on the known file system state.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 node.isEvaluated = true; 561 node.isEvaluated = true;
544 cycle.libraries.add(node.file); 562 cycle.libraries.add(node.file);
545 } 563 }
546 topologicallySortedCycles.add(cycle); 564 topologicallySortedCycles.add(cycle);
547 } 565 }
548 566
549 _LibraryNode getNode(FileState file) { 567 _LibraryNode getNode(FileState file) {
550 return nodesOfFiles.putIfAbsent(file, () => new _LibraryNode(this, file)); 568 return nodesOfFiles.putIfAbsent(file, () => new _LibraryNode(this, file));
551 } 569 }
552 } 570 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698