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

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

Issue 1657033002: Resynthesize instance creation expressions. (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
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/resynthesize_test.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) 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';
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference]; 415 _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
416 if (info.element != null) { 416 if (info.element != null) {
417 SimpleIdentifier node = AstFactory.identifier3(info.name); 417 SimpleIdentifier node = AstFactory.identifier3(info.name);
418 node.staticElement = info.element; 418 node.staticElement = info.element;
419 _push(node); 419 _push(node);
420 } else { 420 } else {
421 throw new StateError('Unsupported reference ${ref.toMap()}'); 421 throw new StateError('Unsupported reference ${ref.toMap()}');
422 } 422 }
423 break; 423 break;
424 case UnlinkedConstOperation.invokeConstructor: 424 case UnlinkedConstOperation.invokeConstructor:
425 _pushInstanceCreation();
426 break;
425 case UnlinkedConstOperation.length: 427 case UnlinkedConstOperation.length:
426 return AstFactory.nullLiteral(); 428 return AstFactory.nullLiteral();
427 // throw new StateError('Unsupported constant operation $operation'); 429 // throw new StateError('Unsupported constant operation $operation');
428 } 430 }
429 } 431 }
430 return stack.single; 432 return stack.single;
431 } 433 }
432 434
433 TypeName _buildTypeAst(DartType type) { 435 TypeName _buildTypeAst(DartType type) {
434 if (type is DynamicTypeImpl) { 436 if (type is DynamicTypeImpl) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 void _push(Expression expr) { 475 void _push(Expression expr) {
474 stack.add(expr); 476 stack.add(expr);
475 } 477 }
476 478
477 void _pushBinary(TokenType operator) { 479 void _pushBinary(TokenType operator) {
478 Expression right = _pop(); 480 Expression right = _pop();
479 Expression left = _pop(); 481 Expression left = _pop();
480 _push(AstFactory.binaryExpression(left, operator, right)); 482 _push(AstFactory.binaryExpression(left, operator, right));
481 } 483 }
482 484
485 void _pushInstanceCreation() {
486 EntityRef ref = uc.references[refPtr++];
487 _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
488 // prepare ClassElement / ConstructorElement
489 String className;
490 ClassElement classElement;
491 String constructorName;
492 ConstructorElement constructorElement;
493 if (info.element is ConstructorElement) {
494 constructorName = info.name;
495 constructorElement = info.element;
496 className = info.enclosing.name;
497 classElement = info.enclosing.element as ClassElement;
498 } else if (info.element is ClassElement) {
499 className = info.name;
500 classElement = info.element;
501 constructorName = null;
502 constructorElement = new ConstructorElementHandle(
503 resynthesizer.summaryResynthesizer,
504 new ElementLocationImpl.con3(
505 classElement.location.components.toList()..add('')));
506 } else {
507 throw new StateError('Unsupported element for invokeConstructor '
508 '${info.element?.runtimeType}');
509 }
510 // prepare arguments
511 List<Expression> arguments;
512 {
513 int numNamedArgs = uc.ints[intPtr++];
514 int numPositionalArgs = uc.ints[intPtr++];
515 int numArgs = numNamedArgs + numPositionalArgs;
516 arguments = _removeTopItems(numArgs);
517 // add names to the named arguments
518 for (int i = 0; i < numNamedArgs; i++) {
519 String name = uc.strings[stringPtr++];
520 int index = numPositionalArgs + i;
521 arguments[index] = AstFactory.namedExpression2(name, arguments[index]);
522 }
523 }
524 // create TypeName
525 SimpleIdentifier typeNameNode = AstFactory.identifier3(className);
526 typeNameNode.staticElement = classElement;
527 TypeName typeNode = AstFactory.typeName3(typeNameNode);
528 // create ConstructorName
529 ConstructorName constructorNode;
530 if (constructorName != null) {
531 constructorNode = AstFactory.constructorName(typeNode, info.name);
532 constructorNode.name.staticElement = constructorElement;
533 } else {
534 constructorNode = AstFactory.constructorName(typeNode, null);
535 }
536 constructorNode.staticElement = constructorElement;
537 // create InstanceCreationExpression
538 InstanceCreationExpression instanceCreation = AstFactory
539 .instanceCreationExpression(Keyword.CONST, constructorNode, arguments);
540 instanceCreation.staticElement = constructorElement;
541 _push(instanceCreation);
542 }
543
483 void _pushList(TypeArgumentList typeArguments) { 544 void _pushList(TypeArgumentList typeArguments) {
484 int count = uc.ints[intPtr++]; 545 int count = uc.ints[intPtr++];
485 List<Expression> elements = <Expression>[]; 546 List<Expression> elements = <Expression>[];
486 for (int i = 0; i < count; i++) { 547 for (int i = 0; i < count; i++) {
487 elements.insert(0, _pop()); 548 elements.insert(0, _pop());
488 } 549 }
489 _push(AstFactory.listLiteral2(Keyword.CONST, typeArguments, elements)); 550 _push(AstFactory.listLiteral2(Keyword.CONST, typeArguments, elements));
490 } 551 }
491 552
492 void _pushMap(TypeArgumentList typeArguments) { 553 void _pushMap(TypeArgumentList typeArguments) {
493 int count = uc.ints[intPtr++]; 554 int count = uc.ints[intPtr++];
494 List<MapLiteralEntry> entries = <MapLiteralEntry>[]; 555 List<MapLiteralEntry> entries = <MapLiteralEntry>[];
495 for (int i = 0; i < count; i++) { 556 for (int i = 0; i < count; i++) {
496 Expression value = _pop(); 557 Expression value = _pop();
497 Expression key = _pop(); 558 Expression key = _pop();
498 entries.insert(0, AstFactory.mapLiteralEntry2(key, value)); 559 entries.insert(0, AstFactory.mapLiteralEntry2(key, value));
499 } 560 }
500 _push(AstFactory.mapLiteral(Keyword.CONST, typeArguments, entries)); 561 _push(AstFactory.mapLiteral(Keyword.CONST, typeArguments, entries));
501 } 562 }
502 563
503 void _pushPrefix(TokenType operator) { 564 void _pushPrefix(TokenType operator) {
504 Expression operand = _pop(); 565 Expression operand = _pop();
505 _push(AstFactory.prefixExpression(operator, operand)); 566 _push(AstFactory.prefixExpression(operator, operand));
506 } 567 }
568
569 List<Expression> _removeTopItems(int count) {
570 int start = stack.length - count;
571 int end = stack.length;
572 List<Expression> items = stack.getRange(start, end).toList();
573 stack.removeRange(start, end);
574 return items;
575 }
507 } 576 }
508 577
509 /** 578 /**
510 * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the 579 * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the
511 * elements in a single library from that library's summary. 580 * elements in a single library from that library's summary.
512 */ 581 */
513 class _LibraryResynthesizer { 582 class _LibraryResynthesizer {
514 /** 583 /**
515 * The [SummaryResynthesizer] which is being used to obtain summaries. 584 * The [SummaryResynthesizer] which is being used to obtain summaries.
516 */ 585 */
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 /** 1513 /**
1445 * Populate [referenceInfos] with the correct information for the current 1514 * Populate [referenceInfos] with the correct information for the current
1446 * compilation unit. 1515 * compilation unit.
1447 */ 1516 */
1448 void populateReferenceInfos() { 1517 void populateReferenceInfos() {
1449 int numLinkedReferences = linkedUnit.references.length; 1518 int numLinkedReferences = linkedUnit.references.length;
1450 int numUnlinkedReferences = unlinkedUnit.references.length; 1519 int numUnlinkedReferences = unlinkedUnit.references.length;
1451 referenceInfos = new List<_ReferenceInfo>(numLinkedReferences); 1520 referenceInfos = new List<_ReferenceInfo>(numLinkedReferences);
1452 for (int i = 0; i < numLinkedReferences; i++) { 1521 for (int i = 0; i < numLinkedReferences; i++) {
1453 LinkedReference linkedReference = linkedUnit.references[i]; 1522 LinkedReference linkedReference = linkedUnit.references[i];
1523 _ReferenceInfo enclosingInfo = null;
1454 String name; 1524 String name;
1455 int containingReference; 1525 int containingReference;
1456 if (i < numUnlinkedReferences) { 1526 if (i < numUnlinkedReferences) {
1457 name = unlinkedUnit.references[i].name; 1527 name = unlinkedUnit.references[i].name;
1458 containingReference = unlinkedUnit.references[i].prefixReference; 1528 containingReference = unlinkedUnit.references[i].prefixReference;
1459 } else { 1529 } else {
1460 name = linkedUnit.references[i].name; 1530 name = linkedUnit.references[i].name;
1461 containingReference = linkedUnit.references[i].containingReference; 1531 containingReference = linkedUnit.references[i].containingReference;
1462 } 1532 }
1463 Element element; 1533 Element element;
1464 DartType type; 1534 DartType type;
1465 if (linkedReference.kind == ReferenceKind.unresolved) { 1535 if (linkedReference.kind == ReferenceKind.unresolved) {
1466 type = summaryResynthesizer.typeProvider.undefinedType; 1536 type = summaryResynthesizer.typeProvider.undefinedType;
1467 element = type.element; 1537 element = type.element;
1468 } else if (name == 'dynamic') { 1538 } else if (name == 'dynamic') {
1469 type = summaryResynthesizer.typeProvider.dynamicType; 1539 type = summaryResynthesizer.typeProvider.dynamicType;
1470 element = type.element; 1540 element = type.element;
1471 } else if (name == 'void') { 1541 } else if (name == 'void') {
1472 type = VoidTypeImpl.instance; 1542 type = VoidTypeImpl.instance;
1473 element = type.element; 1543 element = type.element;
1474 } else { 1544 } else {
1475 List<String> locationComponents; 1545 List<String> locationComponents;
1476 if (containingReference != 0 && 1546 if (containingReference != 0 &&
1477 referenceInfos[containingReference].element is ClassElement) { 1547 referenceInfos[containingReference].element is ClassElement) {
1478 String identifier = _getElementIdentifier(name, linkedReference.kind); 1548 String identifier = _getElementIdentifier(name, linkedReference.kind);
1479 locationComponents = referenceInfos[containingReference] 1549 enclosingInfo = referenceInfos[containingReference];
1480 .element 1550 locationComponents =
1481 .location 1551 enclosingInfo.element.location.components.toList();
1482 .components
1483 .toList();
1484 locationComponents.add(identifier); 1552 locationComponents.add(identifier);
1485 } else { 1553 } else {
1486 String identifier = _getElementIdentifier(name, linkedReference.kind); 1554 String identifier = _getElementIdentifier(name, linkedReference.kind);
1487 locationComponents = getReferencedLocationComponents( 1555 locationComponents = getReferencedLocationComponents(
1488 linkedReference.dependency, linkedReference.unit, identifier); 1556 linkedReference.dependency, linkedReference.unit, identifier);
1489 } 1557 }
1490 ElementLocation location = 1558 ElementLocation location =
1491 new ElementLocationImpl.con3(locationComponents); 1559 new ElementLocationImpl.con3(locationComponents);
1492 switch (linkedReference.kind) { 1560 switch (linkedReference.kind) {
1493 case ReferenceKind.classOrEnum: 1561 case ReferenceKind.classOrEnum:
1494 element = new ClassElementHandle(summaryResynthesizer, location); 1562 element = new ClassElementHandle(summaryResynthesizer, location);
1495 break; 1563 break;
1496 case ReferenceKind.typedef: 1564 case ReferenceKind.typedef:
1497 element = new FunctionTypeAliasElementHandle( 1565 element = new FunctionTypeAliasElementHandle(
1498 summaryResynthesizer, location); 1566 summaryResynthesizer, location);
1499 break; 1567 break;
1500 case ReferenceKind.topLevelPropertyAccessor: 1568 case ReferenceKind.topLevelPropertyAccessor:
1501 element = new PropertyAccessorElementHandle( 1569 element = new PropertyAccessorElementHandle(
1502 summaryResynthesizer, location); 1570 summaryResynthesizer, location);
1503 break; 1571 break;
1572 case ReferenceKind.constructor:
1573 assert(location.components.length == 4);
1574 element =
1575 new ConstructorElementHandle(summaryResynthesizer, location);
1576 break;
1504 case ReferenceKind.propertyAccessor: 1577 case ReferenceKind.propertyAccessor:
1505 assert(location.components.length == 4); 1578 assert(location.components.length == 4);
1506 element = new PropertyAccessorElementHandle( 1579 element = new PropertyAccessorElementHandle(
1507 summaryResynthesizer, location); 1580 summaryResynthesizer, location);
1508 break; 1581 break;
1509 case ReferenceKind.method: 1582 case ReferenceKind.method:
1510 assert(location.components.length == 4); 1583 assert(location.components.length == 4);
1511 element = new MethodElementHandle(summaryResynthesizer, location); 1584 element = new MethodElementHandle(summaryResynthesizer, location);
1512 break; 1585 break;
1513 default: 1586 default:
1514 // This is an element that doesn't (yet) need to be referred to 1587 // This is an element that doesn't (yet) need to be referred to
1515 // directly, so don't bother populating an element for it. 1588 // directly, so don't bother populating an element for it.
1516 // TODO(paulberry): add support for more kinds, as needed. 1589 // TODO(paulberry): add support for more kinds, as needed.
1517 break; 1590 break;
1518 } 1591 }
1519 } 1592 }
1520 referenceInfos[i] = new _ReferenceInfo( 1593 referenceInfos[i] = new _ReferenceInfo(enclosingInfo, name, element, type,
1521 name, element, type, linkedReference.numTypeParameters); 1594 linkedReference.numTypeParameters);
1522 } 1595 }
1523 } 1596 }
1524 1597
1525 /** 1598 /**
1526 * Populate a [CompilationUnitElement] by deserializing all the elements 1599 * Populate a [CompilationUnitElement] by deserializing all the elements
1527 * contained in it. 1600 * contained in it.
1528 */ 1601 */
1529 void populateUnit(CompilationUnitElementImpl unit, int unitNum) { 1602 void populateUnit(CompilationUnitElementImpl unit, int unitNum) {
1530 linkedUnit = linkedLibrary.units[unitNum]; 1603 linkedUnit = linkedLibrary.units[unitNum];
1531 unlinkedUnit = unlinkedUnits[unitNum]; 1604 unlinkedUnit = unlinkedUnits[unitNum];
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 } 1666 }
1594 } 1667 }
1595 1668
1596 /** 1669 /**
1597 * Data structure used during resynthesis to record all the information that is 1670 * Data structure used during resynthesis to record all the information that is
1598 * known about how to resynthesize a single entry in [LinkedUnit.references] 1671 * known about how to resynthesize a single entry in [LinkedUnit.references]
1599 * (and its associated entry in [UnlinkedUnit.references], if it exists). 1672 * (and its associated entry in [UnlinkedUnit.references], if it exists).
1600 */ 1673 */
1601 class _ReferenceInfo { 1674 class _ReferenceInfo {
1602 /** 1675 /**
1676 * The enclosing [_ReferenceInfo], or `null` for top-level elements.
1677 */
1678 final _ReferenceInfo enclosing;
1679
1680 /**
1603 * The name of the entity referred to by this reference. 1681 * The name of the entity referred to by this reference.
1604 */ 1682 */
1605 final String name; 1683 final String name;
1606 1684
1607 /** 1685 /**
1608 * The element referred to by this reference, or `null` if there is no 1686 * The element referred to by this reference, or `null` if there is no
1609 * associated element (e.g. because it is a reference to an undefined 1687 * associated element (e.g. because it is a reference to an undefined
1610 * entity). 1688 * entity).
1611 */ 1689 */
1612 final Element element; 1690 final Element element;
(...skipping 12 matching lines...) Expand all
1625 1703
1626 /** 1704 /**
1627 * Create a new [_ReferenceInfo] object referring to an element called [name] 1705 * Create a new [_ReferenceInfo] object referring to an element called [name]
1628 * via the element handle [element], and having [numTypeParameters] type 1706 * via the element handle [element], and having [numTypeParameters] type
1629 * parameters. 1707 * parameters.
1630 * 1708 *
1631 * For the special types `dynamic` and `void`, [specialType] should point to 1709 * For the special types `dynamic` and `void`, [specialType] should point to
1632 * the type itself. Otherwise, pass `null` and the type will be computed 1710 * the type itself. Otherwise, pass `null` and the type will be computed
1633 * when appropriate. 1711 * when appropriate.
1634 */ 1712 */
1635 _ReferenceInfo( 1713 _ReferenceInfo(this.enclosing, this.name, this.element, DartType specialType,
1636 this.name, this.element, DartType specialType, this.numTypeParameters) { 1714 this.numTypeParameters) {
1637 if (specialType != null) { 1715 if (specialType != null) {
1638 type = specialType; 1716 type = specialType;
1639 } else { 1717 } else {
1640 type = _buildType((_) => DynamicTypeImpl.instance, null); 1718 type = _buildType((_) => DynamicTypeImpl.instance, null);
1641 } 1719 }
1642 } 1720 }
1643 1721
1644 /** 1722 /**
1645 * Build a [DartType] corresponding to the result of applying some type 1723 * Build a [DartType] corresponding to the result of applying some type
1646 * arguments to the entity referred to by this [_ReferenceInfo]. The type 1724 * arguments to the entity referred to by this [_ReferenceInfo]. The type
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 } 1784 }
1707 : () => this.element; 1785 : () => this.element;
1708 // TODO(paulberry): Is it a bug that we have to pass `false` for 1786 // TODO(paulberry): Is it a bug that we have to pass `false` for
1709 // isInstantiated? 1787 // isInstantiated?
1710 return new DeferredFunctionTypeImpl(computer, null, typeArguments, false); 1788 return new DeferredFunctionTypeImpl(computer, null, typeArguments, false);
1711 } else { 1789 } else {
1712 return null; 1790 return null;
1713 } 1791 }
1714 } 1792 }
1715 } 1793 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/resynthesize_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698