Skip to content

Commit

Permalink
Clean up resynthesis of typeArguments.
Browse files Browse the repository at this point in the history
Previously, we had to jump through hoops to properly resynthesize
InterfaceTypeImpl.typeArguments and FunctionTypeImpl.typeArguments,
because the correct set of type arguments depends on the number of
type parameters, and that information wasn't available in the
prelinked summary.  Now it is.

Note that typeParameters and boundTypeParameters still aren't
resynthesized properly (and are untested).  These will be addressed in
a future CL.

[email protected]

Review URL: https://codereview.chromium.org/1559123002 .
  • Loading branch information
stereotype441 committed Jan 5, 2016
1 parent c30e64e commit 1bfb1bb
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 79 deletions.
20 changes: 13 additions & 7 deletions pkg/analyzer/lib/src/dart/element/type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,14 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {

/**
* Initialize a newly created function type to be declared by the given
* [element], with the given [name].
* [element], with the given [name] and [typeArguments].
*
* TODO(paulberry): set [typeParameters] and [boundTypeParameters] properly.
*/
FunctionTypeImpl.elementWithName(Element element, String name)
: prunedTypedefs = null,
super(element, name);
FunctionTypeImpl.elementWithNameAndArgs(
Element element, String name, List<DartType> typeArguments)
: this._(element, name, null, typeArguments,
const <TypeParameterElement>[], const <TypeParameterElement>[]);

/**
* Initialize a newly created function type to be declared by the given
Expand Down Expand Up @@ -1107,11 +1110,14 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {

/**
* Initialize a newly created type to be declared by the given [element],
* with the given [name].
* with the given [name] and [typeArguents].
*/
InterfaceTypeImpl.elementWithName(ClassElement element, String name)
InterfaceTypeImpl.elementWithNameAndArgs(
ClassElement element, String name, List<DartType> typeArguments)
: prunedTypedefs = null,
super(element, name);
super(element, name) {
this.typeArguments = typeArguments;
}

/**
* Initialize a newly created type to have the given [name]. This constructor
Expand Down
87 changes: 15 additions & 72 deletions pkg/analyzer/lib/src/summary/resynthesize.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,66 +24,6 @@ typedef PrelinkedLibrary GetPrelinkedSummaryCallback(String uri);
*/
typedef UnlinkedUnit GetUnlinkedSummaryCallback(String uri);

/**
* Specialization of [FunctionTypeImpl] used for function types resynthesized
* from summaries.
*/
class ResynthesizedFunctionTypeImpl extends FunctionTypeImpl
with ResynthesizedType {
final SummaryResynthesizer summaryResynthesizer;

ResynthesizedFunctionTypeImpl(
FunctionTypeAliasElement element, String name, this.summaryResynthesizer)
: super.elementWithName(element, name);

int get _numTypeParameters {
FunctionTypeAliasElement element = this.element;
return element.typeParameters.length;
}
}

/**
* Specialization of [InterfaceTypeImpl] used for interface types resynthesized
* from summaries.
*/
class ResynthesizedInterfaceTypeImpl extends InterfaceTypeImpl
with ResynthesizedType {
final SummaryResynthesizer summaryResynthesizer;

ResynthesizedInterfaceTypeImpl(
ClassElement element, String name, this.summaryResynthesizer)
: super.elementWithName(element, name);

int get _numTypeParameters => element.typeParameters.length;
}

/**
* Common code for types resynthesized from summaries. This code takes care of
* filling in the appropriate number of copies of `dynamic` when it is queried
* for type parameters on a bare type reference (i.e. it converts `List` to
* `List<dynamic>`).
*/
abstract class ResynthesizedType implements DartType {
/**
* The type arguments, if known. Otherwise `null`.
*/
List<DartType> _typeArguments;

SummaryResynthesizer get summaryResynthesizer;

List<DartType> get typeArguments {
if (_typeArguments == null) {
// Default to replicating "dynamic" as many times as the class element
// requires.
_typeArguments = new List<DartType>.filled(
_numTypeParameters, summaryResynthesizer.typeProvider.dynamicType);
}
return _typeArguments;
}

int get _numTypeParameters;
}

/**
* Implementation of [ElementResynthesizer] used when resynthesizing an element
* model from summaries.
Expand Down Expand Up @@ -812,33 +752,36 @@ class _LibraryResynthesizer {
partUri = referencedLibraryUri;
}
}
ResynthesizedType resynthesizedType;
ElementLocationImpl location = new ElementLocationImpl.con3(
<String>[referencedLibraryUri, partUri, reference.name]);
List<DartType> typeArguments = const <DartType>[];
if (referenceResolution.numTypeParameters != 0) {
typeArguments = <DartType>[];
for (int i = 0; i < referenceResolution.numTypeParameters; i++) {
if (i < type.typeArguments.length) {
typeArguments.add(buildType(type.typeArguments[i]));
} else {
typeArguments.add(summaryResynthesizer.typeProvider.dynamicType);
}
}
}
switch (referenceResolution.kind) {
case PrelinkedReferenceKind.classOrEnum:
resynthesizedType = new ResynthesizedInterfaceTypeImpl(
return new InterfaceTypeImpl.elementWithNameAndArgs(
new ClassElementHandle(summaryResynthesizer, location),
reference.name,
summaryResynthesizer);
break;
typeArguments);
case PrelinkedReferenceKind.typedef:
resynthesizedType = new ResynthesizedFunctionTypeImpl(
return new FunctionTypeImpl.elementWithNameAndArgs(
new FunctionTypeAliasElementHandle(
summaryResynthesizer, location),
reference.name,
summaryResynthesizer);
break;
typeArguments);
default:
// TODO(paulberry): figure out how to handle this case (which should
// only occur in the event of erroneous code).
throw new UnimplementedError();
}
if (type.typeArguments.isNotEmpty) {
resynthesizedType._typeArguments =
type.typeArguments.map(buildType).toList();
}
return resynthesizedType;
}
}

Expand Down

0 comments on commit 1bfb1bb

Please sign in to comment.