Resynthesize typedef(s) and generic function types.
R=brianwilkerson@google.com
Change-Id: I3ee3014ffc615052ef077dbf58947330e4ca5e17
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97420
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 5cf726d..6c9fb86 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1780,7 +1780,9 @@
var context = enclosingUnit.linkedContext;
var containerRef = reference.getChild('@typeAlias');
_typeAliases = linkedNode.compilationUnit_declarations
- .where((node) => node.kind == LinkedNodeKind.functionTypeAlias)
+ .where((node) =>
+ node.kind == LinkedNodeKind.functionTypeAlias ||
+ node.kind == LinkedNodeKind.genericTypeAlias)
.map((node) {
var name = context.getUnitMemberName(node);
var reference = containerRef.getChild(name);
@@ -4372,32 +4374,12 @@
var context = enclosingUnit.linkedContext;
var containerRef = reference.getChild('@parameter');
var formalParameters = context.getFormalParameters(linkedNode);
- if (formalParameters != null) {
- _parameters = formalParameters.map((node) {
- if (node.kind == LinkedNodeKind.defaultFormalParameter) {
- var parameterNode = node.defaultFormalParameter_parameter;
- var name = context.getFormalParameterName(parameterNode);
- var reference = containerRef.getChild(name);
- reference.node = node;
- return DefaultParameterElementImpl.forLinkedNode(
- this,
- reference,
- node,
- );
- } else {
- var name = context.getFormalParameterName(node);
- var reference = containerRef.getChild(name);
- reference.node = node;
- return ParameterElementImpl.forLinkedNodeFactory(
- this,
- reference,
- node,
- );
- }
- }).toList();
- } else {
- _parameters = const [];
- }
+ _parameters = ParameterElementImpl.forLinkedNodeList(
+ this,
+ context,
+ containerRef,
+ formalParameters,
+ );
}
if (serializedExecutable != null) {
_parameters = ParameterElementImpl.resynthesizeList(
@@ -5143,6 +5125,10 @@
/// The type defined by this element.
FunctionType _type;
+ GenericFunctionTypeElementImpl.forLinkedNode(
+ ElementImpl enclosingElement, Reference reference, LinkedNode linkedNode)
+ : super.forLinkedNode(enclosingElement, reference, linkedNode);
+
/// Initialize a newly created function element to have no name and the given
/// [nameOffset]. This is used for function expressions, that have no name.
GenericFunctionTypeElementImpl.forOffset(int nameOffset)
@@ -5167,6 +5153,15 @@
@override
List<ParameterElement> get parameters {
if (_parameters == null) {
+ if (linkedNode != null) {
+ var context = enclosingUnit.linkedContext;
+ return _parameters = ParameterElementImpl.forLinkedNodeList(
+ this,
+ context,
+ reference.getChild('@parameter'),
+ context.getFormalParameters(linkedNode),
+ );
+ }
if (_entityRef != null) {
_parameters = ParameterElementImpl.resynthesizeList(
_entityRef.syntheticParams, this);
@@ -5188,6 +5183,10 @@
@override
DartType get returnType {
if (_returnType == null) {
+ if (linkedNode != null) {
+ var context = enclosingUnit.linkedContext;
+ return _returnType = context.getReturnType(linkedNode);
+ }
if (_entityRef != null) {
_returnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
this, _entityRef.syntheticReturnType,
@@ -5217,6 +5216,16 @@
_type = type;
}
+ @override
+ List<TypeParameterElement> get typeParameters {
+ if (linkedNode != null) {
+ if (linkedNode.kind == LinkedNodeKind.functionTypeAlias) {
+ return const <TypeParameterElement>[];
+ }
+ }
+ return super.typeParameters;
+ }
+
/// Set the type parameters defined by this function type element to the given
/// [typeParameters].
void set typeParameters(List<TypeParameterElement> typeParameters) {
@@ -5362,24 +5371,19 @@
if (_function != null) return _function;
if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- _function = new GenericFunctionTypeElementImpl.forOffset(-1);
- _function.enclosingElement = this;
- _function.returnType = context.getType(
- linkedNode.functionTypeAlias_returnType2,
- );
- var containerRef = reference.getChild('@parameter');
- var formalParameters = context.getFormalParameters(linkedNode);
- _function.parameters = formalParameters.map((node) {
- var name = context.getFormalParameterName(node);
- var reference = containerRef.getChild(name);
- reference.node = node;
- return ParameterElementImpl.forLinkedNodeFactory(
+ if (linkedNode.kind == LinkedNodeKind.genericTypeAlias) {
+ _function = GenericFunctionTypeElementImpl.forLinkedNode(
this,
- reference,
- node,
+ reference.getChild('@function'),
+ linkedNode.genericTypeAlias_functionType,
);
- }).toList();
+ } else {
+ return _function = GenericFunctionTypeElementImpl.forLinkedNode(
+ this,
+ reference.getChild('@function'),
+ linkedNode,
+ );
+ }
return _function;
}
@@ -8080,6 +8084,39 @@
}
}
+ static List<ParameterElement> forLinkedNodeList(
+ ElementImpl enclosing,
+ LinkedUnitContext context,
+ Reference containerRef,
+ List<LinkedNode> formalParameters) {
+ if (formalParameters == null) {
+ return const [];
+ }
+
+ return formalParameters.map((node) {
+ if (node.kind == LinkedNodeKind.defaultFormalParameter) {
+ var parameterNode = node.defaultFormalParameter_parameter;
+ var name = context.getFormalParameterName(parameterNode);
+ var reference = containerRef.getChild(name);
+ reference.node = node;
+ return DefaultParameterElementImpl.forLinkedNode(
+ enclosing,
+ reference,
+ node,
+ );
+ } else {
+ var name = context.getFormalParameterName(node);
+ var reference = containerRef.getChild(name);
+ reference.node = node;
+ return ParameterElementImpl.forLinkedNodeFactory(
+ enclosing,
+ reference,
+ node,
+ );
+ }
+ }).toList();
+ }
+
/// Create and return [ParameterElement]s for the given [unlinkedParameters].
static List<ParameterElement> resynthesizeList(
List<UnlinkedParam> unlinkedParameters, ElementImpl enclosingElement,
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 38784fc..ce7fd72 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -9433,6 +9433,12 @@
return _variantField_25;
}
+ @override
+ LinkedNodeTypeBuilder get genericFunctionType_type {
+ assert(kind == idl.LinkedNodeKind.genericFunctionType);
+ return _variantField_25;
+ }
+
void set expression_type(LinkedNodeTypeBuilder value) {
assert(kind == idl.LinkedNodeKind.adjacentStrings ||
kind == idl.LinkedNodeKind.assignmentExpression ||
@@ -9469,6 +9475,11 @@
_variantField_25 = value;
}
+ void set genericFunctionType_type(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.genericFunctionType);
+ _variantField_25 = value;
+ }
+
@override
idl.LinkedNodeFormalParameterKind get formalParameter_kind {
assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
@@ -10715,13 +10726,15 @@
LinkedNodeBuilder genericFunctionType_formalParameters,
int genericFunctionType_question,
LinkedNodeTypeBuilder genericFunctionType_returnType2,
+ LinkedNodeTypeBuilder genericFunctionType_type,
}) : _kind = idl.LinkedNodeKind.genericFunctionType,
_variantField_6 = genericFunctionType_typeParameters,
_variantField_15 = genericFunctionType_functionKeyword,
_variantField_7 = genericFunctionType_returnType,
_variantField_8 = genericFunctionType_formalParameters,
_variantField_16 = genericFunctionType_question,
- _variantField_24 = genericFunctionType_returnType2;
+ _variantField_24 = genericFunctionType_returnType2,
+ _variantField_25 = genericFunctionType_type;
LinkedNodeBuilder.ifElement({
LinkedNodeBuilder ifMixin_condition,
@@ -14876,6 +14889,14 @@
}
@override
+ idl.LinkedNodeType get genericFunctionType_type {
+ assert(kind == idl.LinkedNodeKind.genericFunctionType);
+ _variantField_25 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 25, null);
+ return _variantField_25;
+ }
+
+ @override
idl.LinkedNodeFormalParameterKind get formalParameter_kind {
assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
@@ -16275,6 +16296,8 @@
if (genericFunctionType_returnType2 != null)
_result["genericFunctionType_returnType2"] =
genericFunctionType_returnType2.toJson();
+ if (genericFunctionType_type != null)
+ _result["genericFunctionType_type"] = genericFunctionType_type.toJson();
}
if (kind == idl.LinkedNodeKind.ifElement) {
if (ifMixin_condition != null)
@@ -17618,6 +17641,7 @@
genericFunctionType_formalParameters,
"genericFunctionType_question": genericFunctionType_question,
"genericFunctionType_returnType2": genericFunctionType_returnType2,
+ "genericFunctionType_type": genericFunctionType_type,
"isSynthetic": isSynthetic,
"kind": kind,
};
@@ -18540,21 +18564,22 @@
class LinkedNodeTypeBuilder extends Object
with _LinkedNodeTypeMixin
implements idl.LinkedNodeType {
- List<int> _functionFormalParameters;
+ List<LinkedNodeTypeFormalParameterBuilder> _functionFormalParameters;
LinkedNodeTypeBuilder _functionReturnType;
List<int> _functionTypeParameters;
+ int _genericTypeAliasReference;
+ List<LinkedNodeTypeBuilder> _genericTypeAliasTypeArguments;
int _interfaceClass;
List<LinkedNodeTypeBuilder> _interfaceTypeArguments;
idl.LinkedNodeTypeKind _kind;
int _typeParameterParameter;
@override
- List<int> get functionFormalParameters =>
- _functionFormalParameters ??= <int>[];
+ List<LinkedNodeTypeFormalParameterBuilder> get functionFormalParameters =>
+ _functionFormalParameters ??= <LinkedNodeTypeFormalParameterBuilder>[];
- /// References to [LinkedNodeReferences].
- void set functionFormalParameters(List<int> value) {
- assert(value == null || value.every((e) => e >= 0));
+ void set functionFormalParameters(
+ List<LinkedNodeTypeFormalParameterBuilder> value) {
this._functionFormalParameters = value;
}
@@ -18575,6 +18600,22 @@
}
@override
+ int get genericTypeAliasReference => _genericTypeAliasReference ??= 0;
+
+ void set genericTypeAliasReference(int value) {
+ assert(value == null || value >= 0);
+ this._genericTypeAliasReference = value;
+ }
+
+ @override
+ List<LinkedNodeTypeBuilder> get genericTypeAliasTypeArguments =>
+ _genericTypeAliasTypeArguments ??= <LinkedNodeTypeBuilder>[];
+
+ void set genericTypeAliasTypeArguments(List<LinkedNodeTypeBuilder> value) {
+ this._genericTypeAliasTypeArguments = value;
+ }
+
+ @override
int get interfaceClass => _interfaceClass ??= 0;
/// Reference to a [LinkedNodeReferences].
@@ -18608,9 +18649,11 @@
}
LinkedNodeTypeBuilder(
- {List<int> functionFormalParameters,
+ {List<LinkedNodeTypeFormalParameterBuilder> functionFormalParameters,
LinkedNodeTypeBuilder functionReturnType,
List<int> functionTypeParameters,
+ int genericTypeAliasReference,
+ List<LinkedNodeTypeBuilder> genericTypeAliasTypeArguments,
int interfaceClass,
List<LinkedNodeTypeBuilder> interfaceTypeArguments,
idl.LinkedNodeTypeKind kind,
@@ -18618,6 +18661,8 @@
: _functionFormalParameters = functionFormalParameters,
_functionReturnType = functionReturnType,
_functionTypeParameters = functionTypeParameters,
+ _genericTypeAliasReference = genericTypeAliasReference,
+ _genericTypeAliasTypeArguments = genericTypeAliasTypeArguments,
_interfaceClass = interfaceClass,
_interfaceTypeArguments = interfaceTypeArguments,
_kind = kind,
@@ -18627,7 +18672,9 @@
* Flush [informative] data recursively.
*/
void flushInformative() {
+ _functionFormalParameters?.forEach((b) => b.flushInformative());
_functionReturnType?.flushInformative();
+ _genericTypeAliasTypeArguments?.forEach((b) => b.flushInformative());
_interfaceTypeArguments?.forEach((b) => b.flushInformative());
}
@@ -18640,7 +18687,7 @@
} else {
signature.addInt(this._functionFormalParameters.length);
for (var x in this._functionFormalParameters) {
- signature.addInt(x);
+ x?.collectApiSignature(signature);
}
}
signature.addBool(this._functionReturnType != null);
@@ -18664,17 +18711,27 @@
}
signature.addInt(this._kind == null ? 0 : this._kind.index);
signature.addInt(this._typeParameterParameter ?? 0);
+ signature.addInt(this._genericTypeAliasReference ?? 0);
+ if (this._genericTypeAliasTypeArguments == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this._genericTypeAliasTypeArguments.length);
+ for (var x in this._genericTypeAliasTypeArguments) {
+ x?.collectApiSignature(signature);
+ }
+ }
}
fb.Offset finish(fb.Builder fbBuilder) {
fb.Offset offset_functionFormalParameters;
fb.Offset offset_functionReturnType;
fb.Offset offset_functionTypeParameters;
+ fb.Offset offset_genericTypeAliasTypeArguments;
fb.Offset offset_interfaceTypeArguments;
if (!(_functionFormalParameters == null ||
_functionFormalParameters.isEmpty)) {
- offset_functionFormalParameters =
- fbBuilder.writeListUint32(_functionFormalParameters);
+ offset_functionFormalParameters = fbBuilder.writeList(
+ _functionFormalParameters.map((b) => b.finish(fbBuilder)).toList());
}
if (_functionReturnType != null) {
offset_functionReturnType = _functionReturnType.finish(fbBuilder);
@@ -18683,6 +18740,13 @@
offset_functionTypeParameters =
fbBuilder.writeListUint32(_functionTypeParameters);
}
+ if (!(_genericTypeAliasTypeArguments == null ||
+ _genericTypeAliasTypeArguments.isEmpty)) {
+ offset_genericTypeAliasTypeArguments = fbBuilder.writeList(
+ _genericTypeAliasTypeArguments
+ .map((b) => b.finish(fbBuilder))
+ .toList());
+ }
if (!(_interfaceTypeArguments == null || _interfaceTypeArguments.isEmpty)) {
offset_interfaceTypeArguments = fbBuilder.writeList(
_interfaceTypeArguments.map((b) => b.finish(fbBuilder)).toList());
@@ -18697,6 +18761,12 @@
if (offset_functionTypeParameters != null) {
fbBuilder.addOffset(2, offset_functionTypeParameters);
}
+ if (_genericTypeAliasReference != null && _genericTypeAliasReference != 0) {
+ fbBuilder.addUint32(7, _genericTypeAliasReference);
+ }
+ if (offset_genericTypeAliasTypeArguments != null) {
+ fbBuilder.addOffset(8, offset_genericTypeAliasTypeArguments);
+ }
if (_interfaceClass != null && _interfaceClass != 0) {
fbBuilder.addUint32(3, _interfaceClass);
}
@@ -18729,18 +18799,23 @@
_LinkedNodeTypeImpl(this._bc, this._bcOffset);
- List<int> _functionFormalParameters;
+ List<idl.LinkedNodeTypeFormalParameter> _functionFormalParameters;
idl.LinkedNodeType _functionReturnType;
List<int> _functionTypeParameters;
+ int _genericTypeAliasReference;
+ List<idl.LinkedNodeType> _genericTypeAliasTypeArguments;
int _interfaceClass;
List<idl.LinkedNodeType> _interfaceTypeArguments;
idl.LinkedNodeTypeKind _kind;
int _typeParameterParameter;
@override
- List<int> get functionFormalParameters {
+ List<idl.LinkedNodeTypeFormalParameter> get functionFormalParameters {
_functionFormalParameters ??=
- const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
+ const fb.ListReader<idl.LinkedNodeTypeFormalParameter>(
+ const _LinkedNodeTypeFormalParameterReader())
+ .vTableGet(
+ _bc, _bcOffset, 0, const <idl.LinkedNodeTypeFormalParameter>[]);
return _functionFormalParameters;
}
@@ -18759,6 +18834,21 @@
}
@override
+ int get genericTypeAliasReference {
+ _genericTypeAliasReference ??=
+ const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 7, 0);
+ return _genericTypeAliasReference;
+ }
+
+ @override
+ List<idl.LinkedNodeType> get genericTypeAliasTypeArguments {
+ _genericTypeAliasTypeArguments ??=
+ const fb.ListReader<idl.LinkedNodeType>(const _LinkedNodeTypeReader())
+ .vTableGet(_bc, _bcOffset, 8, const <idl.LinkedNodeType>[]);
+ return _genericTypeAliasTypeArguments;
+ }
+
+ @override
int get interfaceClass {
_interfaceClass ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
return _interfaceClass;
@@ -18792,11 +18882,18 @@
Map<String, Object> toJson() {
Map<String, Object> _result = <String, Object>{};
if (functionFormalParameters.isNotEmpty)
- _result["functionFormalParameters"] = functionFormalParameters;
+ _result["functionFormalParameters"] =
+ functionFormalParameters.map((_value) => _value.toJson()).toList();
if (functionReturnType != null)
_result["functionReturnType"] = functionReturnType.toJson();
if (functionTypeParameters.isNotEmpty)
_result["functionTypeParameters"] = functionTypeParameters;
+ if (genericTypeAliasReference != 0)
+ _result["genericTypeAliasReference"] = genericTypeAliasReference;
+ if (genericTypeAliasTypeArguments.isNotEmpty)
+ _result["genericTypeAliasTypeArguments"] = genericTypeAliasTypeArguments
+ .map((_value) => _value.toJson())
+ .toList();
if (interfaceClass != 0) _result["interfaceClass"] = interfaceClass;
if (interfaceTypeArguments.isNotEmpty)
_result["interfaceTypeArguments"] =
@@ -18813,6 +18910,8 @@
"functionFormalParameters": functionFormalParameters,
"functionReturnType": functionReturnType,
"functionTypeParameters": functionTypeParameters,
+ "genericTypeAliasReference": genericTypeAliasReference,
+ "genericTypeAliasTypeArguments": genericTypeAliasTypeArguments,
"interfaceClass": interfaceClass,
"interfaceTypeArguments": interfaceTypeArguments,
"kind": kind,
@@ -18823,6 +18922,148 @@
String toString() => convert.json.encode(toJson());
}
+class LinkedNodeTypeFormalParameterBuilder extends Object
+ with _LinkedNodeTypeFormalParameterMixin
+ implements idl.LinkedNodeTypeFormalParameter {
+ idl.LinkedNodeFormalParameterKind _kind;
+ String _name;
+ LinkedNodeTypeBuilder _type;
+
+ @override
+ idl.LinkedNodeFormalParameterKind get kind =>
+ _kind ??= idl.LinkedNodeFormalParameterKind.required;
+
+ void set kind(idl.LinkedNodeFormalParameterKind value) {
+ this._kind = value;
+ }
+
+ @override
+ String get name => _name ??= '';
+
+ void set name(String value) {
+ this._name = value;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get type => _type;
+
+ void set type(LinkedNodeTypeBuilder value) {
+ this._type = value;
+ }
+
+ LinkedNodeTypeFormalParameterBuilder(
+ {idl.LinkedNodeFormalParameterKind kind,
+ String name,
+ LinkedNodeTypeBuilder type})
+ : _kind = kind,
+ _name = name,
+ _type = type;
+
+ /**
+ * Flush [informative] data recursively.
+ */
+ void flushInformative() {
+ _type?.flushInformative();
+ }
+
+ /**
+ * Accumulate non-[informative] data into [signature].
+ */
+ void collectApiSignature(api_sig.ApiSignature signature) {
+ signature.addInt(this._kind == null ? 0 : this._kind.index);
+ signature.addString(this._name ?? '');
+ signature.addBool(this._type != null);
+ this._type?.collectApiSignature(signature);
+ }
+
+ fb.Offset finish(fb.Builder fbBuilder) {
+ fb.Offset offset_name;
+ fb.Offset offset_type;
+ if (_name != null) {
+ offset_name = fbBuilder.writeString(_name);
+ }
+ if (_type != null) {
+ offset_type = _type.finish(fbBuilder);
+ }
+ fbBuilder.startTable();
+ if (_kind != null && _kind != idl.LinkedNodeFormalParameterKind.required) {
+ fbBuilder.addUint8(0, _kind.index);
+ }
+ if (offset_name != null) {
+ fbBuilder.addOffset(1, offset_name);
+ }
+ if (offset_type != null) {
+ fbBuilder.addOffset(2, offset_type);
+ }
+ return fbBuilder.endTable();
+ }
+}
+
+class _LinkedNodeTypeFormalParameterReader
+ extends fb.TableReader<_LinkedNodeTypeFormalParameterImpl> {
+ const _LinkedNodeTypeFormalParameterReader();
+
+ @override
+ _LinkedNodeTypeFormalParameterImpl createObject(
+ fb.BufferContext bc, int offset) =>
+ new _LinkedNodeTypeFormalParameterImpl(bc, offset);
+}
+
+class _LinkedNodeTypeFormalParameterImpl extends Object
+ with _LinkedNodeTypeFormalParameterMixin
+ implements idl.LinkedNodeTypeFormalParameter {
+ final fb.BufferContext _bc;
+ final int _bcOffset;
+
+ _LinkedNodeTypeFormalParameterImpl(this._bc, this._bcOffset);
+
+ idl.LinkedNodeFormalParameterKind _kind;
+ String _name;
+ idl.LinkedNodeType _type;
+
+ @override
+ idl.LinkedNodeFormalParameterKind get kind {
+ _kind ??= const _LinkedNodeFormalParameterKindReader().vTableGet(
+ _bc, _bcOffset, 0, idl.LinkedNodeFormalParameterKind.required);
+ return _kind;
+ }
+
+ @override
+ String get name {
+ _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
+ return _name;
+ }
+
+ @override
+ idl.LinkedNodeType get type {
+ _type ??= const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 2, null);
+ return _type;
+ }
+}
+
+abstract class _LinkedNodeTypeFormalParameterMixin
+ implements idl.LinkedNodeTypeFormalParameter {
+ @override
+ Map<String, Object> toJson() {
+ Map<String, Object> _result = <String, Object>{};
+ if (kind != idl.LinkedNodeFormalParameterKind.required)
+ _result["kind"] = kind.toString().split('.')[1];
+ if (name != '') _result["name"] = name;
+ if (type != null) _result["type"] = type.toJson();
+ return _result;
+ }
+
+ @override
+ Map<String, Object> toMap() => {
+ "kind": kind,
+ "name": name,
+ "type": type,
+ };
+
+ @override
+ String toString() => convert.json.encode(toJson());
+}
+
class LinkedNodeUnitBuilder extends Object
with _LinkedNodeUnitMixin
implements idl.LinkedNodeUnit {
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 3d529d9..8b52c07 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1920,14 +1920,17 @@
/// Information about a Dart type.
table LinkedNodeType {
- /// References to [LinkedNodeReferences].
- functionFormalParameters:[uint] (id: 0);
+ functionFormalParameters:[LinkedNodeTypeFormalParameter] (id: 0);
functionReturnType:LinkedNodeType (id: 1);
/// References to [LinkedNodeReferences].
functionTypeParameters:[uint] (id: 2);
+ genericTypeAliasReference:uint (id: 7);
+
+ genericTypeAliasTypeArguments:[LinkedNodeType] (id: 8);
+
/// Reference to a [LinkedNodeReferences].
interfaceClass:uint (id: 3);
@@ -1939,6 +1942,15 @@
typeParameterParameter:uint (id: 6);
}
+/// Information about a formal parameter in a function type.
+table LinkedNodeTypeFormalParameter {
+ kind:LinkedNodeFormalParameterKind (id: 0);
+
+ name:string (id: 1);
+
+ type:LinkedNodeType (id: 2);
+}
+
/// Information about a single library in a [LinkedNodeLibrary].
table LinkedNodeUnit {
node:LinkedNode (id: 2);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 81731be..e214f9c 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -1531,6 +1531,9 @@
@VariantId(24, variant: LinkedNodeKind.genericFunctionType)
LinkedNodeType get genericFunctionType_returnType2;
+ @VariantId(25, variant: LinkedNodeKind.genericFunctionType)
+ LinkedNodeType get genericFunctionType_type;
+
@VariantId(6, variant: LinkedNodeKind.genericFunctionType)
LinkedNode get genericFunctionType_typeParameters;
@@ -2433,9 +2436,8 @@
/// Information about a Dart type.
abstract class LinkedNodeType extends base.SummaryClass {
- /// References to [LinkedNodeReferences].
@Id(0)
- List<int> get functionFormalParameters;
+ List<LinkedNodeTypeFormalParameter> get functionFormalParameters;
@Id(1)
LinkedNodeType get functionReturnType;
@@ -2444,6 +2446,12 @@
@Id(2)
List<int> get functionTypeParameters;
+ @Id(7)
+ int get genericTypeAliasReference;
+
+ @Id(8)
+ List<LinkedNodeType> get genericTypeAliasTypeArguments;
+
/// Reference to a [LinkedNodeReferences].
@Id(3)
int get interfaceClass;
@@ -2459,6 +2467,18 @@
int get typeParameterParameter;
}
+/// Information about a formal parameter in a function type.
+abstract class LinkedNodeTypeFormalParameter extends base.SummaryClass {
+ @Id(0)
+ LinkedNodeFormalParameterKind get kind;
+
+ @Id(1)
+ String get name;
+
+ @Id(2)
+ LinkedNodeType get type;
+}
+
/// Kinds of [LinkedNodeType]s.
enum LinkedNodeTypeKind {
bottom,
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 9b03ad2..93c7b51 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -28,6 +28,16 @@
return node;
}
+ ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
+ if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
+ return ParameterKind.NAMED;
+ }
+ if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
+ return ParameterKind.POSITIONAL;
+ }
+ return ParameterKind.REQUIRED;
+ }
+
T _getElement<T extends Element>(int index) {
var bundleContext = _unitContext.bundleContext;
return bundleContext.elementOfIndex(index);
@@ -1434,7 +1444,10 @@
return FunctionTypeImpl.synthetic(
_readType(data.functionReturnType),
_getElements(data.functionTypeParameters),
- _getElements(data.functionFormalParameters),
+ data.functionFormalParameters
+ .map((p) => ParameterElementImpl.synthetic(
+ p.name, _readType(p.type), _formalParameterKind(p.kind)))
+ .toList(),
);
case LinkedNodeTypeKind.interface:
var element = _getElement(data.interfaceClass);
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
index fbaf454..e0abe3a 100644
--- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/reference.dart';
@@ -46,19 +47,21 @@
var kind = linkedType.kind;
if (kind == LinkedNodeTypeKind.dynamic_) {
return DynamicTypeImpl.instance;
+ } else if (kind == LinkedNodeTypeKind.genericTypeAlias) {
+ var reference = referenceOfIndex(linkedType.genericTypeAliasReference);
+ return GenericTypeAliasElementImpl.typeAfterSubstitution(
+ elementFactory.elementOfReference(reference),
+ linkedType.genericTypeAliasTypeArguments.map(getType).toList(),
+ );
} else if (kind == LinkedNodeTypeKind.function) {
var returnType = getType(linkedType.functionReturnType);
- var typeParameters = linkedType.functionTypeParameters
- .map(referenceOfIndex)
- .map(elementFactory.elementOfReference)
- .cast<TypeParameterElement>()
- .toList();
- var formalParameters = linkedType.functionFormalParameters
- .map(referenceOfIndex)
- .map(elementFactory.elementOfReference)
- .cast<ParameterElement>()
- .toList();
- // TODO(scheglov) Rework this to purely synthetic types.
+ var formalParameters = linkedType.functionFormalParameters.map((p) {
+ return ParameterElementImpl.synthetic(
+ p.name,
+ getType(p.type),
+ _formalParameterKind(p.kind),
+ );
+ }).toList();
return FunctionElementImpl.synthetic(formalParameters, returnType).type;
} else if (kind == LinkedNodeTypeKind.interface) {
var reference = referenceOfIndex(linkedType.interfaceClass);
@@ -105,4 +108,14 @@
return reference;
}
+
+ ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
+ if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
+ return ParameterKind.NAMED;
+ }
+ if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
+ return ParameterKind.POSITIONAL;
+ }
+ return ParameterKind.REQUIRED;
+ }
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index b1bb1f4..a5fe43b 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -56,6 +56,8 @@
.functionExpression_formalParameters;
} else if (kind == LinkedNodeKind.functionTypeAlias) {
parameterList = node.functionTypeAlias_formalParameters;
+ } else if (kind == LinkedNodeKind.genericFunctionType) {
+ parameterList = node.genericFunctionType_formalParameters;
} else if (kind == LinkedNodeKind.methodDeclaration) {
parameterList = node.methodDeclaration_formalParameters;
} else {
@@ -109,6 +111,10 @@
var kind = node.kind;
if (kind == LinkedNodeKind.functionDeclaration) {
return getType(node.functionDeclaration_returnType2);
+ } else if (kind == LinkedNodeKind.functionTypeAlias) {
+ return getType(node.functionTypeAlias_returnType2);
+ } else if (kind == LinkedNodeKind.genericFunctionType) {
+ return getType(node.genericFunctionType_returnType2);
} else if (kind == LinkedNodeKind.methodDeclaration) {
return getType(node.methodDeclaration_returnType2);
} else {
@@ -161,6 +167,10 @@
typeParameterList = node.functionExpression_typeParameters;
} else if (kind == LinkedNodeKind.functionTypeAlias) {
typeParameterList = node.functionTypeAlias_typeParameters;
+ } else if (kind == LinkedNodeKind.genericFunctionType) {
+ typeParameterList = node.genericFunctionType_typeParameters;
+ } else if (kind == LinkedNodeKind.genericTypeAlias) {
+ typeParameterList = node.genericTypeAlias_typeParameters;
} else if (kind == LinkedNodeKind.methodDeclaration) {
typeParameterList = node.methodDeclaration_typeParameters;
} else {
diff --git a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
index 50b9b92..c296437 100644
--- a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/reference.dart';
@@ -56,7 +57,14 @@
} else if (type is FunctionType) {
return LinkedNodeTypeBuilder(
kind: LinkedNodeTypeKind.function,
- functionFormalParameters: _getReferences(type.parameters),
+ functionFormalParameters: type.parameters
+ .map((p) => LinkedNodeTypeFormalParameterBuilder(
+ // ignore: deprecated_member_use_from_same_package
+ kind: _formalParameterKind(p.parameterKind),
+ name: p.name,
+ type: writeType(p.type),
+ ))
+ .toList(),
functionReturnType: writeType(type.returnType),
functionTypeParameters: _getReferences(type.typeParameters),
);
@@ -80,6 +88,16 @@
}
}
+ LinkedNodeFormalParameterKind _formalParameterKind(ParameterKind kind) {
+ if (kind == ParameterKind.NAMED) {
+ return LinkedNodeFormalParameterKind.optionalNamed;
+ }
+ if (kind == ParameterKind.POSITIONAL) {
+ return LinkedNodeFormalParameterKind.optionalPositional;
+ }
+ return LinkedNodeFormalParameterKind.required;
+ }
+
int _getReferenceIndex(Element element) {
if (element == null) return 0;
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 7ab1198..72ac0e4 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -203,13 +203,12 @@
var returnType = node.genericFunctionType_returnType;
if (returnType != null) {
_node(returnType);
- node.genericFunctionType_returnType2 =
- _getTypeAnnotationType(returnType);
- } else {
- node.genericFunctionType_returnType2 = _dynamicType;
+ typesToBuild.declarations.add(node);
}
_node(node.genericFunctionType_formalParameters);
+
+ typesToBuild.typeAnnotations.add(node);
});
reference = reference.parent.parent;
@@ -229,15 +228,6 @@
reference = reference.parent.parent;
}
- LinkedNodeTypeBuilder _getTypeAnnotationType(LinkedNodeBuilder node) {
- var kind = node.kind;
- if (kind == LinkedNodeKind.typeName) {
- return node.typeName_type;
- } else {
- throw UnimplementedError('$kind');
- }
- }
-
void _importDirective(LinkedNodeBuilder node) {}
void _libraryDirective(LinkedNodeBuilder node) {}
@@ -385,7 +375,7 @@
_node(typeArgumentList);
}
- typesToBuild.typeNames.add(node);
+ typesToBuild.typeAnnotations.add(node);
} else {
// TODO(scheglov) implement
throw UnimplementedError();
@@ -445,12 +435,14 @@
/// know this until we resolved `A` declaration, and we might have not yet.
/// So, we remember [LinkedNodeKind.typeName] nodes to resolve them later.
class TypesToBuild {
- /// Nodes with [LinkedNodeKind.typeName], both with type arguments, and
- /// without them. These nodes will be resolved by [ReferenceResolver], so
- /// that they have their references set, but their types will not be set yet.
+ /// Nodes with [LinkedNodeKind.typeName] (with type arguments, and without
+ /// them), and [LinkedNodeKind.genericFunctionType]. These nodes will be
+ /// resolved by [ReferenceResolver], so that they have their references set,
+ /// but their types will not be set yet.
///
- /// Types arguments must be before the types that use them in this list.
- final List<LinkedNodeBuilder> typeNames = [];
+ /// Types arguments, return types, and types of formal parameters must be
+ /// before the types that use them in this list.
+ final List<LinkedNodeBuilder> typeAnnotations = [];
/// Nodes with type annotations, where we want not just resolve these types
/// annotations, but also set additional types. For example instance method
diff --git a/pkg/analyzer/lib/src/summary2/type_builder.dart b/pkg/analyzer/lib/src/summary2/type_builder.dart
index fcacd84..c2c6359 100644
--- a/pkg/analyzer/lib/src/summary2/type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/type_builder.dart
@@ -13,15 +13,53 @@
TypeBuilder(this.bundleContext);
+ LinkedNodeTypeBuilder get _dynamicType {
+ return LinkedNodeTypeBuilder(
+ kind: LinkedNodeTypeKind.dynamic_,
+ );
+ }
+
void build(TypesToBuild typesToBuild) {
- for (var node in typesToBuild.typeNames) {
- _buildTypeName(node);
+ for (var node in typesToBuild.typeAnnotations) {
+ var kind = node.kind;
+ if (kind == LinkedNodeKind.genericFunctionType) {
+ _buildGenericFunctionType(node);
+ } else if (kind == LinkedNodeKind.typeName) {
+ _buildTypeName(node);
+ } else {
+ throw StateError('$kind');
+ }
}
for (var node in typesToBuild.declarations) {
_setTypesForDeclaration(node);
}
}
+ void _buildGenericFunctionType(LinkedNodeBuilder node) {
+ // TODO(scheglov) Type parameters?
+ LinkedNodeTypeBuilder returnType;
+ if (node.genericFunctionType_returnType != null) {
+ returnType = _getType(node.genericFunctionType_returnType);
+ } else {
+ returnType = _dynamicType;
+ }
+
+ var formalParameters = <LinkedNodeTypeFormalParameterBuilder>[];
+ for (var parameter in node
+ .genericFunctionType_formalParameters.formalParameterList_parameters) {
+ formalParameters.add(LinkedNodeTypeFormalParameterBuilder(
+ kind: parameter.formalParameter_kind,
+ type: _getType(parameter.simpleFormalParameter_type),
+ ));
+ }
+
+ node.genericFunctionType_type = LinkedNodeTypeBuilder(
+ kind: LinkedNodeTypeKind.function,
+ functionFormalParameters: formalParameters,
+ functionReturnType: returnType,
+ );
+ }
+
void _buildTypeName(LinkedNodeBuilder node) {
var referenceIndex = _typeNameElementIndex(node.typeName_name);
var reference = bundleContext.referenceOfIndex(referenceIndex);
@@ -40,6 +78,12 @@
interfaceClass: referenceIndex,
interfaceTypeArguments: typeArguments,
);
+ } else if (reference.isGenericTypeAlias) {
+ node.typeName_type = LinkedNodeTypeBuilder(
+ kind: LinkedNodeTypeKind.genericTypeAlias,
+ genericTypeAliasReference: referenceIndex,
+ genericTypeAliasTypeArguments: typeArguments,
+ );
} else if (reference.isEnum) {
node.typeName_type = LinkedNodeTypeBuilder(
kind: LinkedNodeTypeKind.interface,
@@ -52,7 +96,7 @@
);
} else {
// TODO(scheglov) set Object? keep unresolved?
- throw UnimplementedError();
+ throw UnimplementedError('$reference');
}
}
@@ -70,6 +114,10 @@
node.functionTypeAlias_returnType2 = _getType(
node.functionTypeAlias_returnType,
);
+ } else if (kind == LinkedNodeKind.genericFunctionType) {
+ node.genericFunctionType_returnType2 = _getType(
+ node.genericFunctionType_returnType,
+ );
} else if (kind == LinkedNodeKind.methodDeclaration) {
node.methodDeclaration_returnType2 = _getType(
node.methodDeclaration_returnType,
@@ -90,7 +138,9 @@
static LinkedNodeTypeBuilder _getType(LinkedNodeBuilder node) {
var kind = node.kind;
- if (kind == LinkedNodeKind.typeName) {
+ if (kind == LinkedNodeKind.genericFunctionType) {
+ return node.genericFunctionType_type;
+ } else if (kind == LinkedNodeKind.typeName) {
return node.typeName_type;
} else {
throw UnimplementedError('$kind');
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 32edf88..087ef97 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -443,12 +443,6 @@
@override
@failingTest
- test_const_reference_staticMethod_imported() async {
- await super.test_const_reference_staticMethod_imported();
- }
-
- @override
- @failingTest
test_const_reference_staticMethod_imported_withPrefix() async {
await super.test_const_reference_staticMethod_imported_withPrefix();
}
@@ -750,12 +744,6 @@
@override
@failingTest
- test_executable_parameter_type_typedef() async {
- await super.test_executable_parameter_type_typedef();
- }
-
- @override
- @failingTest
test_export_class() async {
await super.test_export_class();
}
@@ -1014,42 +1002,12 @@
@override
@failingTest
- test_genericFunction_asFunctionReturnType() async {
- await super.test_genericFunction_asFunctionReturnType();
- }
-
- @override
- @failingTest
test_genericFunction_asFunctionTypedParameterReturnType() async {
await super.test_genericFunction_asFunctionTypedParameterReturnType();
}
@override
@failingTest
- test_genericFunction_asGenericFunctionReturnType() async {
- await super.test_genericFunction_asGenericFunctionReturnType();
- }
-
- @override
- @failingTest
- test_genericFunction_asMethodReturnType() async {
- await super.test_genericFunction_asMethodReturnType();
- }
-
- @override
- @failingTest
- test_genericFunction_asParameterType() async {
- await super.test_genericFunction_asParameterType();
- }
-
- @override
- @failingTest
- test_genericFunction_asTopLevelVariableType() async {
- await super.test_genericFunction_asTopLevelVariableType();
- }
-
- @override
- @failingTest
test_getter_inferred_type_nonStatic_implicit_return() async {
await super.test_getter_inferred_type_nonStatic_implicit_return();
}
@@ -1683,12 +1641,6 @@
@override
@failingTest
- test_type_reference_lib_to_lib() async {
- await super.test_type_reference_lib_to_lib();
- }
-
- @override
- @failingTest
test_type_reference_lib_to_part() async {
await super.test_type_reference_lib_to_part();
}
@@ -1773,24 +1725,6 @@
@override
@failingTest
- test_type_reference_to_typedef() async {
- await super.test_type_reference_to_typedef();
- }
-
- @override
- @failingTest
- test_type_reference_to_typedef_with_type_arguments() async {
- await super.test_type_reference_to_typedef_with_type_arguments();
- }
-
- @override
- @failingTest
- test_type_reference_to_typedef_with_type_arguments_implicit() async {
- await super.test_type_reference_to_typedef_with_type_arguments_implicit();
- }
-
- @override
- @failingTest
test_type_unresolved_prefixed() async {
await super.test_type_unresolved_prefixed();
}
@@ -1827,12 +1761,6 @@
@override
@failingTest
- test_typedef_parameters_named() async {
- await super.test_typedef_parameters_named();
- }
-
- @override
- @failingTest
test_typedef_type_parameters_bound_recursive() async {
await super.test_typedef_type_parameters_bound_recursive();
}