Chromium Code Reviews| 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'; |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |