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

Side by Side Diff: pkg/analyzer/tool/summary/generate.dart

Issue 1579663002: Cache values of fields and lists in summary implementations. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 /** 5 /**
6 * This file contains code to generate serialization/deserialization logic for 6 * This file contains code to generate serialization/deserialization logic for
7 * summaries based on an "IDL" description of the summary format (written in 7 * summaries based on an "IDL" description of the summary format (written in
8 * stylized Dart). 8 * stylized Dart).
9 * 9 *
10 * For each class in the "IDL" input, two corresponding classes are generated: 10 * For each class in the "IDL" input, two corresponding classes are generated:
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 }); 274 });
275 for (var cls in _idl.classes.values) { 275 for (var cls in _idl.classes.values) {
276 List<String> builderParams = _generateBuilder(cls); 276 List<String> builderParams = _generateBuilder(cls);
277 out(); 277 out();
278 _generateEncodeFunction(cls, builderParams); 278 _generateEncodeFunction(cls, builderParams);
279 out(); 279 out();
280 _generateInterface(cls); 280 _generateInterface(cls);
281 out(); 281 out();
282 _generateReader(cls); 282 _generateReader(cls);
283 out(); 283 out();
284 _generateImpl(cls);
285 out();
284 } 286 }
285 } 287 }
286 288
287 /** 289 /**
288 * Enclose [s] in quotes, escaping as necessary. 290 * Enclose [s] in quotes, escaping as necessary.
289 */ 291 */
290 String quoted(String s) { 292 String quoted(String s) {
291 return JSON.encode(s); 293 return JSON.encode(s);
292 } 294 }
293 295
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 out('$builderName builder = new $builderName();'); 436 out('$builderName builder = new $builderName();');
435 for (idlModel.FieldDeclaration field in cls.fields) { 437 for (idlModel.FieldDeclaration field in cls.fields) {
436 String fieldName = field.name; 438 String fieldName = field.name;
437 out('builder.$fieldName = $fieldName;'); 439 out('builder.$fieldName = $fieldName;');
438 } 440 }
439 out('return builder;'); 441 out('return builder;');
440 }); 442 });
441 out('}'); 443 out('}');
442 } 444 }
443 445
444 void _generateInterface(idlModel.ClassDeclaration cls) { 446 void _generateImpl(idlModel.ClassDeclaration cls) {
445 String name = cls.name; 447 String name = cls.name;
446 outDoc(cls.documentation); 448 String implName = '_${name}Impl';
447 out('abstract class $name extends base.SummaryClass {'); 449 out('class $implName implements $name {');
448 indent(() {
449 if (cls.isTopLevel) {
450 out('factory $name.fromBuffer(List<int> buffer) {');
451 indent(() {
452 out('fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer) ;');
453 out('return const _${name}Reader().read(rootRef);');
454 });
455 out('}');
456 }
457 cls.fields.asMap().forEach((index, field) {
458 String fieldName = field.name;
459 idlModel.FieldType type = field.type;
460 out();
461 outDoc(field.documentation);
462 out('${dartType(type)} get $fieldName;');
463 });
464 });
465 out('}');
466 }
467
468 void _generateReader(idlModel.ClassDeclaration cls) {
469 String name = cls.name;
470 String readerName = '_${name}Reader';
471 out('class $readerName extends fb.TableReader<$readerName> implements $name {');
472 indent(() { 450 indent(() {
473 out('final fb.BufferPointer _bp;'); 451 out('final fb.BufferPointer _bp;');
474 out(); 452 out();
475 out('const $readerName([this._bp]);'); 453 out('$implName(this._bp);');
476 out(); 454 out();
477 out('@override'); 455 // Write cache fields.
478 out('$readerName createReader(fb.BufferPointer bp) => new $readerName(bp); '); 456 for (idlModel.FieldDeclaration field in cls.fields) {
457 String returnType = dartType(field.type);
458 String fieldName = field.name;
459 out('$returnType _$fieldName;');
460 }
479 out(); 461 out();
480 // Write toMap(). 462 // Write toMap().
481 out('@override'); 463 out('@override');
482 out('Map<String, Object> toMap() => {'); 464 out('Map<String, Object> toMap() => {');
483 indent(() { 465 indent(() {
484 for (idlModel.FieldDeclaration field in cls.fields) { 466 for (idlModel.FieldDeclaration field in cls.fields) {
485 String fieldName = field.name; 467 String fieldName = field.name;
486 out('${quoted(fieldName)}: $fieldName,'); 468 out('${quoted(fieldName)}: $fieldName,');
487 } 469 }
488 }); 470 });
489 out('};'); 471 out('};');
490 // Write getters. 472 // Write getters.
491 cls.fields.asMap().forEach((index, field) { 473 cls.fields.asMap().forEach((index, field) {
492 String fieldName = field.name; 474 String fieldName = field.name;
493 idlModel.FieldType type = field.type; 475 idlModel.FieldType type = field.type;
494 String typeName = type.typeName; 476 String typeName = type.typeName;
495 // Prepare "readLines" or "readCode" + "def" + "readSuffix" 477 // Prepare "readExpr" or "readCode" + "def"
496 List<String> readLines; 478 String readExpr;
497 String readCode; 479 String readCode;
498 String def = defaultValue(type); 480 String def = defaultValue(type);
499 if (type.isList) { 481 if (type.isList) {
500 if (typeName == 'int') { 482 if (typeName == 'int') {
501 String itemCode = 'const fb.Int32Reader()'; 483 String itemCode = 'const fb.Int32Reader()';
502 readCode = 'const fb.ListReader<int>($itemCode)'; 484 readCode = 'const fb.ListReader<int>($itemCode)';
503 } else if (typeName == 'String') { 485 } else if (typeName == 'String') {
504 String itemCode = 'const fb.StringReader()'; 486 String itemCode = 'const fb.StringReader()';
505 readCode = 'const fb.ListReader<String>($itemCode)'; 487 readCode = 'const fb.ListReader<String>($itemCode)';
506 } else { 488 } else {
507 String itemCode = '$typeName>(const _${typeName}Reader()'; 489 String itemCode = '$typeName>(const _${typeName}Reader()';
508 readCode = 'const fb.ListReader<$itemCode)'; 490 readCode = 'const fb.ListReader<$itemCode)';
509 } 491 }
510 } else if (typeName == 'bool') { 492 } else if (typeName == 'bool') {
511 readCode = 'const fb.BoolReader()'; 493 readCode = 'const fb.BoolReader()';
512 } else if (typeName == 'int') { 494 } else if (typeName == 'int') {
513 readCode = 'const fb.Int32Reader()'; 495 readCode = 'const fb.Int32Reader()';
514 } else if (typeName == 'String') { 496 } else if (typeName == 'String') {
515 readCode = 'const fb.StringReader()'; 497 readCode = 'const fb.StringReader()';
516 } else if (_idl.enums.containsKey(typeName)) { 498 } else if (_idl.enums.containsKey(typeName)) {
517 readLines = <String>[ 499 readExpr =
518 'int index = const fb.Int32Reader().vTableGet(_bp, $index, 0);', 500 '$typeName.values[const fb.Int32Reader().vTableGet(_bp, $index, 0) ]';
519 'return $typeName.values[index];'
520 ];
521 } else if (_idl.classes.containsKey(typeName)) { 501 } else if (_idl.classes.containsKey(typeName)) {
522 readCode = 'const _${typeName}Reader()'; 502 readCode = 'const _${typeName}Reader()';
523 } 503 }
524 assert(readCode != null || readLines != null); 504 if (readExpr == null) {
505 assert(readCode != null);
506 readExpr = '$readCode.vTableGet(_bp, $index, $def)';
507 }
525 // Write the getter implementation. 508 // Write the getter implementation.
526 out(); 509 out();
527 out('@override'); 510 out('@override');
528 String returnType = dartType(type); 511 String returnType = dartType(type);
529 if (readLines != null) { 512 out('$returnType get $fieldName {');
530 out('$returnType get $fieldName {'); 513 indent(() {
531 indent(() { 514 out('_$fieldName ??= $readExpr;');
532 readLines.forEach(out); 515 out('return _$fieldName;');
533 }); 516 });
534 out('}'); 517 out('}');
535 } else {
536 String expr = '$readCode.vTableGet(_bp, $index, $def)';
537 out('$returnType get $fieldName => $expr;');
538 }
539 }); 518 });
540 }); 519 });
541 out('}'); 520 out('}');
542 } 521 }
543 522
523 void _generateInterface(idlModel.ClassDeclaration cls) {
524 String name = cls.name;
525 outDoc(cls.documentation);
526 out('abstract class $name extends base.SummaryClass {');
527 indent(() {
528 if (cls.isTopLevel) {
529 out('factory $name.fromBuffer(List<int> buffer) {');
530 indent(() {
531 out('fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer) ;');
532 out('return const _${name}Reader().read(rootRef);');
533 });
534 out('}');
535 }
536 cls.fields.asMap().forEach((index, field) {
537 String fieldName = field.name;
538 idlModel.FieldType type = field.type;
539 out();
540 outDoc(field.documentation);
541 out('${dartType(type)} get $fieldName;');
542 });
543 });
544 out('}');
545 }
546
547 void _generateReader(idlModel.ClassDeclaration cls) {
548 String name = cls.name;
549 String readerName = '_${name}Reader';
550 String implName = '_${name}Impl';
551 out('class $readerName extends fb.TableReader<$implName> {');
552 indent(() {
553 out('const $readerName();');
554 out();
555 out('@override');
556 out('$implName createObject(fb.BufferPointer bp) => new $implName(bp);');
557 });
558 out('}');
559 }
560
544 /** 561 /**
545 * Return the documentation text of the given [node], or `null` if the [node] 562 * Return the documentation text of the given [node], or `null` if the [node]
546 * does not have a comment. Each line is `\n` separated. 563 * does not have a comment. Each line is `\n` separated.
547 */ 564 */
548 String _getNodeDoc(LineInfo lineInfo, AnnotatedNode node) { 565 String _getNodeDoc(LineInfo lineInfo, AnnotatedNode node) {
549 Comment comment = node.documentationComment; 566 Comment comment = node.documentationComment;
550 if (comment != null && 567 if (comment != null &&
551 comment.isDocumentation && 568 comment.isDocumentation &&
552 comment.tokens.length == 1 && 569 comment.tokens.length == 1 &&
553 comment.tokens.first.type == TokenType.MULTI_LINE_COMMENT) { 570 comment.tokens.first.type == TokenType.MULTI_LINE_COMMENT) {
554 Token token = comment.tokens.first; 571 Token token = comment.tokens.first;
555 int column = lineInfo.getLocation(token.offset).columnNumber; 572 int column = lineInfo.getLocation(token.offset).columnNumber;
556 String indent = ' ' * (column - 1); 573 String indent = ' ' * (column - 1);
557 return token.lexeme.split('\n').map((String line) { 574 return token.lexeme.split('\n').map((String line) {
558 if (line.startsWith(indent)) { 575 if (line.startsWith(indent)) {
559 line = line.substring(indent.length); 576 line = line.substring(indent.length);
560 } 577 }
561 return line; 578 return line;
562 }).join('\n'); 579 }).join('\n');
563 } 580 }
564 return null; 581 return null;
565 } 582 }
566 } 583 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698