| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |