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

Side by Side Diff: pkg/analyzer/lib/src/summary/resynthesize.dart

Issue 1660663002: Resynthesize generic class instance creations. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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) 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 library summary_resynthesizer; 5 library summary_resynthesizer;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/element/element.dart'; 10 import 'package:analyzer/dart/element/element.dart';
11 import 'package:analyzer/dart/element/type.dart'; 11 import 'package:analyzer/dart/element/type.dart';
12 import 'package:analyzer/src/dart/element/element.dart'; 12 import 'package:analyzer/src/dart/element/element.dart';
13 import 'package:analyzer/src/dart/element/member.dart';
13 import 'package:analyzer/src/dart/element/type.dart'; 14 import 'package:analyzer/src/dart/element/type.dart';
14 import 'package:analyzer/src/generated/element_handle.dart'; 15 import 'package:analyzer/src/generated/element_handle.dart';
15 import 'package:analyzer/src/generated/engine.dart'; 16 import 'package:analyzer/src/generated/engine.dart';
16 import 'package:analyzer/src/generated/resolver.dart'; 17 import 'package:analyzer/src/generated/resolver.dart';
17 import 'package:analyzer/src/generated/scanner.dart'; 18 import 'package:analyzer/src/generated/scanner.dart';
18 import 'package:analyzer/src/generated/source_io.dart'; 19 import 'package:analyzer/src/generated/source_io.dart';
19 import 'package:analyzer/src/generated/testing/ast_factory.dart'; 20 import 'package:analyzer/src/generated/testing/ast_factory.dart';
20 import 'package:analyzer/src/generated/testing/token_factory.dart'; 21 import 'package:analyzer/src/generated/testing/token_factory.dart';
21 import 'package:analyzer/src/generated/utilities_dart.dart'; 22 import 'package:analyzer/src/generated/utilities_dart.dart';
22 import 'package:analyzer/src/summary/format.dart'; 23 import 'package:analyzer/src/summary/format.dart';
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 List<TypeName> argumentNodes = 443 List<TypeName> argumentNodes =
443 type.typeArguments.map(_buildTypeAst).toList(); 444 type.typeArguments.map(_buildTypeAst).toList();
444 TypeName node = AstFactory.typeName4(type.name, argumentNodes); 445 TypeName node = AstFactory.typeName4(type.name, argumentNodes);
445 node.type = type; 446 node.type = type;
446 (node.name as SimpleIdentifier).staticElement = type.element; 447 (node.name as SimpleIdentifier).staticElement = type.element;
447 return node; 448 return node;
448 } 449 }
449 throw new StateError('Unsupported type $type'); 450 throw new StateError('Unsupported type $type');
450 } 451 }
451 452
453 /**
454 * Return the [ConstructorElement] for the given [ref] and its linked [info].
455 * Both cases when [info] is a [ClassElement] and [ConstructorElement] are
456 * supported. [ref] is used to get the type arguments and the name of the
457 * constructor.
458 */
459 _DeferredConstructorElement _createConstructorElement(
460 EntityRef ref, _ReferenceInfo info) {
461 bool isClass = info.element is ClassElement;
462 _ReferenceInfo classInfo = isClass ? info : info.enclosing;
463 List<DartType> typeArguments =
464 ref.typeArguments.map(resynthesizer.buildType).toList();
465 InterfaceType classType =
466 classInfo.buildType((i) => typeArguments[i], const <int>[]);
467 String name = isClass ? '' : info.name;
468 return new _DeferredConstructorElement(classType, name);
469 }
470
452 InterpolationElement _newInterpolationElement(Expression expr) { 471 InterpolationElement _newInterpolationElement(Expression expr) {
453 if (expr is SimpleStringLiteral) { 472 if (expr is SimpleStringLiteral) {
454 return new InterpolationString(expr.literal, expr.value); 473 return new InterpolationString(expr.literal, expr.value);
455 } else { 474 } else {
456 return new InterpolationExpression( 475 return new InterpolationExpression(
457 TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION), 476 TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION),
458 expr, 477 expr,
459 TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET)); 478 TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
460 } 479 }
461 } 480 }
(...skipping 17 matching lines...) Expand all
479 void _pushBinary(TokenType operator) { 498 void _pushBinary(TokenType operator) {
480 Expression right = _pop(); 499 Expression right = _pop();
481 Expression left = _pop(); 500 Expression left = _pop();
482 _push(AstFactory.binaryExpression(left, operator, right)); 501 _push(AstFactory.binaryExpression(left, operator, right));
483 } 502 }
484 503
485 void _pushInstanceCreation() { 504 void _pushInstanceCreation() {
486 EntityRef ref = uc.references[refPtr++]; 505 EntityRef ref = uc.references[refPtr++];
487 _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference]; 506 _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
488 // prepare ClassElement / ConstructorElement 507 // prepare ClassElement / ConstructorElement
489 String className;
490 ClassElement classElement;
491 String constructorName; 508 String constructorName;
492 ConstructorElement constructorElement; 509 _DeferredConstructorElement constructorElement;
493 if (info.element is ConstructorElement) { 510 if (info.element is ConstructorElement) {
494 constructorName = info.name; 511 constructorName = info.name;
495 constructorElement = info.element; 512 constructorElement = _createConstructorElement(ref, info);
Paul Berry 2016/02/02 22:01:16 Nit: since the logic is the same for both construc
scheglov 2016/02/02 22:28:04 Ah, yes. This code used to be much more complex an
496 className = info.enclosing.name;
497 classElement = info.enclosing.element as ClassElement;
498 } else if (info.element is ClassElement) { 513 } else if (info.element is ClassElement) {
499 className = info.name;
500 classElement = info.element;
501 constructorName = null; 514 constructorName = null;
502 constructorElement = new ConstructorElementHandle( 515 constructorElement = _createConstructorElement(ref, info);
503 resynthesizer.summaryResynthesizer,
504 new ElementLocationImpl.con3(
505 classElement.location.components.toList()..add('')));
506 } else { 516 } else {
507 throw new StateError('Unsupported element for invokeConstructor ' 517 throw new StateError('Unsupported element for invokeConstructor '
508 '${info.element?.runtimeType}'); 518 '${info.element?.runtimeType}');
509 } 519 }
510 // prepare arguments 520 // prepare arguments
511 List<Expression> arguments; 521 List<Expression> arguments;
512 { 522 {
513 int numNamedArgs = uc.ints[intPtr++]; 523 int numNamedArgs = uc.ints[intPtr++];
514 int numPositionalArgs = uc.ints[intPtr++]; 524 int numPositionalArgs = uc.ints[intPtr++];
515 int numArgs = numNamedArgs + numPositionalArgs; 525 int numArgs = numNamedArgs + numPositionalArgs;
516 arguments = _removeTopItems(numArgs); 526 arguments = _removeTopItems(numArgs);
517 // add names to the named arguments 527 // add names to the named arguments
518 for (int i = 0; i < numNamedArgs; i++) { 528 for (int i = 0; i < numNamedArgs; i++) {
519 String name = uc.strings[stringPtr++]; 529 String name = uc.strings[stringPtr++];
520 int index = numPositionalArgs + i; 530 int index = numPositionalArgs + i;
521 arguments[index] = AstFactory.namedExpression2(name, arguments[index]); 531 arguments[index] = AstFactory.namedExpression2(name, arguments[index]);
522 } 532 }
523 } 533 }
524 // create TypeName 534 // create TypeName
525 SimpleIdentifier typeNameNode = AstFactory.identifier3(className); 535 TypeName typeNode = _buildTypeAst(constructorElement.definingType);
526 typeNameNode.staticElement = classElement;
527 TypeName typeNode = AstFactory.typeName3(typeNameNode);
528 // create ConstructorName 536 // create ConstructorName
529 ConstructorName constructorNode; 537 ConstructorName constructorNode;
530 if (constructorName != null) { 538 if (constructorName != null) {
531 constructorNode = AstFactory.constructorName(typeNode, info.name); 539 constructorNode = AstFactory.constructorName(typeNode, constructorName);
532 constructorNode.name.staticElement = constructorElement; 540 constructorNode.name.staticElement = constructorElement;
533 } else { 541 } else {
534 constructorNode = AstFactory.constructorName(typeNode, null); 542 constructorNode = AstFactory.constructorName(typeNode, null);
535 } 543 }
536 constructorNode.staticElement = constructorElement; 544 constructorNode.staticElement = constructorElement;
537 // create InstanceCreationExpression 545 // create InstanceCreationExpression
538 InstanceCreationExpression instanceCreation = AstFactory 546 InstanceCreationExpression instanceCreation = AstFactory
539 .instanceCreationExpression(Keyword.CONST, constructorNode, arguments); 547 .instanceCreationExpression(Keyword.CONST, constructorNode, arguments);
540 instanceCreation.staticElement = constructorElement; 548 instanceCreation.staticElement = constructorElement;
541 _push(instanceCreation); 549 _push(instanceCreation);
(...skipping 27 matching lines...) Expand all
569 List<Expression> _removeTopItems(int count) { 577 List<Expression> _removeTopItems(int count) {
570 int start = stack.length - count; 578 int start = stack.length - count;
571 int end = stack.length; 579 int end = stack.length;
572 List<Expression> items = stack.getRange(start, end).toList(); 580 List<Expression> items = stack.getRange(start, end).toList();
573 stack.removeRange(start, end); 581 stack.removeRange(start, end);
574 return items; 582 return items;
575 } 583 }
576 } 584 }
577 585
578 /** 586 /**
587 * The constructor element that has been resynthesized from a summary. The
588 * actual element won't be constructed until it is requested. But properties
589 * [definingType], [displayName], [enclosingElement] and [name] can be used
590 * without creating the actual element.
591 */
592 class _DeferredConstructorElement extends ConstructorElementHandle {
593 final InterfaceType definingType;
594 final String name;
595
596 factory _DeferredConstructorElement(InterfaceType definingType, String name) {
597 List<String> components = definingType.element.location.components.toList();
598 components.add(name);
599 ElementLocationImpl location = new ElementLocationImpl.con3(components);
600 return new _DeferredConstructorElement._(definingType, name, location);
601 }
602
603 _DeferredConstructorElement._(
604 this.definingType, this.name, ElementLocation location)
605 : super(null, location);
606
607 @override
608 Element get actualElement {
609 ConstructorElement element = enclosingElement.getNamedConstructor(name);
610 return new ConstructorMember(element, definingType);
611 }
612
613 @override
614 String get displayName => name;
615
616 @override
617 ClassElement get enclosingElement {
618 return definingType.element;
619 }
620 }
621
622 /**
579 * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the 623 * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the
580 * elements in a single library from that library's summary. 624 * elements in a single library from that library's summary.
581 */ 625 */
582 class _LibraryResynthesizer { 626 class _LibraryResynthesizer {
583 /** 627 /**
584 * The [SummaryResynthesizer] which is being used to obtain summaries. 628 * The [SummaryResynthesizer] which is being used to obtain summaries.
585 */ 629 */
586 final SummaryResynthesizer summaryResynthesizer; 630 final SummaryResynthesizer summaryResynthesizer;
587 631
588 /** 632 /**
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 int containingReference; 1563 int containingReference;
1520 if (i < numUnlinkedReferences) { 1564 if (i < numUnlinkedReferences) {
1521 name = unlinkedUnit.references[i].name; 1565 name = unlinkedUnit.references[i].name;
1522 containingReference = unlinkedUnit.references[i].prefixReference; 1566 containingReference = unlinkedUnit.references[i].prefixReference;
1523 } else { 1567 } else {
1524 name = linkedUnit.references[i].name; 1568 name = linkedUnit.references[i].name;
1525 containingReference = linkedUnit.references[i].containingReference; 1569 containingReference = linkedUnit.references[i].containingReference;
1526 } 1570 }
1527 Element element; 1571 Element element;
1528 DartType type; 1572 DartType type;
1573 int numTypeParameters = linkedReference.numTypeParameters;
1529 if (linkedReference.kind == ReferenceKind.unresolved) { 1574 if (linkedReference.kind == ReferenceKind.unresolved) {
1530 type = summaryResynthesizer.typeProvider.undefinedType; 1575 type = summaryResynthesizer.typeProvider.undefinedType;
1531 element = type.element; 1576 element = type.element;
1532 } else if (name == 'dynamic') { 1577 } else if (name == 'dynamic') {
1533 type = summaryResynthesizer.typeProvider.dynamicType; 1578 type = summaryResynthesizer.typeProvider.dynamicType;
1534 element = type.element; 1579 element = type.element;
1535 } else if (name == 'void') { 1580 } else if (name == 'void') {
1536 type = VoidTypeImpl.instance; 1581 type = VoidTypeImpl.instance;
1537 element = type.element; 1582 element = type.element;
1538 } else { 1583 } else {
(...skipping 21 matching lines...) Expand all
1560 summaryResynthesizer, location); 1605 summaryResynthesizer, location);
1561 break; 1606 break;
1562 case ReferenceKind.topLevelPropertyAccessor: 1607 case ReferenceKind.topLevelPropertyAccessor:
1563 element = new PropertyAccessorElementHandle( 1608 element = new PropertyAccessorElementHandle(
1564 summaryResynthesizer, location); 1609 summaryResynthesizer, location);
1565 break; 1610 break;
1566 case ReferenceKind.constructor: 1611 case ReferenceKind.constructor:
1567 assert(location.components.length == 4); 1612 assert(location.components.length == 4);
1568 element = 1613 element =
1569 new ConstructorElementHandle(summaryResynthesizer, location); 1614 new ConstructorElementHandle(summaryResynthesizer, location);
1615 numTypeParameters = enclosingInfo.numTypeParameters;
1570 break; 1616 break;
1571 case ReferenceKind.propertyAccessor: 1617 case ReferenceKind.propertyAccessor:
1572 assert(location.components.length == 4); 1618 assert(location.components.length == 4);
1573 element = new PropertyAccessorElementHandle( 1619 element = new PropertyAccessorElementHandle(
1574 summaryResynthesizer, location); 1620 summaryResynthesizer, location);
1575 break; 1621 break;
1576 case ReferenceKind.method: 1622 case ReferenceKind.method:
1577 assert(location.components.length == 4); 1623 assert(location.components.length == 4);
1578 element = new MethodElementHandle(summaryResynthesizer, location); 1624 element = new MethodElementHandle(summaryResynthesizer, location);
1579 break; 1625 break;
1580 default: 1626 default:
1581 // This is an element that doesn't (yet) need to be referred to 1627 // This is an element that doesn't (yet) need to be referred to
1582 // directly, so don't bother populating an element for it. 1628 // directly, so don't bother populating an element for it.
1583 // TODO(paulberry): add support for more kinds, as needed. 1629 // TODO(paulberry): add support for more kinds, as needed.
1584 break; 1630 break;
1585 } 1631 }
1586 } 1632 }
1587 referenceInfos[i] = new _ReferenceInfo(enclosingInfo, name, element, type, 1633 referenceInfos[i] = new _ReferenceInfo(
1588 linkedReference.numTypeParameters); 1634 enclosingInfo, name, element, type, numTypeParameters);
1589 } 1635 }
1590 } 1636 }
1591 1637
1592 /** 1638 /**
1593 * Populate a [CompilationUnitElement] by deserializing all the elements 1639 * Populate a [CompilationUnitElement] by deserializing all the elements
1594 * contained in it. 1640 * contained in it.
1595 */ 1641 */
1596 void populateUnit(CompilationUnitElementImpl unit, int unitNum) { 1642 void populateUnit(CompilationUnitElementImpl unit, int unitNum) {
1597 linkedUnit = linkedLibrary.units[unitNum]; 1643 linkedUnit = linkedLibrary.units[unitNum];
1598 unlinkedUnit = unlinkedUnits[unitNum]; 1644 unlinkedUnit = unlinkedUnits[unitNum];
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1778 } 1824 }
1779 : () => this.element; 1825 : () => this.element;
1780 // TODO(paulberry): Is it a bug that we have to pass `false` for 1826 // TODO(paulberry): Is it a bug that we have to pass `false` for
1781 // isInstantiated? 1827 // isInstantiated?
1782 return new DeferredFunctionTypeImpl(computer, null, typeArguments, false); 1828 return new DeferredFunctionTypeImpl(computer, null, typeArguments, false);
1783 } else { 1829 } else {
1784 return null; 1830 return null;
1785 } 1831 }
1786 } 1832 }
1787 } 1833 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/element/type.dart ('k') | pkg/analyzer/test/src/summary/resynthesize_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698