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

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

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: 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
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 '../ast.dart'; 6 import '../ast.dart';
7 import 'tag.dart'; 7 import 'tag.dart';
8 import 'loader.dart';
9 import 'dart:convert'; 8 import 'dart:convert';
10 import 'package:kernel/transformations/flags.dart'; 9 import 'package:kernel/transformations/flags.dart';
11 10
12 class ParseError { 11 class ParseError {
13 String filename; 12 String filename;
14 int byteIndex; 13 int byteIndex;
15 String message; 14 String message;
16 String path; 15 String path;
17 16
18 ParseError(this.message, {this.filename, this.byteIndex, this.path}); 17 ParseError(this.message, {this.filename, this.byteIndex, this.path});
19 18
20 String toString() => '$filename:$byteIndex: $message at $path'; 19 String toString() => '$filename:$byteIndex: $message at $path';
21 } 20 }
22 21
23 class BinaryBuilder { 22 class BinaryBuilder {
24 final BinaryReferenceLoader loader;
25 final List<Library> importTable = <Library>[];
26 final List<VariableDeclaration> variableStack = <VariableDeclaration>[]; 23 final List<VariableDeclaration> variableStack = <VariableDeclaration>[];
27 final List<LabeledStatement> labelStack = <LabeledStatement>[]; 24 final List<LabeledStatement> labelStack = <LabeledStatement>[];
28 int labelStackBase = 0; 25 int labelStackBase = 0;
29 final List<SwitchCase> switchCaseStack = <SwitchCase>[]; 26 final List<SwitchCase> switchCaseStack = <SwitchCase>[];
30 final List<TypeParameter> typeParameterStack = <TypeParameter>[]; 27 final List<TypeParameter> typeParameterStack = <TypeParameter>[];
31 final String filename; 28 final String filename;
32 final List<int> _bytes; 29 final List<int> _bytes;
33 int _byteIndex = 0; 30 int _byteIndex = 0;
34 Library _currentLibrary;
35 List<String> _stringTable; 31 List<String> _stringTable;
36 List<String> _sourceUriTable; 32 List<String> _sourceUriTable;
33 List<CanonicalName> _linkTable;
37 int _transformerFlags = 0; 34 int _transformerFlags = 0;
38 35
39 // If something goes wrong, this list should indicate what library, 36 // If something goes wrong, this list should indicate what library,
40 // class, and member was being built. 37 // class, and member was being built.
41 List<String> debugPath = <String>[]; 38 List<String> debugPath = <String>[];
42 39
43 BinaryBuilder(this.loader, this._bytes, [this.filename]); 40 bool _isReadingLibraryImplementation = false;
41
42 BinaryBuilder(this._bytes, [this.filename]);
44 43
45 fail(String message) { 44 fail(String message) {
46 throw new ParseError(message, 45 throw new ParseError(message,
47 byteIndex: _byteIndex, filename: filename, path: debugPath.join('::')); 46 byteIndex: _byteIndex, filename: filename, path: debugPath.join('::'));
48 } 47 }
49 48
50 int readByte() => _bytes[_byteIndex++]; 49 int readByte() => _bytes[_byteIndex++];
51 50
52 int readUInt() { 51 int readUInt() {
53 var byte = readByte(); 52 var byte = readByte();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 return _stringTable[readUInt()]; 118 return _stringTable[readUInt()];
120 } 119 }
121 120
122 String readStringOrNullIfEmpty() { 121 String readStringOrNullIfEmpty() {
123 var string = readStringReference(); 122 var string = readStringReference();
124 return string.isEmpty ? null : string; 123 return string.isEmpty ? null : string;
125 } 124 }
126 125
127 InferredValue readOptionalInferredValue() { 126 InferredValue readOptionalInferredValue() {
128 if (readAndCheckOptionTag()) { 127 if (readAndCheckOptionTag()) {
129 Class baseClass = readClassReference(allowNull: true); 128 CanonicalName baseClass = readClassReference(allowNull: true);
130 BaseClassKind baseClassKind = BaseClassKind.values[readByte()]; 129 BaseClassKind baseClassKind = BaseClassKind.values[readByte()];
131 int valueBits = readByte(); 130 int valueBits = readByte();
132 return new InferredValue(baseClass, baseClassKind, valueBits); 131 return new InferredValue.byName(baseClass, baseClassKind, valueBits);
133 } 132 }
134 return null; 133 return null;
135 } 134 }
136 135
137 bool readAndCheckOptionTag() { 136 bool readAndCheckOptionTag() {
138 int tag = readByte(); 137 int tag = readByte();
139 if (tag == Tag.Nothing) { 138 if (tag == Tag.Nothing) {
140 return false; 139 return false;
141 } else if (tag == Tag.Something) { 140 } else if (tag == Tag.Something) {
142 return true; 141 return true;
(...skipping 20 matching lines...) Expand all
163 } 162 }
164 } 163 }
165 164
166 void _fillNonTreeNodeList(List<Node> list, Node buildObject()) { 165 void _fillNonTreeNodeList(List<Node> list, Node buildObject()) {
167 list.length = readUInt(); 166 list.length = readUInt();
168 for (int i = 0; i < list.length; ++i) { 167 for (int i = 0; i < list.length; ++i) {
169 list[i] = buildObject(); 168 list[i] = buildObject();
170 } 169 }
171 } 170 }
172 171
173 Program readProgramFile() { 172 /// Reads a list of linked nodes, reusing any existing objects already in the
173 /// linking tree. The nodes are merged into [list], and if reading the library
174 /// implementation, the order is corrected.
ahe 2017/02/13 10:07:07 I suggest that you add some documentation of what
asgerf 2017/02/16 14:22:42 Done.
175 void _mergeLinkedNodeList(
176 List<LinkedNode> list, LinkedNode readObject(), TreeNode parent) {
177 if (_isReadingLibraryImplementation) {
178 // When reading the library implementation, overwrite the whole list
179 // with the new one.
180 _fillTreeNodeList(list, readObject, parent);
181 } else {
182 // When reading an external library, the results should either be:
183 // - merged with the existing external library definition (if any)
184 // - ignored if the library impementation is already in memory
185 //
186 // We use the parent pointer of a node to determine if it already is in
187 // the AST and hence should not be added again.
188 int numberOfNodes = readUInt();
189 for (int i = 0; i < numberOfNodes; ++i) {
190 var value = readObject();
191 if (value.parent == null) {
192 list.add(value..parent = parent);
193 }
194 }
195 }
196 }
197
198 void readLinkTable(CanonicalName linkRoot) {
199 int length = readUInt();
200 _linkTable = new List<CanonicalName>(length);
201 for (int i = 0; i < length; ++i) {
202 int biasedParentIndex = readUInt();
203 String name = readStringReference();
204 var parent =
205 biasedParentIndex == 0 ? linkRoot : _linkTable[biasedParentIndex - 1];
206 _linkTable[i] = parent.getChild(name);
207 }
208 }
209
210 /// Deserializes a kernel program and stores it in [program].
211 ///
212 /// The input bytes may contain multiple files concatenated.
213 void readMultiFile(Program program) {
214 while (_byteIndex < _bytes.length) {
215 _readProgram(program);
216 }
217 }
218
219 /// Reads a single program file from the input and loads it into [program],
220 /// overwriting and reusing any existing data in the program.
221 ///
222 /// This should *only* be used when there is a reason to not allow
223 /// concatenated files.
224 void readSingleFile(Program program) {
225 _readProgram(program);
226 if (_byteIndex < _bytes.length) {
227 if (_byteIndex + 3 < _bytes.length) {
228 int magic = readMagicWord();
229 if (magic == Tag.ProgramFile) {
230 throw 'Concatenated program file given when a single program '
231 'was expected.';
232 }
233 }
234 throw 'Unrecognized bytes following program data';
235 }
236 }
237
238 void _readProgram(Program program) {
174 int magic = readMagicWord(); 239 int magic = readMagicWord();
175 if (magic != Tag.ProgramFile) { 240 if (magic != Tag.ProgramFile) {
176 throw fail('This is not a binary dart file. ' 241 throw fail('This is not a binary dart file. '
177 'Magic number was: ${magic.toRadixString(16)}'); 242 'Magic number was: ${magic.toRadixString(16)}');
178 } 243 }
179 readStringTable(); 244 readStringTable();
180 Map<String, Source> uriToSource = readUriToSource(); 245 Map<String, Source> uriToSource = readUriToSource();
181 importTable.length = readUInt(); 246 program.uriToSource.addAll(uriToSource);
182 for (int i = 0; i < importTable.length; ++i) { 247 readLinkTable(program.root);
183 importTable[i] = new Library(null); 248 int numberOfLibraries = readUInt();
184 } 249 List<Library> libraries = new List<Library>(numberOfLibraries);
185 for (int i = 0; i < importTable.length; ++i) { 250 for (int i = 0; i < numberOfLibraries; ++i) {
186 _currentLibrary = importTable[i]; 251 libraries[i] = readLibrary(program);
187 readLibrary();
188 } 252 }
189 var mainMethod = readMemberReference(allowNull: true); 253 var mainMethod = readMemberReference(allowNull: true);
190 return new Program(importTable, uriToSource) 254 program.mainMethodName ??= mainMethod;
191 ..mainMethod = mainMethod;
192 } 255 }
193 256
194 Map<String, Source> readUriToSource() { 257 Map<String, Source> readUriToSource() {
195 readSourceUriTable(); 258 readSourceUriTable();
196 int length = _sourceUriTable.length; 259 int length = _sourceUriTable.length;
197 Map<String, Source> uriToLineStarts = <String, Source>{}; 260 Map<String, Source> uriToSource = <String, Source>{};
198 for (int i = 0; i < length; ++i) { 261 for (int i = 0; i < length; ++i) {
199 String uri = _sourceUriTable[i]; 262 String uri = _sourceUriTable[i];
200 String sourceCode = readStringEntry(); 263 String sourceCode = readStringEntry();
201 int lineCount = readUInt(); 264 int lineCount = readUInt();
202 List<int> lineStarts = new List<int>(lineCount); 265 List<int> lineStarts = new List<int>(lineCount);
203 int previousLineStart = 0; 266 int previousLineStart = 0;
204 for (int j = 0; j < lineCount; ++j) { 267 for (int j = 0; j < lineCount; ++j) {
205 int lineStart = readUInt() + previousLineStart; 268 int lineStart = readUInt() + previousLineStart;
206 lineStarts[j] = lineStart; 269 lineStarts[j] = lineStart;
207 previousLineStart = lineStart; 270 previousLineStart = lineStart;
208 } 271 }
209 uriToLineStarts[uri] = new Source(lineStarts, sourceCode); 272 uriToSource[uri] = new Source(lineStarts, sourceCode);
210 } 273 }
211 return uriToLineStarts; 274 return uriToSource;
212 } 275 }
213 276
214 void _fillLazilyLoadedList( 277 CanonicalName readCanonicalNameReference() {
215 List<TreeNode> list, void buildObject(int tag, int index)) { 278 var index = readUInt();
216 int length = readUInt(); 279 if (index == 0) return null;
217 list.length = length; 280 return _linkTable[index - 1];
218 for (int i = 0; i < length; ++i) {
219 int tag = readByte();
220 buildObject(tag, i);
221 }
222 } 281 }
223 282
224 Library readLibraryReference() { 283 CanonicalName readLibraryReference() {
225 int index = readUInt(); 284 return readCanonicalNameReference();
226 return importTable[index];
227 } 285 }
228 286
229 Class readClassReference({bool allowNull: false}) { 287 CanonicalName readClassReference({bool allowNull: false}) {
230 int tag = readByte(); 288 var name = readCanonicalNameReference();
231 if (tag == Tag.NullReference) { 289 if (name == null && !allowNull) {
232 if (!allowNull) { 290 throw 'Expected a class reference to be valid but was `null`.';
233 throw 'Expected a class reference to be valid but was `null`.';
234 }
235 return null;
236 } else {
237 var library = readLibraryReference();
238 int index = readUInt();
239 return loader.getClassReference(library, tag, index);
240 } 291 }
292 return name;
241 } 293 }
242 294
243 Member readMemberReference({bool allowNull: false}) { 295 CanonicalName readMemberReference({bool allowNull: false}) {
244 int tag = readByte(); 296 var name = readCanonicalNameReference();
245 switch (tag) { 297 if (name == null && !allowNull) {
246 case Tag.LibraryFieldReference: 298 throw 'Expected a member reference to be valid but was `null`.';
247 case Tag.LibraryProcedureReference:
248 var library = readLibraryReference();
249 var index = readUInt();
250 return loader.getLibraryMemberReference(library, tag, index);
251
252 case Tag.ClassFieldReference:
253 case Tag.ClassConstructorReference:
254 case Tag.ClassProcedureReference:
255 var classNode = readClassReference();
256 var index = readUInt();
257 return loader.getClassMemberReference(classNode, tag, index);
258
259 case Tag.NullReference:
260 if (!allowNull) {
261 throw 'Expected a member reference to be valid but was `null`.';
262 }
263 return null;
264
265 default:
266 throw fail('Invalid member reference tag: $tag');
267 } 299 }
300 return name;
268 } 301 }
269 302
270 Name readName() { 303 Name readName() {
271 String text = readStringReference(); 304 String text = readStringReference();
272 if (text.isNotEmpty && text[0] == '_') { 305 if (text.isNotEmpty && text[0] == '_') {
273 return new Name(text, readLibraryReference()); 306 return new Name.byReference(text, readLibraryReference());
274 } else { 307 } else {
275 return new Name(text); 308 return new Name(text);
276 } 309 }
277 } 310 }
278 311
279 Uri readImportUri() { 312 Library readLibrary(Program program) {
280 return Uri.parse(readStringReference()); 313 int flags = readByte();
314 bool isExternal = (flags & 0x1) != 0;
315 _isReadingLibraryImplementation = !isExternal;
316 var canonicalName = readCanonicalNameReference();
317 Library library = canonicalName.definition;
318 bool shouldWriteData = library == null || _isReadingLibraryImplementation;
319 if (library == null) {
320 library = new Library(Uri.parse(canonicalName.name));
321 canonicalName.linkTo(library);
322 program.libraries.add(library..parent = program);
323 }
324 String name = readStringOrNullIfEmpty();
325 // TODO(jensj): We currently save (almost the same) uri twice.
326 String fileUri = readUriReference();
327
328 if (shouldWriteData) {
329 library.isExternal = isExternal;
330 library.name = name;
331 library.fileUri = fileUri;
332 }
333
334 debugPath.add(library.name ?? library.importUri?.toString() ?? 'library');
335
336 _mergeLinkedNodeList(library.classes, readClass, library);
337 _mergeLinkedNodeList(library.fields, readField, library);
338 _mergeLinkedNodeList(library.procedures, readProcedure, library);
339
340 debugPath.removeLast();
341 return library;
281 } 342 }
282 343
283 void readLibrary() { 344 Class readClass() {
284 int flags = readByte(); 345 int tag = readByte();
285 _currentLibrary.isExternal = (flags & 0x1) != 0; 346 assert(tag == Tag.Class);
286 _currentLibrary.name = readStringOrNullIfEmpty(); 347 var canonicalName = readCanonicalNameReference();
287 _currentLibrary.importUri = readImportUri(); 348 Class node = canonicalName.definition;
288 debugPath.add(_currentLibrary.name ?? 349 bool shouldWriteData = node == null || _isReadingLibraryImplementation;
289 _currentLibrary.importUri?.toString() ?? 350 if (node == null) {
290 'library'); 351 node = new Class()..level = ClassLevel.Temporary;
291 352 canonicalName.linkTo(node);
292 // TODO(jensj): We currently save (almost the same) uri twice.
293 _currentLibrary.fileUri = readUriReference();
294
295 _fillLazilyLoadedList(_currentLibrary.classes, (int tag, int index) {
296 readClass(loader.getClassReference(_currentLibrary, tag, index), tag);
297 });
298 _fillLazilyLoadedList(_currentLibrary.fields, (int tag, int index) {
299 readField(
300 loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
301 });
302 _fillLazilyLoadedList(_currentLibrary.procedures, (int tag, int index) {
303 readProcedure(
304 loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
305 });
306 debugPath.removeLast();
307 }
308
309 void readClass(Class node, int tag) {
310 assert(node != null);
311 switch (tag) {
312 case Tag.NormalClass:
313 readNormalClass(node);
314 break;
315 case Tag.MixinClass:
316 readMixinClass(node);
317 break;
318 default:
319 throw fail('Invalid class tag: $tag');
320 } 353 }
321 }
322
323 void readNormalClass(Class node) {
324 node.fileOffset = readOffset(); 354 node.fileOffset = readOffset();
325 int flags = readByte(); 355 int flags = readByte();
326 node.isAbstract = flags & 0x1 != 0; 356 node.isAbstract = flags & 0x1 != 0;
327 node.level = _currentLibrary.isExternal 357 var level = _isReadingLibraryImplementation
328 ? (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy 358 ? ClassLevel.Body
329 : ClassLevel.Body; 359 : (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy;
330 node.name = readStringOrNullIfEmpty(); 360 if (level.index >= node.level.index) {
331 node.fileUri = readUriReference(); 361 node.level = level;
332 node.annotations = readAnnotationList(node); 362 }
363 var name = readStringOrNullIfEmpty();
364 var fileUri = readUriReference();
365 var annotations = readAnnotationList(node);
333 debugPath.add(node.name ?? 'normal-class'); 366 debugPath.add(node.name ?? 'normal-class');
334 readAndPushTypeParameterList(node.typeParameters, node); 367 readAndPushTypeParameterList(node.typeParameters, node);
335 node.supertype = readSupertypeOption(); 368 var supertype = readSupertypeOption();
369 var mixedInType = readSupertypeOption();
336 _fillNonTreeNodeList(node.implementedTypes, readSupertype); 370 _fillNonTreeNodeList(node.implementedTypes, readSupertype);
337 _fillLazilyLoadedList(node.fields, (int tag, int index) { 371 _mergeLinkedNodeList(node.fields, readField, node);
338 readField(loader.getClassMemberReference(node, tag, index), tag); 372 _mergeLinkedNodeList(node.constructors, readConstructor, node);
339 }); 373 _mergeLinkedNodeList(node.procedures, readProcedure, node);
340 _fillLazilyLoadedList(node.constructors, (int tag, int index) {
341 readConstructor(loader.getClassMemberReference(node, tag, index), tag);
342 });
343 _fillLazilyLoadedList(node.procedures, (int tag, int index) {
344 readProcedure(loader.getClassMemberReference(node, tag, index), tag);
345 });
346 typeParameterStack.length = 0; 374 typeParameterStack.length = 0;
347 debugPath.removeLast(); 375 debugPath.removeLast();
348 } 376 if (shouldWriteData) {
349 377 node.name = name;
350 void readMixinClass(Class node) { 378 node.fileUri = fileUri;
351 node.fileOffset = readOffset(); 379 node.annotations = annotations;
352 int flags = readByte(); 380 node.supertype = supertype;
353 node.isAbstract = flags & 0x1 != 0; 381 node.mixedInType = mixedInType;
354 node.level = _currentLibrary.isExternal 382 }
355 ? (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy 383 return node;
356 : ClassLevel.Body;
357 node.name = readStringOrNullIfEmpty();
358 node.fileUri = readUriReference();
359 node.annotations = readAnnotationList(node);
360 debugPath.add(node.name ?? 'mixin-class');
361 readAndPushTypeParameterList(node.typeParameters, node);
362 node.supertype = readSupertype();
363 node.mixedInType = readSupertype();
364 _fillNonTreeNodeList(node.implementedTypes, readDartType);
365 _fillLazilyLoadedList(node.constructors, (int tag, int index) {
366 readConstructor(loader.getClassMemberReference(node, tag, index), tag);
367 });
368 typeParameterStack.length = 0;
369 debugPath.removeLast();
370 } 384 }
371 385
372 int getAndResetTransformerFlags() { 386 int getAndResetTransformerFlags() {
373 int flags = _transformerFlags; 387 int flags = _transformerFlags;
374 _transformerFlags = 0; 388 _transformerFlags = 0;
375 return flags; 389 return flags;
376 } 390 }
377 391
378 /// Adds the given flag to the current [Member.transformerFlags]. 392 /// Adds the given flag to the current [Member.transformerFlags].
379 void addTransformerFlag(int flags) { 393 void addTransformerFlag(int flags) {
380 _transformerFlags |= flags; 394 _transformerFlags |= flags;
381 } 395 }
382 396
383 void readField(Field node, int tag) { 397 Field readField() {
384 // Note: as with readProcedure and readConstructor, the tag parameter 398 int tag = readByte();
385 // is unused, but we pass it in to clarify that the tag has already been
386 // consumed from the input.
387 assert(tag == Tag.Field); 399 assert(tag == Tag.Field);
388 node.fileOffset = readOffset(); 400 var canonicalName = readCanonicalNameReference();
389 node.fileEndOffset = readOffset(); 401 Field node = canonicalName.definition;
390 node.flags = readByte(); 402 bool shouldWriteData = node == null || _isReadingLibraryImplementation;
391 node.name = readName(); 403 if (node == null) {
392 node.fileUri = readUriReference(); 404 node = new Field(null);
393 node.annotations = readAnnotationList(node); 405 canonicalName.linkTo(node);
406 }
407 int fileOffset = readOffset();
408 int fileEndOffset = readOffset();
409 int flags = readByte();
410 var name = readName();
411 var fileUri = readUriReference();
412 var annotations = readAnnotationList(node);
394 debugPath.add(node.name?.name ?? 'field'); 413 debugPath.add(node.name?.name ?? 'field');
395 node.type = readDartType(); 414 var type = readDartType();
396 node.inferredValue = readOptionalInferredValue(); 415 var inferredValue = readOptionalInferredValue();
397 node.initializer = readExpressionOption(); 416 var initializer = readExpressionOption();
398 node.initializer?.parent = node; 417 int transformerFlags = getAndResetTransformerFlags();
399 node.transformerFlags = getAndResetTransformerFlags();
400 debugPath.removeLast(); 418 debugPath.removeLast();
419 if (shouldWriteData) {
420 node.fileOffset = fileOffset;
421 node.fileEndOffset = fileEndOffset;
422 node.flags = flags;
423 node.name = name;
424 node.fileUri = fileUri;
425 node.annotations = annotations;
426 node.type = type;
427 node.inferredValue = inferredValue;
428 node.initializer = initializer;
429 node.initializer?.parent = node;
430 node.transformerFlags = transformerFlags;
431 }
432 return node;
401 } 433 }
402 434
403 void readConstructor(Constructor node, int tag) { 435 Constructor readConstructor() {
436 int tag = readByte();
404 assert(tag == Tag.Constructor); 437 assert(tag == Tag.Constructor);
405 node.fileOffset = readOffset(); 438 var canonicalName = readCanonicalNameReference();
406 node.fileEndOffset = readOffset(); 439 Constructor node = canonicalName.definition;
407 node.flags = readByte(); 440 bool shouldWriteData = node == null || _isReadingLibraryImplementation;
408 node.name = readName(); 441 if (node == null) {
409 node.annotations = readAnnotationList(node); 442 node = new Constructor(null);
443 canonicalName.linkTo(node);
444 }
445 var fileOffset = readOffset();
446 var fileEndOffset = readOffset();
447 var flags = readByte();
448 var name = readName();
449 var annotations = readAnnotationList(node);
410 debugPath.add(node.name?.name ?? 'constructor'); 450 debugPath.add(node.name?.name ?? 'constructor');
411 node.function = readFunctionNode()..parent = node; 451 var function = readFunctionNode();
412 pushVariableDeclarations(node.function.positionalParameters); 452 if (_isReadingLibraryImplementation) {
413 pushVariableDeclarations(node.function.namedParameters); 453 pushVariableDeclarations(function.positionalParameters);
414 _fillTreeNodeList(node.initializers, readInitializer, node); 454 pushVariableDeclarations(function.namedParameters);
415 variableStack.length = 0; 455 _fillTreeNodeList(node.initializers, readInitializer, node);
416 node.transformerFlags = getAndResetTransformerFlags(); 456 variableStack.length = 0;
457 } else {
458 // External libraries should not contain constructor initializers.
459 int numberOfInitializers = readUInt();
460 assert(numberOfInitializers == 0);
461 }
462 var transformerFlags = getAndResetTransformerFlags();
417 debugPath.removeLast(); 463 debugPath.removeLast();
464 if (shouldWriteData) {
465 node.fileOffset = fileOffset;
466 node.fileEndOffset = fileEndOffset;
467 node.flags = flags;
468 node.name = name;
469 node.annotations = annotations;
470 node.function = function..parent = node;
471 node.transformerFlags = transformerFlags;
472 }
473 return node;
418 } 474 }
419 475
420 void readProcedure(Procedure node, int tag) { 476 Procedure readProcedure() {
477 int tag = readByte();
421 assert(tag == Tag.Procedure); 478 assert(tag == Tag.Procedure);
422 node.fileOffset = readOffset(); 479 var canonicalName = readCanonicalNameReference();
423 node.fileEndOffset = readOffset(); 480 Procedure node = canonicalName.definition;
481 bool shouldWriteData = node == null || _isReadingLibraryImplementation;
482 if (node == null) {
483 node = new Procedure(null, null, null);
484 canonicalName.linkTo(node);
485 }
486 var fileOffset = readOffset();
487 var fileEndOffset = readOffset();
424 int kindIndex = readByte(); 488 int kindIndex = readByte();
425 node.kind = ProcedureKind.values[kindIndex]; 489 var kind = ProcedureKind.values[kindIndex];
426 node.flags = readByte(); 490 var flags = readByte();
427 node.name = readName(); 491 var name = readName();
428 node.fileUri = readUriReference(); 492 var fileUri = readUriReference();
429 node.annotations = readAnnotationList(node); 493 var annotations = readAnnotationList(node);
430 debugPath.add(node.name?.name ?? 'procedure'); 494 debugPath.add(node.name?.name ?? 'procedure');
431 node.function = readFunctionNodeOption(); 495 var function = readFunctionNodeOption();
432 node.function?.parent = node; 496 var transformerFlags = getAndResetTransformerFlags();
433 node.transformerFlags = getAndResetTransformerFlags();
434 debugPath.removeLast(); 497 debugPath.removeLast();
498 if (shouldWriteData) {
499 node.fileOffset = fileOffset;
500 node.fileEndOffset = fileEndOffset;
501 node.kind = kind;
502 node.flags = flags;
503 node.name = name;
504 node.fileUri = fileUri;
505 node.annotations = annotations;
506 node.function = function;
507 node.function?.parent = node;
508 node.transformerFlags = transformerFlags;
509 }
510 return node;
435 } 511 }
436 512
437 Initializer readInitializer() { 513 Initializer readInitializer() {
438 int tag = readByte(); 514 int tag = readByte();
439 switch (tag) { 515 switch (tag) {
440 case Tag.InvalidInitializer: 516 case Tag.InvalidInitializer:
441 return new InvalidInitializer(); 517 return new InvalidInitializer();
442 case Tag.FieldInitializer: 518 case Tag.FieldInitializer:
443 return new FieldInitializer(readMemberReference(), readExpression()); 519 return new FieldInitializer.byName(
520 readMemberReference(), readExpression());
444 case Tag.SuperInitializer: 521 case Tag.SuperInitializer:
445 return new SuperInitializer(readMemberReference(), readArguments()); 522 return new SuperInitializer.byName(
523 readMemberReference(), readArguments());
446 case Tag.RedirectingInitializer: 524 case Tag.RedirectingInitializer:
447 return new RedirectingInitializer( 525 return new RedirectingInitializer.byName(
448 readMemberReference(), readArguments()); 526 readMemberReference(), readArguments());
449 case Tag.LocalInitializer: 527 case Tag.LocalInitializer:
450 return new LocalInitializer(readAndPushVariableDeclaration()); 528 return new LocalInitializer(readAndPushVariableDeclaration());
451 default: 529 default:
452 throw fail('Invalid initializer tag: $tag'); 530 throw fail('Invalid initializer tag: $tag');
453 } 531 }
454 } 532 }
455 533
456 FunctionNode readFunctionNodeOption() { 534 FunctionNode readFunctionNodeOption() {
457 return readAndCheckOptionTag() ? readFunctionNode() : null; 535 return readAndCheckOptionTag() ? readFunctionNode() : null;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 int offset = readOffset(); 622 int offset = readOffset();
545 return new VariableSet(readVariableReference(), readExpression()) 623 return new VariableSet(readVariableReference(), readExpression())
546 ..fileOffset = offset; 624 ..fileOffset = offset;
547 case Tag.SpecializedVariableSet: 625 case Tag.SpecializedVariableSet:
548 int index = tagByte & Tag.SpecializedPayloadMask; 626 int index = tagByte & Tag.SpecializedPayloadMask;
549 int offset = readOffset(); 627 int offset = readOffset();
550 return new VariableSet(variableStack[index], readExpression()) 628 return new VariableSet(variableStack[index], readExpression())
551 ..fileOffset = offset; 629 ..fileOffset = offset;
552 case Tag.PropertyGet: 630 case Tag.PropertyGet:
553 int offset = readOffset(); 631 int offset = readOffset();
554 return new PropertyGet( 632 return new PropertyGet.byName(
555 readExpression(), readName(), readMemberReference(allowNull: true)) 633 readExpression(), readName(), readMemberReference(allowNull: true))
556 ..fileOffset = offset; 634 ..fileOffset = offset;
557 case Tag.PropertySet: 635 case Tag.PropertySet:
558 int offset = readOffset(); 636 int offset = readOffset();
559 return new PropertySet(readExpression(), readName(), readExpression(), 637 return new PropertySet.byName(
638 readExpression(),
639 readName(),
640 readExpression(),
560 readMemberReference(allowNull: true))..fileOffset = offset; 641 readMemberReference(allowNull: true))..fileOffset = offset;
561 case Tag.SuperPropertyGet: 642 case Tag.SuperPropertyGet:
562 addTransformerFlag(TransformerFlag.superCalls); 643 addTransformerFlag(TransformerFlag.superCalls);
563 return new SuperPropertyGet( 644 return new SuperPropertyGet.byName(
564 readName(), readMemberReference(allowNull: true)); 645 readName(), readMemberReference(allowNull: true));
565 case Tag.SuperPropertySet: 646 case Tag.SuperPropertySet:
566 addTransformerFlag(TransformerFlag.superCalls); 647 addTransformerFlag(TransformerFlag.superCalls);
567 return new SuperPropertySet( 648 return new SuperPropertySet.byName(
568 readName(), readExpression(), readMemberReference(allowNull: true)); 649 readName(), readExpression(), readMemberReference(allowNull: true));
569 case Tag.DirectPropertyGet: 650 case Tag.DirectPropertyGet:
570 return new DirectPropertyGet(readExpression(), readMemberReference()); 651 return new DirectPropertyGet.byName(
652 readExpression(), readMemberReference());
571 case Tag.DirectPropertySet: 653 case Tag.DirectPropertySet:
572 return new DirectPropertySet( 654 return new DirectPropertySet.byName(
573 readExpression(), readMemberReference(), readExpression()); 655 readExpression(), readMemberReference(), readExpression());
574 case Tag.StaticGet: 656 case Tag.StaticGet:
575 int offset = readOffset(); 657 int offset = readOffset();
576 return new StaticGet(readMemberReference())..fileOffset = offset; 658 return new StaticGet.byName(readMemberReference())..fileOffset = offset;
577 case Tag.StaticSet: 659 case Tag.StaticSet:
578 return new StaticSet(readMemberReference(), readExpression()); 660 return new StaticSet.byName(readMemberReference(), readExpression());
579 case Tag.MethodInvocation: 661 case Tag.MethodInvocation:
580 int offset = readOffset(); 662 int offset = readOffset();
581 return new MethodInvocation( 663 return new MethodInvocation.byName(
582 readExpression(), 664 readExpression(),
583 readName(), 665 readName(),
584 readArguments(), 666 readArguments(),
585 readMemberReference(allowNull: true))..fileOffset = offset; 667 readMemberReference(allowNull: true))..fileOffset = offset;
586 case Tag.SuperMethodInvocation: 668 case Tag.SuperMethodInvocation:
587 int offset = readOffset(); 669 int offset = readOffset();
588 addTransformerFlag(TransformerFlag.superCalls); 670 addTransformerFlag(TransformerFlag.superCalls);
589 return new SuperMethodInvocation( 671 return new SuperMethodInvocation.byName(
590 readName(), readArguments(), readMemberReference(allowNull: true)) 672 readName(), readArguments(), readMemberReference(allowNull: true))
591 ..fileOffset = offset; 673 ..fileOffset = offset;
592 case Tag.DirectMethodInvocation: 674 case Tag.DirectMethodInvocation:
593 return new DirectMethodInvocation( 675 return new DirectMethodInvocation.byName(
594 readExpression(), readMemberReference(), readArguments()); 676 readExpression(), readMemberReference(), readArguments());
595 case Tag.StaticInvocation: 677 case Tag.StaticInvocation:
596 int offset = readOffset(); 678 int offset = readOffset();
597 return new StaticInvocation(readMemberReference(), readArguments(), 679 return new StaticInvocation.byName(
598 isConst: false)..fileOffset = offset; 680 readMemberReference(), readArguments(), isConst: false)
681 ..fileOffset = offset;
599 case Tag.ConstStaticInvocation: 682 case Tag.ConstStaticInvocation:
600 int offset = readOffset(); 683 int offset = readOffset();
601 return new StaticInvocation(readMemberReference(), readArguments(), 684 return new StaticInvocation.byName(
602 isConst: true)..fileOffset = offset; 685 readMemberReference(), readArguments(), isConst: true)
686 ..fileOffset = offset;
603 case Tag.ConstructorInvocation: 687 case Tag.ConstructorInvocation:
604 int offset = readOffset(); 688 int offset = readOffset();
605 return new ConstructorInvocation(readMemberReference(), readArguments(), 689 return new ConstructorInvocation.byName(
606 isConst: false)..fileOffset = offset; 690 readMemberReference(), readArguments(), isConst: false)
691 ..fileOffset = offset;
607 case Tag.ConstConstructorInvocation: 692 case Tag.ConstConstructorInvocation:
608 int offset = readOffset(); 693 int offset = readOffset();
609 return new ConstructorInvocation(readMemberReference(), readArguments(), 694 return new ConstructorInvocation.byName(
610 isConst: true)..fileOffset = offset; 695 readMemberReference(), readArguments(), isConst: true)
696 ..fileOffset = offset;
611 case Tag.Not: 697 case Tag.Not:
612 return new Not(readExpression()); 698 return new Not(readExpression());
613 case Tag.LogicalExpression: 699 case Tag.LogicalExpression:
614 return new LogicalExpression(readExpression(), 700 return new LogicalExpression(readExpression(),
615 logicalOperatorToString(readByte()), readExpression()); 701 logicalOperatorToString(readByte()), readExpression());
616 case Tag.ConditionalExpression: 702 case Tag.ConditionalExpression:
617 return new ConditionalExpression(readExpression(), readExpression(), 703 return new ConditionalExpression(readExpression(), readExpression(),
618 readExpression(), readDartTypeOption()); 704 readExpression(), readDartTypeOption());
619 case Tag.StringConcatenation: 705 case Tag.StringConcatenation:
620 int offset = readOffset(); 706 int offset = readOffset();
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 915
830 Block readBlock() { 916 Block readBlock() {
831 int stackHeight = variableStack.length; 917 int stackHeight = variableStack.length;
832 var body = readStatementList(); 918 var body = readStatementList();
833 variableStack.length = stackHeight; 919 variableStack.length = stackHeight;
834 return new Block(body); 920 return new Block(body);
835 } 921 }
836 922
837 Supertype readSupertype() { 923 Supertype readSupertype() {
838 InterfaceType type = readDartType(); 924 InterfaceType type = readDartType();
839 return new Supertype(type.classNode, type.typeArguments); 925 return new Supertype.byName(type.className, type.typeArguments);
840 } 926 }
841 927
842 Supertype readSupertypeOption() { 928 Supertype readSupertypeOption() {
843 return readAndCheckOptionTag() ? readSupertype() : null; 929 return readAndCheckOptionTag() ? readSupertype() : null;
844 } 930 }
845 931
846 List<Supertype> readSupertypeList() { 932 List<Supertype> readSupertypeList() {
847 return new List<Supertype>.generate(readUInt(), (i) => readSupertype()); 933 return new List<Supertype>.generate(readUInt(), (i) => readSupertype());
848 } 934 }
849 935
(...skipping 18 matching lines...) Expand all
868 switch (tag) { 954 switch (tag) {
869 case Tag.BottomType: 955 case Tag.BottomType:
870 return const BottomType(); 956 return const BottomType();
871 case Tag.InvalidType: 957 case Tag.InvalidType:
872 return const InvalidType(); 958 return const InvalidType();
873 case Tag.DynamicType: 959 case Tag.DynamicType:
874 return const DynamicType(); 960 return const DynamicType();
875 case Tag.VoidType: 961 case Tag.VoidType:
876 return const VoidType(); 962 return const VoidType();
877 case Tag.InterfaceType: 963 case Tag.InterfaceType:
878 return new InterfaceType(readClassReference(), readDartTypeList()); 964 return new InterfaceType.byName(
965 readClassReference(), readDartTypeList());
879 case Tag.SimpleInterfaceType: 966 case Tag.SimpleInterfaceType:
880 return new InterfaceType(readClassReference(), const <DartType>[]); 967 return new InterfaceType.byName(
968 readClassReference(), const <DartType>[]);
881 case Tag.FunctionType: 969 case Tag.FunctionType:
882 int typeParameterStackHeight = typeParameterStack.length; 970 int typeParameterStackHeight = typeParameterStack.length;
883 var typeParameters = readAndPushTypeParameterList(); 971 var typeParameters = readAndPushTypeParameterList();
884 var requiredParameterCount = readUInt(); 972 var requiredParameterCount = readUInt();
885 var positional = readDartTypeList(); 973 var positional = readDartTypeList();
886 var named = readNamedTypeList(); 974 var named = readNamedTypeList();
887 var returnType = readDartType(); 975 var returnType = readDartType();
888 typeParameterStack.length = typeParameterStackHeight; 976 typeParameterStack.length = typeParameterStackHeight;
889 return new FunctionType(positional, returnType, 977 return new FunctionType(positional, returnType,
890 typeParameters: typeParameters, 978 typeParameters: typeParameters,
(...skipping 11 matching lines...) Expand all
902 } 990 }
903 } 991 }
904 992
905 List<TypeParameter> readAndPushTypeParameterList( 993 List<TypeParameter> readAndPushTypeParameterList(
906 [List<TypeParameter> list, TreeNode parent]) { 994 [List<TypeParameter> list, TreeNode parent]) {
907 int length = readUInt(); 995 int length = readUInt();
908 if (length == 0) return list ?? <TypeParameter>[]; 996 if (length == 0) return list ?? <TypeParameter>[];
909 if (list == null) { 997 if (list == null) {
910 list = new List<TypeParameter>.generate( 998 list = new List<TypeParameter>.generate(
911 length, (i) => new TypeParameter(null, null)..parent = parent); 999 length, (i) => new TypeParameter(null, null)..parent = parent);
912 } else { 1000 } else if (list.length != length) {
913 list.length = length; 1001 list.length = length;
914 for (int i = 0; i < length; ++i) { 1002 for (int i = 0; i < length; ++i) {
915 list[i] = new TypeParameter(null, null)..parent = parent; 1003 list[i] = new TypeParameter(null, null)..parent = parent;
916 } 1004 }
917 } 1005 }
918 typeParameterStack.addAll(list); 1006 typeParameterStack.addAll(list);
919 for (int i = 0; i < list.length; ++i) { 1007 for (int i = 0; i < list.length; ++i) {
920 readTypeParameter(list[i]); 1008 readTypeParameter(list[i]);
921 } 1009 }
922 return list; 1010 return list;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 isFinal: flags & 0x1 != 0, 1056 isFinal: flags & 0x1 != 0,
969 isConst: flags & 0x2 != 0)..fileOffset = offset; 1057 isConst: flags & 0x2 != 0)..fileOffset = offset;
970 } 1058 }
971 1059
972 int readOffset() { 1060 int readOffset() {
973 // Offset is saved as unsigned, 1061 // Offset is saved as unsigned,
974 // but actually ranges from -1 and up (thus the -1) 1062 // but actually ranges from -1 and up (thus the -1)
975 return readUInt() - 1; 1063 return readUInt() - 1;
976 } 1064 }
977 } 1065 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698