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

Side by Side Diff: pkg/kernel/lib/binary/ast_from_binary.dart

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: Address Kevin's comments Created 3 years, 10 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
« no previous file with comments | « pkg/kernel/lib/ast.dart ('k') | pkg/kernel/lib/binary/ast_to_binary.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 library kernel.ast_from_binary; 4 library kernel.ast_from_binary;
5 5
6 import 'dart:convert';
7
6 import '../ast.dart'; 8 import '../ast.dart';
9 import '../transformations/flags.dart';
7 import 'tag.dart'; 10 import 'tag.dart';
8 import 'loader.dart';
9 import 'dart:convert';
10 import 'package:kernel/transformations/flags.dart';
11 11
12 class ParseError { 12 class ParseError {
13 String filename; 13 String filename;
14 int byteIndex; 14 int byteIndex;
15 String message; 15 String message;
16 String path; 16 String path;
17 17
18 ParseError(this.message, {this.filename, this.byteIndex, this.path}); 18 ParseError(this.message, {this.filename, this.byteIndex, this.path});
19 19
20 String toString() => '$filename:$byteIndex: $message at $path'; 20 String toString() => '$filename:$byteIndex: $message at $path';
21 } 21 }
22 22
23 class BinaryBuilder { 23 class BinaryBuilder {
24 final BinaryReferenceLoader loader;
25 final List<Library> importTable = <Library>[];
26 final List<VariableDeclaration> variableStack = <VariableDeclaration>[]; 24 final List<VariableDeclaration> variableStack = <VariableDeclaration>[];
27 final List<LabeledStatement> labelStack = <LabeledStatement>[]; 25 final List<LabeledStatement> labelStack = <LabeledStatement>[];
28 int labelStackBase = 0; 26 int labelStackBase = 0;
29 final List<SwitchCase> switchCaseStack = <SwitchCase>[]; 27 final List<SwitchCase> switchCaseStack = <SwitchCase>[];
30 final List<TypeParameter> typeParameterStack = <TypeParameter>[]; 28 final List<TypeParameter> typeParameterStack = <TypeParameter>[];
31 final String filename; 29 final String filename;
32 final List<int> _bytes; 30 final List<int> _bytes;
33 int _byteIndex = 0; 31 int _byteIndex = 0;
34 Library _currentLibrary;
35 List<String> _stringTable; 32 List<String> _stringTable;
36 List<String> _sourceUriTable; 33 List<String> _sourceUriTable;
34 List<CanonicalName> _linkTable;
37 int _transformerFlags = 0; 35 int _transformerFlags = 0;
36 Library _currentLibrary;
38 37
39 // If something goes wrong, this list should indicate what library, 38 // If something goes wrong, this list should indicate what library,
40 // class, and member was being built. 39 // class, and member was being built.
41 List<String> debugPath = <String>[]; 40 List<String> debugPath = <String>[];
42 41
43 BinaryBuilder(this.loader, this._bytes, [this.filename]); 42 bool _isReadingLibraryImplementation = false;
43
44 BinaryBuilder(this._bytes, [this.filename]);
44 45
45 fail(String message) { 46 fail(String message) {
46 throw new ParseError(message, 47 throw new ParseError(message,
47 byteIndex: _byteIndex, filename: filename, path: debugPath.join('::')); 48 byteIndex: _byteIndex, filename: filename, path: debugPath.join('::'));
48 } 49 }
49 50
50 int readByte() => _bytes[_byteIndex++]; 51 int readByte() => _bytes[_byteIndex++];
51 52
52 int readUInt() { 53 int readUInt() {
53 var byte = readByte(); 54 var byte = readByte();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 return _stringTable[readUInt()]; 120 return _stringTable[readUInt()];
120 } 121 }
121 122
122 String readStringOrNullIfEmpty() { 123 String readStringOrNullIfEmpty() {
123 var string = readStringReference(); 124 var string = readStringReference();
124 return string.isEmpty ? null : string; 125 return string.isEmpty ? null : string;
125 } 126 }
126 127
127 InferredValue readOptionalInferredValue() { 128 InferredValue readOptionalInferredValue() {
128 if (readAndCheckOptionTag()) { 129 if (readAndCheckOptionTag()) {
129 Class baseClass = readClassReference(allowNull: true); 130 Reference baseClass = readClassReference(allowNull: true);
130 BaseClassKind baseClassKind = BaseClassKind.values[readByte()]; 131 BaseClassKind baseClassKind = BaseClassKind.values[readByte()];
131 int valueBits = readByte(); 132 int valueBits = readByte();
132 return new InferredValue(baseClass, baseClassKind, valueBits); 133 return new InferredValue.byReference(baseClass, baseClassKind, valueBits);
133 } 134 }
134 return null; 135 return null;
135 } 136 }
136 137
137 bool readAndCheckOptionTag() { 138 bool readAndCheckOptionTag() {
138 int tag = readByte(); 139 int tag = readByte();
139 if (tag == Tag.Nothing) { 140 if (tag == Tag.Nothing) {
140 return false; 141 return false;
141 } else if (tag == Tag.Something) { 142 } else if (tag == Tag.Something) {
142 return true; 143 return true;
(...skipping 20 matching lines...) Expand all
163 } 164 }
164 } 165 }
165 166
166 void _fillNonTreeNodeList(List<Node> list, Node buildObject()) { 167 void _fillNonTreeNodeList(List<Node> list, Node buildObject()) {
167 list.length = readUInt(); 168 list.length = readUInt();
168 for (int i = 0; i < list.length; ++i) { 169 for (int i = 0; i < list.length; ++i) {
169 list[i] = buildObject(); 170 list[i] = buildObject();
170 } 171 }
171 } 172 }
172 173
173 Program readProgramFile() { 174 /// Reads a list of named nodes, reusing any existing objects already in the
175 /// linking tree. The nodes are merged into [list], and if reading the library
176 /// implementation, the order is corrected.
177 ///
178 /// [readObject] should read the object definition and its canonical name.
179 /// If an existing object is bound to the canonical name, the existing object
180 /// must be reused and returned.
181 void _mergeNamedNodeList(
182 List<NamedNode> list, NamedNode readObject(), TreeNode parent) {
183 if (_isReadingLibraryImplementation) {
184 // When reading the library implementation, overwrite the whole list
185 // with the new one.
186 _fillTreeNodeList(list, readObject, parent);
187 } else {
188 // When reading an external library, the results should either be:
189 // - merged with the existing external library definition (if any)
190 // - ignored if the library implementation is already in memory
191 int numberOfNodes = readUInt();
192 for (int i = 0; i < numberOfNodes; ++i) {
193 var value = readObject();
194 // We use the parent pointer of a node to determine if it already is in
195 // the AST and hence should not be added again.
196 if (value.parent == null) {
197 list.add(value..parent = parent);
198 }
199 }
200 }
201 }
202
203 void readLinkTable(CanonicalName linkRoot) {
204 int length = readUInt();
205 _linkTable = new List<CanonicalName>(length);
206 for (int i = 0; i < length; ++i) {
207 int biasedParentIndex = readUInt();
208 String name = readStringReference();
209 var parent =
210 biasedParentIndex == 0 ? linkRoot : _linkTable[biasedParentIndex - 1];
211 _linkTable[i] = parent.getChild(name);
212 }
213 }
214
215 /// Deserializes a kernel program and stores it in [program].
216 ///
217 /// When linking with a non-empty program, canonical names must have been
218 /// computed ahead of time.
219 ///
220 /// The input bytes may contain multiple files concatenated.
221 void readProgram(Program program) {
222 while (_byteIndex < _bytes.length) {
223 _readOneProgram(program);
224 }
225 }
226
227 /// Reads a single program file from the input and loads it into [program],
228 /// overwriting and reusing any existing data in the program.
229 ///
230 /// When linking with a non-empty program, canonical names must have been
231 /// computed ahead of time.
232 ///
233 /// This should *only* be used when there is a reason to not allow
234 /// concatenated files.
235 void readSingleFileProgram(Program program) {
236 _readOneProgram(program);
237 if (_byteIndex < _bytes.length) {
238 if (_byteIndex + 3 < _bytes.length) {
239 int magic = readMagicWord();
240 if (magic == Tag.ProgramFile) {
241 throw 'Concatenated program file given when a single program '
242 'was expected.';
243 }
244 }
245 throw 'Unrecognized bytes following program data';
246 }
247 }
248
249 void _readOneProgram(Program program) {
174 int magic = readMagicWord(); 250 int magic = readMagicWord();
175 if (magic != Tag.ProgramFile) { 251 if (magic != Tag.ProgramFile) {
176 throw fail('This is not a binary dart file. ' 252 throw fail('This is not a binary dart file. '
177 'Magic number was: ${magic.toRadixString(16)}'); 253 'Magic number was: ${magic.toRadixString(16)}');
178 } 254 }
179 readStringTable(); 255 readStringTable();
180 Map<String, Source> uriToSource = readUriToSource(); 256 Map<String, Source> uriToSource = readUriToSource();
181 importTable.length = readUInt(); 257 program.uriToSource.addAll(uriToSource);
182 for (int i = 0; i < importTable.length; ++i) { 258 readLinkTable(program.root);
183 importTable[i] = new Library(null); 259 int numberOfLibraries = readUInt();
184 } 260 List<Library> libraries = new List<Library>(numberOfLibraries);
185 for (int i = 0; i < importTable.length; ++i) { 261 for (int i = 0; i < numberOfLibraries; ++i) {
186 _currentLibrary = importTable[i]; 262 libraries[i] = readLibrary(program);
187 readLibrary();
188 } 263 }
189 var mainMethod = readMemberReference(allowNull: true); 264 var mainMethod = readMemberReference(allowNull: true);
190 return new Program(importTable, uriToSource)..mainMethod = mainMethod; 265 program.mainMethodName ??= mainMethod;
191 } 266 }
192 267
193 Map<String, Source> readUriToSource() { 268 Map<String, Source> readUriToSource() {
194 readSourceUriTable(); 269 readSourceUriTable();
195 int length = _sourceUriTable.length; 270 int length = _sourceUriTable.length;
196 Map<String, Source> uriToLineStarts = <String, Source>{}; 271 Map<String, Source> uriToSource = <String, Source>{};
197 for (int i = 0; i < length; ++i) { 272 for (int i = 0; i < length; ++i) {
198 String uri = _sourceUriTable[i]; 273 String uri = _sourceUriTable[i];
199 String sourceCode = readStringEntry(); 274 String sourceCode = readStringEntry();
200 int lineCount = readUInt(); 275 int lineCount = readUInt();
201 List<int> lineStarts = new List<int>(lineCount); 276 List<int> lineStarts = new List<int>(lineCount);
202 int previousLineStart = 0; 277 int previousLineStart = 0;
203 for (int j = 0; j < lineCount; ++j) { 278 for (int j = 0; j < lineCount; ++j) {
204 int lineStart = readUInt() + previousLineStart; 279 int lineStart = readUInt() + previousLineStart;
205 lineStarts[j] = lineStart; 280 lineStarts[j] = lineStart;
206 previousLineStart = lineStart; 281 previousLineStart = lineStart;
207 } 282 }
208 uriToLineStarts[uri] = new Source(lineStarts, sourceCode); 283 uriToSource[uri] = new Source(lineStarts, sourceCode);
209 } 284 }
210 return uriToLineStarts; 285 return uriToSource;
211 } 286 }
212 287
213 void _fillLazilyLoadedList( 288 CanonicalName readCanonicalNameReference() {
214 List<TreeNode> list, void buildObject(int tag, int index)) { 289 var index = readUInt();
215 int length = readUInt(); 290 if (index == 0) return null;
216 list.length = length; 291 return _linkTable[index - 1];
217 for (int i = 0; i < length; ++i) {
218 int tag = readByte();
219 buildObject(tag, i);
220 }
221 } 292 }
222 293
223 Library readLibraryReference() { 294 Reference readLibraryReference() {
224 int index = readUInt(); 295 return readCanonicalNameReference().getReference();
225 return importTable[index];
226 } 296 }
227 297
228 DeferredImport readDeferredImportReference() { 298 DeferredImport readDeferredImportReference() {
229 int index = readUInt(); 299 int index = readUInt();
230 return _currentLibrary.deferredImports[index]; 300 return _currentLibrary.deferredImports[index];
231 } 301 }
232 302
233 Class readClassReference({bool allowNull: false}) { 303 Reference readClassReference({bool allowNull: false}) {
234 int tag = readByte(); 304 var name = readCanonicalNameReference();
235 if (tag == Tag.NullReference) { 305 if (name == null && !allowNull) {
236 if (!allowNull) { 306 throw 'Expected a class reference to be valid but was `null`.';
237 throw 'Expected a class reference to be valid but was `null`.';
238 }
239 return null;
240 } else {
241 var library = readLibraryReference();
242 int index = readUInt();
243 return loader.getClassReference(library, tag, index);
244 } 307 }
308 return name?.getReference();
245 } 309 }
246 310
247 Member readMemberReference({bool allowNull: false}) { 311 Reference readMemberReference({bool allowNull: false}) {
248 int tag = readByte(); 312 var name = readCanonicalNameReference();
249 switch (tag) { 313 if (name == null && !allowNull) {
250 case Tag.LibraryFieldReference: 314 throw 'Expected a member reference to be valid but was `null`.';
251 case Tag.LibraryProcedureReference:
252 var library = readLibraryReference();
253 var index = readUInt();
254 return loader.getLibraryMemberReference(library, tag, index);
255
256 case Tag.ClassFieldReference:
257 case Tag.ClassConstructorReference:
258 case Tag.ClassProcedureReference:
259 var classNode = readClassReference();
260 var index = readUInt();
261 return loader.getClassMemberReference(classNode, tag, index);
262
263 case Tag.NullReference:
264 if (!allowNull) {
265 throw 'Expected a member reference to be valid but was `null`.';
266 }
267 return null;
268
269 default:
270 throw fail('Invalid member reference tag: $tag');
271 } 315 }
316 return name?.getReference();
272 } 317 }
273 318
274 Name readName() { 319 Name readName() {
275 String text = readStringReference(); 320 String text = readStringReference();
276 if (text.isNotEmpty && text[0] == '_') { 321 if (text.isNotEmpty && text[0] == '_') {
277 return new Name(text, readLibraryReference()); 322 return new Name.byReference(text, readLibraryReference());
278 } else { 323 } else {
279 return new Name(text); 324 return new Name(text);
280 } 325 }
281 } 326 }
282 327
283 Uri readImportUri() { 328 Library readLibrary(Program program) {
284 return Uri.parse(readStringReference()); 329 int flags = readByte();
285 } 330 bool isExternal = (flags & 0x1) != 0;
331 _isReadingLibraryImplementation = !isExternal;
332 var canonicalName = readCanonicalNameReference();
333 Reference reference = canonicalName.getReference();
334 Library library = reference.node;
335 bool shouldWriteData = library == null || _isReadingLibraryImplementation;
336 if (library == null) {
337 library =
338 new Library(Uri.parse(canonicalName.name), reference: reference);
339 program.libraries.add(library..parent = program);
340 }
341 _currentLibrary = library;
342 String name = readStringOrNullIfEmpty();
343 // TODO(jensj): We currently save (almost the same) uri twice.
344 String fileUri = readUriReference();
286 345
287 void readLibrary() { 346 if (shouldWriteData) {
288 int flags = readByte(); 347 library.isExternal = isExternal;
289 _currentLibrary.isExternal = (flags & 0x1) != 0; 348 library.name = name;
290 _currentLibrary.name = readStringOrNullIfEmpty(); 349 library.fileUri = fileUri;
291 _currentLibrary.importUri = readImportUri(); 350 }
292 debugPath.add(_currentLibrary.name ??
293 _currentLibrary.importUri?.toString() ??
294 'library');
295 351
296 // TODO(jensj): We currently save (almost the same) uri twice. 352 _readDeferredImports(library);
297 _currentLibrary.fileUri = readUriReference();
298 353
299 _readDeferredImports(_currentLibrary); 354 debugPath.add(library.name ?? library.importUri?.toString() ?? 'library');
300 _fillLazilyLoadedList(_currentLibrary.classes, (int tag, int index) { 355
301 readClass(loader.getClassReference(_currentLibrary, tag, index), tag); 356 _mergeNamedNodeList(library.classes, readClass, library);
302 }); 357 _mergeNamedNodeList(library.fields, readField, library);
303 _fillLazilyLoadedList(_currentLibrary.fields, (int tag, int index) { 358 _mergeNamedNodeList(library.procedures, readProcedure, library);
304 readField( 359
305 loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
306 });
307 _fillLazilyLoadedList(_currentLibrary.procedures, (int tag, int index) {
308 readProcedure(
309 loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
310 });
311 debugPath.removeLast(); 360 debugPath.removeLast();
361 _currentLibrary = null;
362 return library;
312 } 363 }
313 364
314 void _readDeferredImports(Library library) { 365 void _readDeferredImports(Library library) {
315 int count = readUInt(); 366 int length = readUInt();
316 library.deferredImports.length = count; 367 if (library.isExternal) {
317 for (int i = 0; i < count; ++i) { 368 assert(length == 0);
318 var importNode = _readDeferredImport(); 369 return;
319 library.deferredImports.add(importNode..parent = library); 370 }
371 library.deferredImports.length = length;
372 for (int i = 0; i < length; ++i) {
373 library.deferredImports[i] = new DeferredImport.byReference(
374 readLibraryReference(), readStringReference())..parent = library;
320 } 375 }
321 } 376 }
322 377
323 DeferredImport _readDeferredImport() { 378 Class readClass() {
324 return new DeferredImport(readLibraryReference(), readStringReference()); 379 int tag = readByte();
325 } 380 assert(tag == Tag.Class);
326 381 var canonicalName = readCanonicalNameReference();
327 void readClass(Class node, int tag) { 382 var reference = canonicalName.getReference();
328 assert(node != null); 383 Class node = reference.node;
329 switch (tag) { 384 bool shouldWriteData = node == null || _isReadingLibraryImplementation;
330 case Tag.NormalClass: 385 if (node == null) {
331 readNormalClass(node); 386 node = new Class(reference: reference)..level = ClassLevel.Temporary;
332 break;
333 case Tag.MixinClass:
334 readMixinClass(node);
335 break;
336 default:
337 throw fail('Invalid class tag: $tag');
338 } 387 }
339 }
340
341 void readNormalClass(Class node) {
342 node.fileOffset = readOffset(); 388 node.fileOffset = readOffset();
343 int flags = readByte(); 389 int flags = readByte();
344 node.isAbstract = flags & 0x1 != 0; 390 node.isAbstract = flags & 0x1 != 0;
345 int levelIndex = (flags >> 1) & 0x3; 391 int levelIndex = (flags >> 1) & 0x3;
346 node.level = ClassLevel.values[levelIndex + 1]; 392 var level = ClassLevel.values[levelIndex + 1];
347 node.name = readStringOrNullIfEmpty(); 393 if (level.index >= node.level.index) {
348 node.fileUri = readUriReference(); 394 node.level = level;
349 node.annotations = readAnnotationList(node); 395 }
396 var name = readStringOrNullIfEmpty();
397 var fileUri = readUriReference();
398 var annotations = readAnnotationList(node);
350 debugPath.add(node.name ?? 'normal-class'); 399 debugPath.add(node.name ?? 'normal-class');
351 readAndPushTypeParameterList(node.typeParameters, node); 400 readAndPushTypeParameterList(node.typeParameters, node);
352 node.supertype = readSupertypeOption(); 401 var supertype = readSupertypeOption();
402 var mixedInType = readSupertypeOption();
353 _fillNonTreeNodeList(node.implementedTypes, readSupertype); 403 _fillNonTreeNodeList(node.implementedTypes, readSupertype);
354 _fillLazilyLoadedList(node.fields, (int tag, int index) { 404 _mergeNamedNodeList(node.fields, readField, node);
355 readField(loader.getClassMemberReference(node, tag, index), tag); 405 _mergeNamedNodeList(node.constructors, readConstructor, node);
356 }); 406 _mergeNamedNodeList(node.procedures, readProcedure, node);
357 _fillLazilyLoadedList(node.constructors, (int tag, int index) {
358 readConstructor(loader.getClassMemberReference(node, tag, index), tag);
359 });
360 _fillLazilyLoadedList(node.procedures, (int tag, int index) {
361 readProcedure(loader.getClassMemberReference(node, tag, index), tag);
362 });
363 typeParameterStack.length = 0; 407 typeParameterStack.length = 0;
364 debugPath.removeLast(); 408 debugPath.removeLast();
365 } 409 if (shouldWriteData) {
366 410 node.name = name;
367 void readMixinClass(Class node) { 411 node.fileUri = fileUri;
368 node.fileOffset = readOffset(); 412 node.annotations = annotations;
369 int flags = readByte(); 413 node.supertype = supertype;
370 node.isAbstract = flags & 0x1 != 0; 414 node.mixedInType = mixedInType;
371 int levelIndex = (flags >> 1) & 0x3; 415 }
372 node.level = ClassLevel.values[levelIndex]; 416 return node;
373 node.name = readStringOrNullIfEmpty();
374 node.fileUri = readUriReference();
375 node.annotations = readAnnotationList(node);
376 debugPath.add(node.name ?? 'mixin-class');
377 readAndPushTypeParameterList(node.typeParameters, node);
378 node.supertype = readSupertype();
379 node.mixedInType = readSupertype();
380 _fillNonTreeNodeList(node.implementedTypes, readDartType);
381 _fillLazilyLoadedList(node.constructors, (int tag, int index) {
382 readConstructor(loader.getClassMemberReference(node, tag, index), tag);
383 });
384 typeParameterStack.length = 0;
385 debugPath.removeLast();
386 } 417 }
387 418
388 int getAndResetTransformerFlags() { 419 int getAndResetTransformerFlags() {
389 int flags = _transformerFlags; 420 int flags = _transformerFlags;
390 _transformerFlags = 0; 421 _transformerFlags = 0;
391 return flags; 422 return flags;
392 } 423 }
393 424
394 /// Adds the given flag to the current [Member.transformerFlags]. 425 /// Adds the given flag to the current [Member.transformerFlags].
395 void addTransformerFlag(int flags) { 426 void addTransformerFlag(int flags) {
396 _transformerFlags |= flags; 427 _transformerFlags |= flags;
397 } 428 }
398 429
399 void readField(Field node, int tag) { 430 Field readField() {
400 // Note: as with readProcedure and readConstructor, the tag parameter 431 int tag = readByte();
401 // is unused, but we pass it in to clarify that the tag has already been
402 // consumed from the input.
403 assert(tag == Tag.Field); 432 assert(tag == Tag.Field);
404 node.fileOffset = readOffset(); 433 var canonicalName = readCanonicalNameReference();
405 node.fileEndOffset = readOffset(); 434 var reference = canonicalName.getReference();
406 node.flags = readByte(); 435 Field node = reference.node;
407 node.name = readName(); 436 bool shouldWriteData = node == null || _isReadingLibraryImplementation;
408 node.fileUri = readUriReference(); 437 if (node == null) {
409 node.annotations = readAnnotationList(node); 438 node = new Field(null, reference: reference);
439 }
440 int fileOffset = readOffset();
441 int fileEndOffset = readOffset();
442 int flags = readByte();
443 var name = readName();
444 var fileUri = readUriReference();
445 var annotations = readAnnotationList(node);
410 debugPath.add(node.name?.name ?? 'field'); 446 debugPath.add(node.name?.name ?? 'field');
411 node.type = readDartType(); 447 var type = readDartType();
412 node.inferredValue = readOptionalInferredValue(); 448 var inferredValue = readOptionalInferredValue();
413 node.initializer = readExpressionOption(); 449 var initializer = readExpressionOption();
414 node.initializer?.parent = node; 450 int transformerFlags = getAndResetTransformerFlags();
415 node.transformerFlags = getAndResetTransformerFlags();
416 debugPath.removeLast(); 451 debugPath.removeLast();
452 if (shouldWriteData) {
453 node.fileOffset = fileOffset;
454 node.fileEndOffset = fileEndOffset;
455 node.flags = flags;
456 node.name = name;
457 node.fileUri = fileUri;
458 node.annotations = annotations;
459 node.type = type;
460 node.inferredValue = inferredValue;
461 node.initializer = initializer;
462 node.initializer?.parent = node;
463 node.transformerFlags = transformerFlags;
464 }
465 return node;
417 } 466 }
418 467
419 void readConstructor(Constructor node, int tag) { 468 Constructor readConstructor() {
469 int tag = readByte();
420 assert(tag == Tag.Constructor); 470 assert(tag == Tag.Constructor);
421 node.fileOffset = readOffset(); 471 var canonicalName = readCanonicalNameReference();
422 node.fileEndOffset = readOffset(); 472 var reference = canonicalName.getReference();
423 node.flags = readByte(); 473 Constructor node = reference.node;
424 node.name = readName(); 474 bool shouldWriteData = node == null || _isReadingLibraryImplementation;
425 node.annotations = readAnnotationList(node); 475 if (node == null) {
476 node = new Constructor(null, reference: reference);
477 }
478 var fileOffset = readOffset();
479 var fileEndOffset = readOffset();
480 var flags = readByte();
481 var name = readName();
482 var annotations = readAnnotationList(node);
426 debugPath.add(node.name?.name ?? 'constructor'); 483 debugPath.add(node.name?.name ?? 'constructor');
427 node.function = readFunctionNode()..parent = node; 484 var function = readFunctionNode();
428 pushVariableDeclarations(node.function.positionalParameters); 485 pushVariableDeclarations(function.positionalParameters);
429 pushVariableDeclarations(node.function.namedParameters); 486 pushVariableDeclarations(function.namedParameters);
430 _fillTreeNodeList(node.initializers, readInitializer, node); 487 _fillTreeNodeList(node.initializers, readInitializer, node);
431 variableStack.length = 0; 488 variableStack.length = 0;
432 node.transformerFlags = getAndResetTransformerFlags(); 489 var transformerFlags = getAndResetTransformerFlags();
433 debugPath.removeLast(); 490 debugPath.removeLast();
491 if (shouldWriteData) {
492 node.fileOffset = fileOffset;
493 node.fileEndOffset = fileEndOffset;
494 node.flags = flags;
495 node.name = name;
496 node.annotations = annotations;
497 node.function = function..parent = node;
498 node.transformerFlags = transformerFlags;
499 }
500 return node;
434 } 501 }
435 502
436 void readProcedure(Procedure node, int tag) { 503 Procedure readProcedure() {
504 int tag = readByte();
437 assert(tag == Tag.Procedure); 505 assert(tag == Tag.Procedure);
438 node.fileOffset = readOffset(); 506 var canonicalName = readCanonicalNameReference();
439 node.fileEndOffset = readOffset(); 507 var reference = canonicalName.getReference();
508 Procedure node = reference.node;
509 bool shouldWriteData = node == null || _isReadingLibraryImplementation;
510 if (node == null) {
511 node = new Procedure(null, null, null, reference: reference);
512 }
513 var fileOffset = readOffset();
514 var fileEndOffset = readOffset();
440 int kindIndex = readByte(); 515 int kindIndex = readByte();
441 node.kind = ProcedureKind.values[kindIndex]; 516 var kind = ProcedureKind.values[kindIndex];
442 node.flags = readByte(); 517 var flags = readByte();
443 node.name = readName(); 518 var name = readName();
444 node.fileUri = readUriReference(); 519 var fileUri = readUriReference();
445 node.annotations = readAnnotationList(node); 520 var annotations = readAnnotationList(node);
446 debugPath.add(node.name?.name ?? 'procedure'); 521 debugPath.add(node.name?.name ?? 'procedure');
447 node.function = readFunctionNodeOption(); 522 var function = readFunctionNodeOption();
448 node.function?.parent = node; 523 var transformerFlags = getAndResetTransformerFlags();
449 node.transformerFlags = getAndResetTransformerFlags();
450 debugPath.removeLast(); 524 debugPath.removeLast();
525 if (shouldWriteData) {
526 node.fileOffset = fileOffset;
527 node.fileEndOffset = fileEndOffset;
528 node.kind = kind;
529 node.flags = flags;
530 node.name = name;
531 node.fileUri = fileUri;
532 node.annotations = annotations;
533 node.function = function;
534 node.function?.parent = node;
535 node.transformerFlags = transformerFlags;
536 }
537 return node;
451 } 538 }
452 539
453 Initializer readInitializer() { 540 Initializer readInitializer() {
454 int tag = readByte(); 541 int tag = readByte();
455 switch (tag) { 542 switch (tag) {
456 case Tag.InvalidInitializer: 543 case Tag.InvalidInitializer:
457 return new InvalidInitializer(); 544 return new InvalidInitializer();
458 case Tag.FieldInitializer: 545 case Tag.FieldInitializer:
459 return new FieldInitializer(readMemberReference(), readExpression()); 546 return new FieldInitializer.byReference(
547 readMemberReference(), readExpression());
460 case Tag.SuperInitializer: 548 case Tag.SuperInitializer:
461 return new SuperInitializer(readMemberReference(), readArguments()); 549 return new SuperInitializer.byReference(
550 readMemberReference(), readArguments());
462 case Tag.RedirectingInitializer: 551 case Tag.RedirectingInitializer:
463 return new RedirectingInitializer( 552 return new RedirectingInitializer.byReference(
464 readMemberReference(), readArguments()); 553 readMemberReference(), readArguments());
465 case Tag.LocalInitializer: 554 case Tag.LocalInitializer:
466 return new LocalInitializer(readAndPushVariableDeclaration()); 555 return new LocalInitializer(readAndPushVariableDeclaration());
467 default: 556 default:
468 throw fail('Invalid initializer tag: $tag'); 557 throw fail('Invalid initializer tag: $tag');
469 } 558 }
470 } 559 }
471 560
472 FunctionNode readFunctionNodeOption() { 561 FunctionNode readFunctionNodeOption() {
473 return readAndCheckOptionTag() ? readFunctionNode() : null; 562 return readAndCheckOptionTag() ? readFunctionNode() : null;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 int offset = readOffset(); 653 int offset = readOffset();
565 return new VariableSet(readVariableReference(), readExpression()) 654 return new VariableSet(readVariableReference(), readExpression())
566 ..fileOffset = offset; 655 ..fileOffset = offset;
567 case Tag.SpecializedVariableSet: 656 case Tag.SpecializedVariableSet:
568 int index = tagByte & Tag.SpecializedPayloadMask; 657 int index = tagByte & Tag.SpecializedPayloadMask;
569 int offset = readOffset(); 658 int offset = readOffset();
570 return new VariableSet(variableStack[index], readExpression()) 659 return new VariableSet(variableStack[index], readExpression())
571 ..fileOffset = offset; 660 ..fileOffset = offset;
572 case Tag.PropertyGet: 661 case Tag.PropertyGet:
573 int offset = readOffset(); 662 int offset = readOffset();
574 return new PropertyGet( 663 return new PropertyGet.byReference(
575 readExpression(), readName(), readMemberReference(allowNull: true)) 664 readExpression(), readName(), readMemberReference(allowNull: true))
576 ..fileOffset = offset; 665 ..fileOffset = offset;
577 case Tag.PropertySet: 666 case Tag.PropertySet:
578 int offset = readOffset(); 667 int offset = readOffset();
579 return new PropertySet(readExpression(), readName(), readExpression(), 668 return new PropertySet.byReference(
669 readExpression(),
670 readName(),
671 readExpression(),
580 readMemberReference(allowNull: true))..fileOffset = offset; 672 readMemberReference(allowNull: true))..fileOffset = offset;
581 case Tag.SuperPropertyGet: 673 case Tag.SuperPropertyGet:
582 addTransformerFlag(TransformerFlag.superCalls); 674 addTransformerFlag(TransformerFlag.superCalls);
583 return new SuperPropertyGet( 675 return new SuperPropertyGet.byReference(
584 readName(), readMemberReference(allowNull: true)); 676 readName(), readMemberReference(allowNull: true));
585 case Tag.SuperPropertySet: 677 case Tag.SuperPropertySet:
586 addTransformerFlag(TransformerFlag.superCalls); 678 addTransformerFlag(TransformerFlag.superCalls);
587 return new SuperPropertySet( 679 return new SuperPropertySet.byReference(
588 readName(), readExpression(), readMemberReference(allowNull: true)); 680 readName(), readExpression(), readMemberReference(allowNull: true));
589 case Tag.DirectPropertyGet: 681 case Tag.DirectPropertyGet:
590 return new DirectPropertyGet(readExpression(), readMemberReference()); 682 return new DirectPropertyGet.byReference(
683 readExpression(), readMemberReference());
591 case Tag.DirectPropertySet: 684 case Tag.DirectPropertySet:
592 return new DirectPropertySet( 685 return new DirectPropertySet.byReference(
593 readExpression(), readMemberReference(), readExpression()); 686 readExpression(), readMemberReference(), readExpression());
594 case Tag.StaticGet: 687 case Tag.StaticGet:
595 int offset = readOffset(); 688 int offset = readOffset();
596 return new StaticGet(readMemberReference())..fileOffset = offset; 689 return new StaticGet.byReference(readMemberReference())
690 ..fileOffset = offset;
597 case Tag.StaticSet: 691 case Tag.StaticSet:
598 return new StaticSet(readMemberReference(), readExpression()); 692 return new StaticSet.byReference(
693 readMemberReference(), readExpression());
599 case Tag.MethodInvocation: 694 case Tag.MethodInvocation:
600 int offset = readOffset(); 695 int offset = readOffset();
601 return new MethodInvocation( 696 return new MethodInvocation.byReference(
602 readExpression(), 697 readExpression(),
603 readName(), 698 readName(),
604 readArguments(), 699 readArguments(),
605 readMemberReference(allowNull: true))..fileOffset = offset; 700 readMemberReference(allowNull: true))..fileOffset = offset;
606 case Tag.SuperMethodInvocation: 701 case Tag.SuperMethodInvocation:
607 int offset = readOffset(); 702 int offset = readOffset();
608 addTransformerFlag(TransformerFlag.superCalls); 703 addTransformerFlag(TransformerFlag.superCalls);
609 return new SuperMethodInvocation( 704 return new SuperMethodInvocation.byReference(
610 readName(), readArguments(), readMemberReference(allowNull: true)) 705 readName(), readArguments(), readMemberReference(allowNull: true))
611 ..fileOffset = offset; 706 ..fileOffset = offset;
612 case Tag.DirectMethodInvocation: 707 case Tag.DirectMethodInvocation:
613 return new DirectMethodInvocation( 708 return new DirectMethodInvocation.byReference(
614 readExpression(), readMemberReference(), readArguments()); 709 readExpression(), readMemberReference(), readArguments());
615 case Tag.StaticInvocation: 710 case Tag.StaticInvocation:
616 int offset = readOffset(); 711 int offset = readOffset();
617 return new StaticInvocation(readMemberReference(), readArguments(), 712 return new StaticInvocation.byReference(
618 isConst: false)..fileOffset = offset; 713 readMemberReference(), readArguments(), isConst: false)
714 ..fileOffset = offset;
619 case Tag.ConstStaticInvocation: 715 case Tag.ConstStaticInvocation:
620 int offset = readOffset(); 716 int offset = readOffset();
621 return new StaticInvocation(readMemberReference(), readArguments(), 717 return new StaticInvocation.byReference(
622 isConst: true)..fileOffset = offset; 718 readMemberReference(), readArguments(), isConst: true)
719 ..fileOffset = offset;
623 case Tag.ConstructorInvocation: 720 case Tag.ConstructorInvocation:
624 int offset = readOffset(); 721 int offset = readOffset();
625 return new ConstructorInvocation(readMemberReference(), readArguments(), 722 return new ConstructorInvocation.byReference(
626 isConst: false)..fileOffset = offset; 723 readMemberReference(), readArguments(), isConst: false)
724 ..fileOffset = offset;
627 case Tag.ConstConstructorInvocation: 725 case Tag.ConstConstructorInvocation:
628 int offset = readOffset(); 726 int offset = readOffset();
629 return new ConstructorInvocation(readMemberReference(), readArguments(), 727 return new ConstructorInvocation.byReference(
630 isConst: true)..fileOffset = offset; 728 readMemberReference(), readArguments(), isConst: true)
729 ..fileOffset = offset;
631 case Tag.Not: 730 case Tag.Not:
632 return new Not(readExpression()); 731 return new Not(readExpression());
633 case Tag.LogicalExpression: 732 case Tag.LogicalExpression:
634 return new LogicalExpression(readExpression(), 733 return new LogicalExpression(readExpression(),
635 logicalOperatorToString(readByte()), readExpression()); 734 logicalOperatorToString(readByte()), readExpression());
636 case Tag.ConditionalExpression: 735 case Tag.ConditionalExpression:
637 return new ConditionalExpression(readExpression(), readExpression(), 736 return new ConditionalExpression(readExpression(), readExpression(),
638 readExpression(), readDartTypeOption()); 737 readExpression(), readDartTypeOption());
639 case Tag.StringConcatenation: 738 case Tag.StringConcatenation:
640 int offset = readOffset(); 739 int offset = readOffset();
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 948
850 Block readBlock() { 949 Block readBlock() {
851 int stackHeight = variableStack.length; 950 int stackHeight = variableStack.length;
852 var body = readStatementList(); 951 var body = readStatementList();
853 variableStack.length = stackHeight; 952 variableStack.length = stackHeight;
854 return new Block(body); 953 return new Block(body);
855 } 954 }
856 955
857 Supertype readSupertype() { 956 Supertype readSupertype() {
858 InterfaceType type = readDartType(); 957 InterfaceType type = readDartType();
859 return new Supertype(type.classNode, type.typeArguments); 958 return new Supertype.byReference(type.className, type.typeArguments);
860 } 959 }
861 960
862 Supertype readSupertypeOption() { 961 Supertype readSupertypeOption() {
863 return readAndCheckOptionTag() ? readSupertype() : null; 962 return readAndCheckOptionTag() ? readSupertype() : null;
864 } 963 }
865 964
866 List<Supertype> readSupertypeList() { 965 List<Supertype> readSupertypeList() {
867 return new List<Supertype>.generate(readUInt(), (i) => readSupertype()); 966 return new List<Supertype>.generate(readUInt(), (i) => readSupertype());
868 } 967 }
869 968
(...skipping 18 matching lines...) Expand all
888 switch (tag) { 987 switch (tag) {
889 case Tag.BottomType: 988 case Tag.BottomType:
890 return const BottomType(); 989 return const BottomType();
891 case Tag.InvalidType: 990 case Tag.InvalidType:
892 return const InvalidType(); 991 return const InvalidType();
893 case Tag.DynamicType: 992 case Tag.DynamicType:
894 return const DynamicType(); 993 return const DynamicType();
895 case Tag.VoidType: 994 case Tag.VoidType:
896 return const VoidType(); 995 return const VoidType();
897 case Tag.InterfaceType: 996 case Tag.InterfaceType:
898 return new InterfaceType(readClassReference(), readDartTypeList()); 997 return new InterfaceType.byReference(
998 readClassReference(), readDartTypeList());
899 case Tag.SimpleInterfaceType: 999 case Tag.SimpleInterfaceType:
900 return new InterfaceType(readClassReference(), const <DartType>[]); 1000 return new InterfaceType.byReference(
1001 readClassReference(), const <DartType>[]);
901 case Tag.FunctionType: 1002 case Tag.FunctionType:
902 int typeParameterStackHeight = typeParameterStack.length; 1003 int typeParameterStackHeight = typeParameterStack.length;
903 var typeParameters = readAndPushTypeParameterList(); 1004 var typeParameters = readAndPushTypeParameterList();
904 var requiredParameterCount = readUInt(); 1005 var requiredParameterCount = readUInt();
905 var positional = readDartTypeList(); 1006 var positional = readDartTypeList();
906 var named = readNamedTypeList(); 1007 var named = readNamedTypeList();
907 var returnType = readDartType(); 1008 var returnType = readDartType();
908 typeParameterStack.length = typeParameterStackHeight; 1009 typeParameterStack.length = typeParameterStackHeight;
909 return new FunctionType(positional, returnType, 1010 return new FunctionType(positional, returnType,
910 typeParameters: typeParameters, 1011 typeParameters: typeParameters,
(...skipping 11 matching lines...) Expand all
922 } 1023 }
923 } 1024 }
924 1025
925 List<TypeParameter> readAndPushTypeParameterList( 1026 List<TypeParameter> readAndPushTypeParameterList(
926 [List<TypeParameter> list, TreeNode parent]) { 1027 [List<TypeParameter> list, TreeNode parent]) {
927 int length = readUInt(); 1028 int length = readUInt();
928 if (length == 0) return list ?? <TypeParameter>[]; 1029 if (length == 0) return list ?? <TypeParameter>[];
929 if (list == null) { 1030 if (list == null) {
930 list = new List<TypeParameter>.generate( 1031 list = new List<TypeParameter>.generate(
931 length, (i) => new TypeParameter(null, null)..parent = parent); 1032 length, (i) => new TypeParameter(null, null)..parent = parent);
932 } else { 1033 } else if (list.length != length) {
933 list.length = length; 1034 list.length = length;
934 for (int i = 0; i < length; ++i) { 1035 for (int i = 0; i < length; ++i) {
935 list[i] = new TypeParameter(null, null)..parent = parent; 1036 list[i] = new TypeParameter(null, null)..parent = parent;
936 } 1037 }
937 } 1038 }
938 typeParameterStack.addAll(list); 1039 typeParameterStack.addAll(list);
939 for (int i = 0; i < list.length; ++i) { 1040 for (int i = 0; i < list.length; ++i) {
940 readTypeParameter(list[i]); 1041 readTypeParameter(list[i]);
941 } 1042 }
942 return list; 1043 return list;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 isFinal: flags & 0x1 != 0, 1089 isFinal: flags & 0x1 != 0,
989 isConst: flags & 0x2 != 0)..fileOffset = offset; 1090 isConst: flags & 0x2 != 0)..fileOffset = offset;
990 } 1091 }
991 1092
992 int readOffset() { 1093 int readOffset() {
993 // Offset is saved as unsigned, 1094 // Offset is saved as unsigned,
994 // but actually ranges from -1 and up (thus the -1) 1095 // but actually ranges from -1 and up (thus the -1)
995 return readUInt() - 1; 1096 return readUInt() - 1;
996 } 1097 }
997 } 1098 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/ast.dart ('k') | pkg/kernel/lib/binary/ast_to_binary.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698