Chromium Code Reviews| Index: pkg/analyzer/lib/src/summary/resynthesize.dart |
| diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart |
| index 4a182ed0f6ec09e39e9a116b05456309958bfe70..478dc389d82f53e355bc6bcdda772bdbc20a6df5 100644 |
| --- a/pkg/analyzer/lib/src/summary/resynthesize.dart |
| +++ b/pkg/analyzer/lib/src/summary/resynthesize.dart |
| @@ -10,6 +10,7 @@ import 'package:analyzer/dart/ast/ast.dart'; |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| import 'package:analyzer/src/dart/element/element.dart'; |
| +import 'package:analyzer/src/dart/element/member.dart'; |
| import 'package:analyzer/src/dart/element/type.dart'; |
| import 'package:analyzer/src/generated/element_handle.dart'; |
| import 'package:analyzer/src/generated/engine.dart'; |
| @@ -449,6 +450,24 @@ class _ConstExprBuilder { |
| throw new StateError('Unsupported type $type'); |
| } |
| + /** |
| + * Return the [ConstructorElement] for the given [ref] and its linked [info]. |
| + * Both cases when [info] is a [ClassElement] and [ConstructorElement] are |
| + * supported. [ref] is used to get the type arguments and the name of the |
| + * constructor. |
| + */ |
| + _DeferredConstructorElement _createConstructorElement( |
| + EntityRef ref, _ReferenceInfo info) { |
| + bool isClass = info.element is ClassElement; |
| + _ReferenceInfo classInfo = isClass ? info : info.enclosing; |
| + List<DartType> typeArguments = |
| + ref.typeArguments.map(resynthesizer.buildType).toList(); |
| + InterfaceType classType = |
| + classInfo.buildType((i) => typeArguments[i], const <int>[]); |
| + String name = isClass ? '' : info.name; |
| + return new _DeferredConstructorElement(classType, name); |
| + } |
| + |
| InterpolationElement _newInterpolationElement(Expression expr) { |
| if (expr is SimpleStringLiteral) { |
| return new InterpolationString(expr.literal, expr.value); |
| @@ -486,23 +505,14 @@ class _ConstExprBuilder { |
| EntityRef ref = uc.references[refPtr++]; |
| _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference]; |
| // prepare ClassElement / ConstructorElement |
| - String className; |
| - ClassElement classElement; |
| String constructorName; |
| - ConstructorElement constructorElement; |
| + _DeferredConstructorElement constructorElement; |
| if (info.element is ConstructorElement) { |
| constructorName = info.name; |
| - constructorElement = info.element; |
| - className = info.enclosing.name; |
| - classElement = info.enclosing.element as ClassElement; |
| + 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
|
| } else if (info.element is ClassElement) { |
| - className = info.name; |
| - classElement = info.element; |
| constructorName = null; |
| - constructorElement = new ConstructorElementHandle( |
| - resynthesizer.summaryResynthesizer, |
| - new ElementLocationImpl.con3( |
| - classElement.location.components.toList()..add(''))); |
| + constructorElement = _createConstructorElement(ref, info); |
| } else { |
| throw new StateError('Unsupported element for invokeConstructor ' |
| '${info.element?.runtimeType}'); |
| @@ -522,13 +532,11 @@ class _ConstExprBuilder { |
| } |
| } |
| // create TypeName |
| - SimpleIdentifier typeNameNode = AstFactory.identifier3(className); |
| - typeNameNode.staticElement = classElement; |
| - TypeName typeNode = AstFactory.typeName3(typeNameNode); |
| + TypeName typeNode = _buildTypeAst(constructorElement.definingType); |
| // create ConstructorName |
| ConstructorName constructorNode; |
| if (constructorName != null) { |
| - constructorNode = AstFactory.constructorName(typeNode, info.name); |
| + constructorNode = AstFactory.constructorName(typeNode, constructorName); |
| constructorNode.name.staticElement = constructorElement; |
| } else { |
| constructorNode = AstFactory.constructorName(typeNode, null); |
| @@ -576,6 +584,42 @@ class _ConstExprBuilder { |
| } |
| /** |
| + * The constructor element that has been resynthesized from a summary. The |
| + * actual element won't be constructed until it is requested. But properties |
| + * [definingType], [displayName], [enclosingElement] and [name] can be used |
| + * without creating the actual element. |
| + */ |
| +class _DeferredConstructorElement extends ConstructorElementHandle { |
| + final InterfaceType definingType; |
| + final String name; |
| + |
| + factory _DeferredConstructorElement(InterfaceType definingType, String name) { |
| + List<String> components = definingType.element.location.components.toList(); |
| + components.add(name); |
| + ElementLocationImpl location = new ElementLocationImpl.con3(components); |
| + return new _DeferredConstructorElement._(definingType, name, location); |
| + } |
| + |
| + _DeferredConstructorElement._( |
| + this.definingType, this.name, ElementLocation location) |
| + : super(null, location); |
| + |
| + @override |
| + Element get actualElement { |
| + ConstructorElement element = enclosingElement.getNamedConstructor(name); |
| + return new ConstructorMember(element, definingType); |
| + } |
| + |
| + @override |
| + String get displayName => name; |
| + |
| + @override |
| + ClassElement get enclosingElement { |
| + return definingType.element; |
| + } |
| +} |
| + |
| +/** |
| * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the |
| * elements in a single library from that library's summary. |
| */ |
| @@ -1526,6 +1570,7 @@ class _LibraryResynthesizer { |
| } |
| Element element; |
| DartType type; |
| + int numTypeParameters = linkedReference.numTypeParameters; |
| if (linkedReference.kind == ReferenceKind.unresolved) { |
| type = summaryResynthesizer.typeProvider.undefinedType; |
| element = type.element; |
| @@ -1567,6 +1612,7 @@ class _LibraryResynthesizer { |
| assert(location.components.length == 4); |
| element = |
| new ConstructorElementHandle(summaryResynthesizer, location); |
| + numTypeParameters = enclosingInfo.numTypeParameters; |
| break; |
| case ReferenceKind.propertyAccessor: |
| assert(location.components.length == 4); |
| @@ -1584,8 +1630,8 @@ class _LibraryResynthesizer { |
| break; |
| } |
| } |
| - referenceInfos[i] = new _ReferenceInfo(enclosingInfo, name, element, type, |
| - linkedReference.numTypeParameters); |
| + referenceInfos[i] = new _ReferenceInfo( |
| + enclosingInfo, name, element, type, numTypeParameters); |
| } |
| } |