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

Unified 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, 11 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
}
}
« 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