Rework storing type parameters and function types.
R=brianwilkerson@google.com, paulberry@google.com
Change-Id: Ia2c71237cf0f7d9c31c7036522bb24a1aaead92f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99094
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 f3c39fc..85e699d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1060,31 +1060,6 @@
return _type;
}
- @override
- List<TypeParameterElement> get typeParameters {
- if (_typeParameterElements != null) return _typeParameterElements;
-
- if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- var containerRef = reference.getChild('@typeParameter');
- var typeParameters = context.getTypeParameters2(linkedNode);
- if (typeParameters == null) {
- return _typeParameterElements = const [];
- }
- return _typeParameterElements = typeParameters.typeParameters.map((node) {
- var name = node.name.name;
- var reference = containerRef.getChild(name);
- if (reference.element == null) {
- reference.node2 = node;
- TypeParameterElementImpl.forLinkedNode(this, reference, node);
- }
- return reference.element as TypeParameterElementImpl;
- }).toList();
- }
-
- return super.typeParameters;
- }
-
/// Set the type parameters defined for this class to the given
/// [typeParameters].
void set typeParameters(List<TypeParameterElement> typeParameters) {
@@ -9243,7 +9218,8 @@
@override
String get name {
if (linkedNode != null) {
- return reference.name;
+ TypeParameter node = this.linkedNode;
+ return node.name.name;
}
if (_unlinkedTypeParam != null) {
return _unlinkedTypeParam.name;
@@ -9317,20 +9293,14 @@
if (_typeParameterElements != null) return _typeParameterElements;
if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- var containerRef = reference.getChild('@typeParameter');
- var typeParameters = context.getTypeParameters2(linkedNode);
+ var typeParameters = linkedContext.getTypeParameters2(linkedNode);
if (typeParameters == null) {
return _typeParameterElements = const [];
}
return _typeParameterElements = typeParameters.typeParameters.map((node) {
- var name = node.name.name;
- var reference = containerRef.getChild(name);
- if (reference.element == null) {
- reference.node2 = node;
- TypeParameterElementImpl.forLinkedNode(this, reference, node);
- }
- return reference.element as TypeParameterElementImpl;
+ TypeParameterElementImpl element = node.declaredElement;
+ element.enclosingElement = this;
+ return element;
}).toList();
}
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index b3fd95f..dbf57f9 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -8,6 +8,37 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_visitor.dart';
+/// Generates a fresh copy of the given type parameters, with their bounds
+/// substituted to reference the new parameters.
+///
+/// The returned object contains the fresh type parameter list as well as a
+/// mapping to be used for replacing other types to use the new type parameters.
+FreshTypeParameters getFreshTypeParameters(
+ List<TypeParameterElement> typeParameters) {
+ var freshParameters = new List<TypeParameterElementImpl>.generate(
+ typeParameters.length,
+ (i) => new TypeParameterElementImpl(typeParameters[i].name, -1),
+ growable: true,
+ );
+
+ var map = <TypeParameterElement, DartType>{};
+ for (int i = 0; i < typeParameters.length; ++i) {
+ map[typeParameters[i]] = new TypeParameterTypeImpl(freshParameters[i]);
+ }
+
+ var substitution = Substitution.fromMap(map);
+
+ for (int i = 0; i < typeParameters.length; ++i) {
+ var bound = typeParameters[i].bound;
+ if (bound != null) {
+ var newBound = substitution.substituteType(bound);
+ freshParameters[i].bound = newBound;
+ }
+ }
+
+ return new FreshTypeParameters(freshParameters, substitution);
+}
+
/// Returns a type where all occurrences of the given type parameters have been
/// replaced with the corresponding types.
///
@@ -27,6 +58,30 @@
return Substitution.fromMap(substitution).substituteType(type);
}
+class FreshTypeParameters {
+ final List<TypeParameterElement> freshTypeParameters;
+ final Substitution substitution;
+
+ FreshTypeParameters(this.freshTypeParameters, this.substitution);
+
+ FunctionType applyToFunctionType(FunctionType type) {
+ return new FunctionTypeImpl.synthetic(
+ substitute(type.returnType),
+ freshTypeParameters,
+ type.parameters.map((parameter) {
+ return ParameterElementImpl.synthetic(
+ parameter.name,
+ substitute(parameter.type),
+ // ignore: deprecated_member_use_from_same_package
+ parameter.parameterKind,
+ );
+ }).toList(),
+ );
+ }
+
+ DartType substitute(DartType type) => substitution.substituteType(type);
+}
+
abstract class Substitution {
static const Substitution empty = _NullSubstitution.instance;
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index fd78d94..e3d8d32 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -8175,6 +8175,12 @@
}
@override
+ int get typeParameter_id {
+ assert(kind == idl.LinkedNodeKind.typeParameter);
+ return _variantField_16 ??= 0;
+ }
+
+ @override
int get typeParameterList_rightBracket {
assert(kind == idl.LinkedNodeKind.typeParameterList);
return _variantField_16 ??= 0;
@@ -8508,6 +8514,12 @@
_variantField_16 = value;
}
+ set typeParameter_id(int value) {
+ assert(kind == idl.LinkedNodeKind.typeParameter);
+ assert(value == null || value >= 0);
+ _variantField_16 = value;
+ }
+
set typeParameterList_rightBracket(int value) {
assert(kind == idl.LinkedNodeKind.typeParameterList);
assert(value == null || value >= 0);
@@ -10649,6 +10661,7 @@
LinkedNodeBuilder typeParameter_bound,
int typeParameter_extendsKeyword,
LinkedNodeBuilder typeParameter_name,
+ int typeParameter_id,
int codeLength,
int codeOffset,
}) : _kind = idl.LinkedNodeKind.typeParameter,
@@ -10657,6 +10670,7 @@
_variantField_6 = typeParameter_bound,
_variantField_15 = typeParameter_extendsKeyword,
_variantField_7 = typeParameter_name,
+ _variantField_16 = typeParameter_id,
_variantField_34 = codeLength,
_variantField_33 = codeOffset;
@@ -14400,6 +14414,14 @@
}
@override
+ int get typeParameter_id {
+ assert(kind == idl.LinkedNodeKind.typeParameter);
+ _variantField_16 ??=
+ const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
+ return _variantField_16;
+ }
+
+ @override
int get typeParameterList_rightBracket {
assert(kind == idl.LinkedNodeKind.typeParameterList);
_variantField_16 ??=
@@ -16265,6 +16287,7 @@
_result["typeParameter_extendsKeyword"] = typeParameter_extendsKeyword;
if (typeParameter_name != null)
_result["typeParameter_name"] = typeParameter_name.toJson();
+ if (typeParameter_id != 0) _result["typeParameter_id"] = typeParameter_id;
if (codeLength != 0) _result["codeLength"] = codeLength;
if (codeOffset != 0) _result["codeOffset"] = codeOffset;
}
@@ -17689,6 +17712,7 @@
"typeParameter_bound": typeParameter_bound,
"typeParameter_extendsKeyword": typeParameter_extendsKeyword,
"typeParameter_name": typeParameter_name,
+ "typeParameter_id": typeParameter_id,
"codeLength": codeLength,
"codeOffset": codeOffset,
"isSynthetic": isSynthetic,
@@ -18891,13 +18915,13 @@
implements idl.LinkedNodeType {
List<LinkedNodeTypeFormalParameterBuilder> _functionFormalParameters;
LinkedNodeTypeBuilder _functionReturnType;
- List<int> _functionTypeParameters;
+ List<LinkedNodeTypeTypeParameterBuilder> _functionTypeParameters;
int _genericTypeAliasReference;
List<LinkedNodeTypeBuilder> _genericTypeAliasTypeArguments;
int _interfaceClass;
List<LinkedNodeTypeBuilder> _interfaceTypeArguments;
idl.LinkedNodeTypeKind _kind;
- int _typeParameterParameter;
+ int _typeParameterId;
@override
List<LinkedNodeTypeFormalParameterBuilder> get functionFormalParameters =>
@@ -18916,11 +18940,10 @@
}
@override
- List<int> get functionTypeParameters => _functionTypeParameters ??= <int>[];
+ List<LinkedNodeTypeTypeParameterBuilder> get functionTypeParameters =>
+ _functionTypeParameters ??= <LinkedNodeTypeTypeParameterBuilder>[];
- /// References to [LinkedNodeReferences].
- set functionTypeParameters(List<int> value) {
- assert(value == null || value.every((e) => e >= 0));
+ set functionTypeParameters(List<LinkedNodeTypeTypeParameterBuilder> value) {
this._functionTypeParameters = value;
}
@@ -18965,24 +18988,23 @@
}
@override
- int get typeParameterParameter => _typeParameterParameter ??= 0;
+ int get typeParameterId => _typeParameterId ??= 0;
- /// Reference to a [LinkedNodeReferences].
- set typeParameterParameter(int value) {
+ set typeParameterId(int value) {
assert(value == null || value >= 0);
- this._typeParameterParameter = value;
+ this._typeParameterId = value;
}
LinkedNodeTypeBuilder(
{List<LinkedNodeTypeFormalParameterBuilder> functionFormalParameters,
LinkedNodeTypeBuilder functionReturnType,
- List<int> functionTypeParameters,
+ List<LinkedNodeTypeTypeParameterBuilder> functionTypeParameters,
int genericTypeAliasReference,
List<LinkedNodeTypeBuilder> genericTypeAliasTypeArguments,
int interfaceClass,
List<LinkedNodeTypeBuilder> interfaceTypeArguments,
idl.LinkedNodeTypeKind kind,
- int typeParameterParameter})
+ int typeParameterId})
: _functionFormalParameters = functionFormalParameters,
_functionReturnType = functionReturnType,
_functionTypeParameters = functionTypeParameters,
@@ -18991,12 +19013,13 @@
_interfaceClass = interfaceClass,
_interfaceTypeArguments = interfaceTypeArguments,
_kind = kind,
- _typeParameterParameter = typeParameterParameter;
+ _typeParameterId = typeParameterId;
/// Flush [informative] data recursively.
void flushInformative() {
_functionFormalParameters?.forEach((b) => b.flushInformative());
_functionReturnType?.flushInformative();
+ _functionTypeParameters?.forEach((b) => b.flushInformative());
_genericTypeAliasTypeArguments?.forEach((b) => b.flushInformative());
_interfaceTypeArguments?.forEach((b) => b.flushInformative());
}
@@ -19018,7 +19041,7 @@
} else {
signature.addInt(this._functionTypeParameters.length);
for (var x in this._functionTypeParameters) {
- signature.addInt(x);
+ x?.collectApiSignature(signature);
}
}
signature.addInt(this._interfaceClass ?? 0);
@@ -19031,7 +19054,7 @@
}
}
signature.addInt(this._kind == null ? 0 : this._kind.index);
- signature.addInt(this._typeParameterParameter ?? 0);
+ signature.addInt(this._typeParameterId ?? 0);
signature.addInt(this._genericTypeAliasReference ?? 0);
if (this._genericTypeAliasTypeArguments == null) {
signature.addInt(0);
@@ -19058,8 +19081,8 @@
offset_functionReturnType = _functionReturnType.finish(fbBuilder);
}
if (!(_functionTypeParameters == null || _functionTypeParameters.isEmpty)) {
- offset_functionTypeParameters =
- fbBuilder.writeListUint32(_functionTypeParameters);
+ offset_functionTypeParameters = fbBuilder.writeList(
+ _functionTypeParameters.map((b) => b.finish(fbBuilder)).toList());
}
if (!(_genericTypeAliasTypeArguments == null ||
_genericTypeAliasTypeArguments.isEmpty)) {
@@ -19097,8 +19120,8 @@
if (_kind != null && _kind != idl.LinkedNodeTypeKind.bottom) {
fbBuilder.addUint8(5, _kind.index);
}
- if (_typeParameterParameter != null && _typeParameterParameter != 0) {
- fbBuilder.addUint32(6, _typeParameterParameter);
+ if (_typeParameterId != null && _typeParameterId != 0) {
+ fbBuilder.addUint32(6, _typeParameterId);
}
return fbBuilder.endTable();
}
@@ -19122,13 +19145,13 @@
List<idl.LinkedNodeTypeFormalParameter> _functionFormalParameters;
idl.LinkedNodeType _functionReturnType;
- List<int> _functionTypeParameters;
+ List<idl.LinkedNodeTypeTypeParameter> _functionTypeParameters;
int _genericTypeAliasReference;
List<idl.LinkedNodeType> _genericTypeAliasTypeArguments;
int _interfaceClass;
List<idl.LinkedNodeType> _interfaceTypeArguments;
idl.LinkedNodeTypeKind _kind;
- int _typeParameterParameter;
+ int _typeParameterId;
@override
List<idl.LinkedNodeTypeFormalParameter> get functionFormalParameters {
@@ -19148,9 +19171,12 @@
}
@override
- List<int> get functionTypeParameters {
+ List<idl.LinkedNodeTypeTypeParameter> get functionTypeParameters {
_functionTypeParameters ??=
- const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
+ const fb.ListReader<idl.LinkedNodeTypeTypeParameter>(
+ const _LinkedNodeTypeTypeParameterReader())
+ .vTableGet(
+ _bc, _bcOffset, 2, const <idl.LinkedNodeTypeTypeParameter>[]);
return _functionTypeParameters;
}
@@ -19191,10 +19217,10 @@
}
@override
- int get typeParameterParameter {
- _typeParameterParameter ??=
+ int get typeParameterId {
+ _typeParameterId ??=
const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
- return _typeParameterParameter;
+ return _typeParameterId;
}
}
@@ -19208,7 +19234,8 @@
if (functionReturnType != null)
_result["functionReturnType"] = functionReturnType.toJson();
if (functionTypeParameters.isNotEmpty)
- _result["functionTypeParameters"] = functionTypeParameters;
+ _result["functionTypeParameters"] =
+ functionTypeParameters.map((_value) => _value.toJson()).toList();
if (genericTypeAliasReference != 0)
_result["genericTypeAliasReference"] = genericTypeAliasReference;
if (genericTypeAliasTypeArguments.isNotEmpty)
@@ -19221,8 +19248,7 @@
interfaceTypeArguments.map((_value) => _value.toJson()).toList();
if (kind != idl.LinkedNodeTypeKind.bottom)
_result["kind"] = kind.toString().split('.')[1];
- if (typeParameterParameter != 0)
- _result["typeParameterParameter"] = typeParameterParameter;
+ if (typeParameterId != 0) _result["typeParameterId"] = typeParameterId;
return _result;
}
@@ -19236,7 +19262,7 @@
"interfaceClass": interfaceClass,
"interfaceTypeArguments": interfaceTypeArguments,
"kind": kind,
- "typeParameterParameter": typeParameterParameter,
+ "typeParameterId": typeParameterId,
};
@override
@@ -19381,6 +19407,116 @@
String toString() => convert.json.encode(toJson());
}
+class LinkedNodeTypeTypeParameterBuilder extends Object
+ with _LinkedNodeTypeTypeParameterMixin
+ implements idl.LinkedNodeTypeTypeParameter {
+ LinkedNodeTypeBuilder _bound;
+ String _name;
+
+ @override
+ LinkedNodeTypeBuilder get bound => _bound;
+
+ set bound(LinkedNodeTypeBuilder value) {
+ this._bound = value;
+ }
+
+ @override
+ String get name => _name ??= '';
+
+ set name(String value) {
+ this._name = value;
+ }
+
+ LinkedNodeTypeTypeParameterBuilder({LinkedNodeTypeBuilder bound, String name})
+ : _bound = bound,
+ _name = name;
+
+ /// Flush [informative] data recursively.
+ void flushInformative() {
+ _bound?.flushInformative();
+ }
+
+ /// Accumulate non-[informative] data into [signature].
+ void collectApiSignature(api_sig.ApiSignature signature) {
+ signature.addString(this._name ?? '');
+ signature.addBool(this._bound != null);
+ this._bound?.collectApiSignature(signature);
+ }
+
+ fb.Offset finish(fb.Builder fbBuilder) {
+ fb.Offset offset_bound;
+ fb.Offset offset_name;
+ if (_bound != null) {
+ offset_bound = _bound.finish(fbBuilder);
+ }
+ if (_name != null) {
+ offset_name = fbBuilder.writeString(_name);
+ }
+ fbBuilder.startTable();
+ if (offset_bound != null) {
+ fbBuilder.addOffset(1, offset_bound);
+ }
+ if (offset_name != null) {
+ fbBuilder.addOffset(0, offset_name);
+ }
+ return fbBuilder.endTable();
+ }
+}
+
+class _LinkedNodeTypeTypeParameterReader
+ extends fb.TableReader<_LinkedNodeTypeTypeParameterImpl> {
+ const _LinkedNodeTypeTypeParameterReader();
+
+ @override
+ _LinkedNodeTypeTypeParameterImpl createObject(
+ fb.BufferContext bc, int offset) =>
+ new _LinkedNodeTypeTypeParameterImpl(bc, offset);
+}
+
+class _LinkedNodeTypeTypeParameterImpl extends Object
+ with _LinkedNodeTypeTypeParameterMixin
+ implements idl.LinkedNodeTypeTypeParameter {
+ final fb.BufferContext _bc;
+ final int _bcOffset;
+
+ _LinkedNodeTypeTypeParameterImpl(this._bc, this._bcOffset);
+
+ idl.LinkedNodeType _bound;
+ String _name;
+
+ @override
+ idl.LinkedNodeType get bound {
+ _bound ??= const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 1, null);
+ return _bound;
+ }
+
+ @override
+ String get name {
+ _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+ return _name;
+ }
+}
+
+abstract class _LinkedNodeTypeTypeParameterMixin
+ implements idl.LinkedNodeTypeTypeParameter {
+ @override
+ Map<String, Object> toJson() {
+ Map<String, Object> _result = <String, Object>{};
+ if (bound != null) _result["bound"] = bound.toJson();
+ if (name != '') _result["name"] = name;
+ return _result;
+ }
+
+ @override
+ Map<String, Object> toMap() => {
+ "bound": bound,
+ "name": name,
+ };
+
+ @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 bb86ffb..dea7ce6 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -406,8 +406,6 @@
function,
- genericTypeAlias,
-
interface,
typeParameter,
@@ -1945,8 +1943,7 @@
functionReturnType:LinkedNodeType (id: 1);
- /// References to [LinkedNodeReferences].
- functionTypeParameters:[uint] (id: 2);
+ functionTypeParameters:[LinkedNodeTypeTypeParameter] (id: 2);
genericTypeAliasReference:uint (id: 7);
@@ -1959,8 +1956,7 @@
kind:LinkedNodeTypeKind (id: 5);
- /// Reference to a [LinkedNodeReferences].
- typeParameterParameter:uint (id: 6);
+ typeParameterId:uint (id: 6);
}
/// Information about a formal parameter in a function type.
@@ -1972,6 +1968,13 @@
type:LinkedNodeType (id: 2);
}
+/// Information about a type parameter in a function type.
+table LinkedNodeTypeTypeParameter {
+ bound:LinkedNodeType (id: 1);
+
+ name:string (id: 0);
+}
+
/// 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 4b897bc..033e6ff 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -2222,6 +2222,9 @@
@VariantId(15, variant: LinkedNodeKind.typeParameter)
int get typeParameter_extendsKeyword;
+ @VariantId(16, variant: LinkedNodeKind.typeParameter)
+ int get typeParameter_id;
+
@VariantId(7, variant: LinkedNodeKind.typeParameter)
LinkedNode get typeParameter_name;
@@ -2501,9 +2504,8 @@
@Id(1)
LinkedNodeType get functionReturnType;
- /// References to [LinkedNodeReferences].
@Id(2)
- List<int> get functionTypeParameters;
+ List<LinkedNodeTypeTypeParameter> get functionTypeParameters;
@Id(7)
int get genericTypeAliasReference;
@@ -2521,9 +2523,8 @@
@Id(5)
LinkedNodeTypeKind get kind;
- /// Reference to a [LinkedNodeReferences].
@Id(6)
- int get typeParameterParameter;
+ int get typeParameterId;
}
/// Information about a formal parameter in a function type.
@@ -2543,12 +2544,20 @@
bottom,
dynamic_,
function,
- genericTypeAlias,
interface,
typeParameter,
void_
}
+/// Information about a type parameter in a function type.
+abstract class LinkedNodeTypeTypeParameter extends base.SummaryClass {
+ @Id(1)
+ LinkedNodeType get bound;
+
+ @Id(0)
+ String get name;
+}
+
/// Information about a single library in a [LinkedNodeLibrary].
abstract class LinkedNodeUnit extends base.SummaryClass {
@Id(2)
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index e08c4f6..b9cc2d1 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -9,7 +9,6 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.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/lazy_ast.dart';
@@ -240,7 +239,7 @@
_getToken(data.classDeclaration_abstractKeyword),
_getToken(data.classDeclaration_classKeyword),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.classOrMixinDeclaration_typeParameters),
+ _readNode(data.classOrMixinDeclaration_typeParameters),
_readNodeLazy(data.classDeclaration_extendsClause),
_readNodeLazy(data.classDeclaration_withClause),
_readNodeLazy(data.classOrMixinDeclaration_implementsClause),
@@ -259,7 +258,7 @@
_readNodeListLazy(data.annotatedNode_metadata),
_getToken(data.typeAlias_typedefKeyword),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.classTypeAlias_typeParameters),
+ _readNode(data.classTypeAlias_typeParameters),
_getToken(data.classTypeAlias_equals),
_getToken(data.classTypeAlias_abstractKeyword),
_readNodeLazy(data.classTypeAlias_superclass),
@@ -618,7 +617,7 @@
_localParameters = thisLocalParameters;
var node = astFactory.functionExpression(
- _readNodeLazy(data.functionExpression_typeParameters),
+ _readNode(data.functionExpression_typeParameters),
_readNodeLazy(data.functionExpression_formalParameters),
_readNodeLazy(data.functionExpression_body),
);
@@ -664,7 +663,7 @@
_getToken(data.typeAlias_typedefKeyword),
_readNodeLazy(data.functionTypeAlias_returnType),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.functionTypeAlias_typeParameters),
+ _readNode(data.functionTypeAlias_typeParameters),
_readNodeLazy(data.functionTypeAlias_formalParameters),
_getToken(data.typeAlias_semicolon),
);
@@ -705,7 +704,7 @@
GenericFunctionTypeImpl node = astFactory.genericFunctionType(
_readNodeLazy(data.genericFunctionType_returnType),
_getToken(data.genericFunctionType_functionKeyword),
- _readNodeLazy(data.genericFunctionType_typeParameters),
+ _readNode(data.genericFunctionType_typeParameters),
_readNodeLazy(data.genericFunctionType_formalParameters),
question: _getToken(data.genericFunctionType_question),
);
@@ -720,7 +719,7 @@
_readNodeList(data.annotatedNode_metadata),
_getToken(data.typeAlias_typedefKeyword),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.genericTypeAlias_typeParameters),
+ _readNode(data.genericTypeAlias_typeParameters),
_getToken(data.genericTypeAlias_equals),
_readNodeLazy(data.genericTypeAlias_functionType),
_getToken(data.typeAlias_semicolon),
@@ -896,7 +895,7 @@
_getToken(data.methodDeclaration_propertyKeyword),
_getToken(data.methodDeclaration_operatorKeyword),
_readNode(data.methodDeclaration_name),
- _readNodeLazy(data.methodDeclaration_typeParameters),
+ _readNode(data.methodDeclaration_typeParameters),
_readNodeLazy(data.methodDeclaration_formalParameters),
_readNodeLazy(data.methodDeclaration_body),
);
@@ -920,7 +919,7 @@
_readNodeList(data.annotatedNode_metadata),
_getToken(data.mixinDeclaration_mixinKeyword),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.classOrMixinDeclaration_typeParameters),
+ _readNode(data.classOrMixinDeclaration_typeParameters),
_readNodeLazy(data.mixinDeclaration_onClause),
_readNodeLazy(data.classOrMixinDeclaration_implementsClause),
_getToken(data.classOrMixinDeclaration_leftBracket),
@@ -1256,6 +1255,7 @@
_readNodeLazy(data.typeParameter_bound),
);
LazyTypeParameter.setData(node, data);
+ _unitContext.addTypeParameter(data.typeParameter_id, node);
return node;
}
@@ -1588,57 +1588,6 @@
}
DartType _readType(LinkedNodeType data) {
- if (data == null) return null;
-
- switch (data.kind) {
- case LinkedNodeTypeKind.bottom:
- return BottomTypeImpl.instance;
- case LinkedNodeTypeKind.dynamic_:
- return DynamicTypeImpl.instance;
- case LinkedNodeTypeKind.function:
- return FunctionTypeImpl.synthetic(
- _readType(data.functionReturnType),
- _getElements(data.functionTypeParameters),
- data.functionFormalParameters
- .map((p) => ParameterElementImpl.synthetic(
- p.name, _readType(p.type), _formalParameterKind(p.kind)))
- .toList(),
- );
- case LinkedNodeTypeKind.interface:
- var element = _getElement(data.interfaceClass);
- if (element != null) {
- return InterfaceTypeImpl.explicit(
- element,
- _readTypes(
- data.interfaceTypeArguments,
- const <InterfaceType>[],
- ),
- );
- }
- return DynamicTypeImpl.instance;
- case LinkedNodeTypeKind.typeParameter:
- var element = _getElement(data.typeParameterParameter);
- // TODO(scheglov) Remove when references include all type parameters.
- element ??= TypeParameterElementImpl('', -1);
- return TypeParameterTypeImpl(element);
- case LinkedNodeTypeKind.void_:
- return VoidTypeImpl.instance;
- default:
- throw UnimplementedError('Type kind: ${data.kind}');
- }
- }
-
- List<T> _readTypes<T extends DartType>(
- List<LinkedNodeType> dataList,
- List<T> ifEmpty,
- ) {
- if (dataList.isEmpty) return ifEmpty;
-
- var result = List<T>(dataList.length);
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- result[i] = _readType(data);
- }
- return result;
+ return _unitContext.readType(data);
}
}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 0766c24..9f70a6b 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -8,8 +8,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
@@ -18,7 +16,7 @@
/// Serializer of fully resolved ASTs into flat buffers.
class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
- final LinkingBundleContext _linkingBundleContext;
+ final LinkingBundleContext _linkingContext;
final TokensContext _tokensContext;
/// This field is set temporary while visiting [FieldDeclaration] or
@@ -26,7 +24,7 @@
/// in these declarations.
LinkedNodeVariablesDeclarationBuilder _variablesDeclaration;
- AstBinaryWriter(this._linkingBundleContext, this._tokensContext);
+ AstBinaryWriter(this._linkingContext, this._tokensContext);
@override
LinkedNodeBuilder visitAdjacentStrings(AdjacentStrings node) {
@@ -94,7 +92,7 @@
@override
LinkedNodeBuilder visitAssignmentExpression(AssignmentExpression node) {
return LinkedNodeBuilder.assignmentExpression(
- assignmentExpression_element: _getReferenceIndex(node.staticElement),
+ assignmentExpression_element: _indexOfElement(node.staticElement),
assignmentExpression_leftHandSide: node.leftHandSide.accept(this),
assignmentExpression_operator: _getToken(node.operator),
assignmentExpression_rightHandSide: node.rightHandSide.accept(this),
@@ -114,7 +112,7 @@
@override
LinkedNodeBuilder visitBinaryExpression(BinaryExpression node) {
return LinkedNodeBuilder.binaryExpression(
- binaryExpression_element: _getReferenceIndex(node.staticElement),
+ binaryExpression_element: _indexOfElement(node.staticElement),
binaryExpression_leftOperand: node.leftOperand.accept(this),
binaryExpression_operator: _getToken(node.operator),
binaryExpression_rightOperand: node.rightOperand.accept(this),
@@ -303,7 +301,7 @@
@override
LinkedNodeBuilder visitConstructorName(ConstructorName node) {
return LinkedNodeBuilder.constructorName(
- constructorName_element: _getReferenceIndex(node.staticElement),
+ constructorName_element: _indexOfElement(node.staticElement),
constructorName_name: node.name?.accept(this),
constructorName_period: _getToken(node.period),
constructorName_type: node.type.accept(this),
@@ -695,7 +693,7 @@
@override
LinkedNodeBuilder visitIndexExpression(IndexExpression node) {
return LinkedNodeBuilder.indexExpression(
- indexExpression_element: _getReferenceIndex(node.staticElement),
+ indexExpression_element: _indexOfElement(node.staticElement),
indexExpression_index: node.index.accept(this),
indexExpression_leftBracket: _getToken(node.leftBracket),
indexExpression_period: _getToken(node.period),
@@ -931,7 +929,7 @@
LinkedNodeBuilder visitPostfixExpression(PostfixExpression node) {
return LinkedNodeBuilder.postfixExpression(
expression_type: _writeType(node.staticType),
- postfixExpression_element: _getReferenceIndex(node.staticElement),
+ postfixExpression_element: _indexOfElement(node.staticElement),
postfixExpression_operand: node.operand.accept(this),
postfixExpression_operator: _getToken(node.operator),
);
@@ -951,7 +949,7 @@
LinkedNodeBuilder visitPrefixExpression(PrefixExpression node) {
return LinkedNodeBuilder.prefixExpression(
expression_type: _writeType(node.staticType),
- prefixExpression_element: _getReferenceIndex(node.staticElement),
+ prefixExpression_element: _indexOfElement(node.staticElement),
prefixExpression_operand: node.operand.accept(this),
prefixExpression_operator: _getToken(node.operator),
);
@@ -977,7 +975,7 @@
redirectingConstructorInvocation_constructorName:
node.constructorName?.accept(this),
redirectingConstructorInvocation_element:
- _getReferenceIndex(node.staticElement),
+ _indexOfElement(node.staticElement),
redirectingConstructorInvocation_period: _getToken(node.period),
redirectingConstructorInvocation_thisKeyword: _getToken(node.thisKeyword),
);
@@ -1053,7 +1051,7 @@
}
return LinkedNodeBuilder.simpleIdentifier(
- simpleIdentifier_element: _getReferenceIndex(element),
+ simpleIdentifier_element: _indexOfElement(element),
simpleIdentifier_token: _getToken(node.token),
expression_type: _writeType(node.staticType),
);
@@ -1092,8 +1090,7 @@
superConstructorInvocation_arguments: node.argumentList.accept(this),
superConstructorInvocation_constructorName:
node.constructorName?.accept(this),
- superConstructorInvocation_element:
- _getReferenceIndex(node.staticElement),
+ superConstructorInvocation_element: _indexOfElement(node.staticElement),
superConstructorInvocation_period: _getToken(node.period),
superConstructorInvocation_superKeyword: _getToken(node.superKeyword),
);
@@ -1222,6 +1219,9 @@
typeParameter_name: node.name.accept(this));
_storeDeclaration(builder, node);
_storeCodeOffsetLength(builder, node);
+ builder.typeParameter_id = _linkingContext.idOfTypeParameter(
+ node.declaredElement,
+ );
return builder;
}
@@ -1307,21 +1307,6 @@
return node.accept(this);
}
- int _getReferenceIndex(Element element) {
- if (element == null) return 0;
-
- if (element is Member) {
- element = (element as Member).baseElement;
- }
-
- var reference = (element as ElementImpl).reference;
- if (identical(element, DynamicElementImpl.instance)) {
- reference = _linkingBundleContext.dynamicReference;
- }
-
- return _linkingBundleContext.indexOfReference(reference);
- }
-
int _getToken(Token token) {
return _tokensContext.indexOfToken(token);
}
@@ -1335,6 +1320,10 @@
return result;
}
+ int _indexOfElement(Element element) {
+ return _linkingContext.indexOfElement(element);
+ }
+
void _storeAnnotatedNode(LinkedNodeBuilder builder, AnnotatedNode node) {
builder
..annotatedNode_comment = node.documentationComment?.accept(this)
@@ -1517,7 +1506,7 @@
builder
..uriBasedDirective_uri = node.uri.accept(this)
..uriBasedDirective_uriContent = node.uriContent
- ..uriBasedDirective_uriElement = _getReferenceIndex(node.uriElement);
+ ..uriBasedDirective_uriElement = _indexOfElement(node.uriElement);
}
void _writeActualReturnType(LinkedNodeBuilder builder, AstNode node) {
@@ -1545,6 +1534,6 @@
}
LinkedNodeTypeBuilder _writeType(DartType type) {
- return _linkingBundleContext.writeType(type);
+ return _linkingContext.writeType(type);
}
}
diff --git a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
index 7339358..f320371 100644
--- a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
@@ -299,6 +299,7 @@
var unitRef = reference.getChild('@unit');
var unitReference = unitRef.getChild(unitContext.uriStr);
var resolver = ReferenceResolver(
+ linker.linkingBundleContext,
nodesToBuildType,
linker.elementFactory,
element,
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index 21076aa..9c7c1cc 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -45,7 +45,6 @@
bool _hasImplementsClause = false;
bool _hasMembers = false;
bool _hasMetadata = false;
- bool _hasTypeParameters = false;
bool _hasWithClause = false;
LazyClassDeclaration(this.data);
@@ -123,19 +122,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- ClassDeclaration node,
- ) {
- var lazy = LazyClassDeclaration.get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.classOrMixinDeclaration_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void readWithClause(
AstBinaryReader reader,
ClassDeclaration node,
@@ -163,7 +149,6 @@
bool _hasImplementsClause = false;
bool _hasMetadata = false;
bool _hasSuperclass = false;
- bool _hasTypeParameters = false;
bool _hasWithClause = false;
LazyClassTypeAlias(this.data);
@@ -228,19 +213,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- ClassTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.classTypeAlias_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void readWithClause(
AstBinaryReader reader,
ClassTypeAlias node,
@@ -635,6 +607,7 @@
AstBinaryReader reader,
FunctionDeclaration node,
) {
+ readFunctionExpression(reader, node);
if (reader.isLazy) {
var lazy = get(node);
if (!lazy._hasReturnType) {
@@ -698,7 +671,6 @@
bool _hasBody = false;
bool _hasFormalParameters = false;
- bool _hasTypeParameters = false;
LazyFunctionExpression(this.data);
@@ -732,19 +704,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- FunctionExpression node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.functionExpression_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(FunctionExpression node, LinkedNode data) {
node.setProperty(_key, LazyFunctionExpression(data));
}
@@ -759,7 +718,6 @@
bool _hasFormalParameters = false;
bool _hasMetadata = false;
bool _hasReturnType = false;
- bool _hasTypeParameters = false;
LazyFunctionTypeAlias(this.data);
@@ -823,19 +781,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- FunctionTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.functionTypeAlias_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(FunctionTypeAlias node, LinkedNode data) {
node.setProperty(_key, LazyFunctionTypeAlias(data));
}
@@ -895,7 +840,6 @@
bool _hasDocumentationComment = false;
bool _hasFunction = false;
- bool _hasTypeParameters = false;
LazyGenericTypeAlias(this.data);
@@ -929,19 +873,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- GenericTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.genericTypeAlias_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(GenericTypeAlias node, LinkedNode data) {
node.setProperty(_key, LazyGenericTypeAlias(data));
}
@@ -957,7 +888,6 @@
bool _hasFormalParameters = false;
bool _hasMetadata = false;
bool _hasReturnType = false;
- bool _hasTypeParameters = false;
LazyMethodDeclaration(this.data);
@@ -1034,19 +964,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.methodDeclaration_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(MethodDeclaration node, LinkedNode data) {
node.setProperty(_key, LazyMethodDeclaration(data));
}
@@ -1061,7 +978,6 @@
bool _hasOnClause = false;
bool _hasImplementsClause = false;
bool _hasMembers = false;
- bool _hasTypeParameters = false;
LazyMixinDeclaration(this.data);
@@ -1123,19 +1039,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- MixinDeclarationImpl node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.classOrMixinDeclaration_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(MixinDeclaration node, LinkedNode data) {
node.setProperty(_key, LazyMixinDeclaration(data));
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
index 88f8655..f81e2c4 100644
--- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
@@ -82,52 +82,6 @@
return result;
}
- InterfaceType getInterfaceType(LinkedNodeType linkedType) {
- var type = getType(linkedType);
- if (type is InterfaceType && !type.element.isEnum) {
- return type;
- }
- return null;
- }
-
- DartType getType(LinkedNodeType linkedType) {
- 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 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);
- Element element = elementFactory.elementOfReference(reference);
- return InterfaceTypeImpl.explicit(
- element,
- linkedType.interfaceTypeArguments.map(getType).toList(),
- );
- } else if (kind == LinkedNodeTypeKind.typeParameter) {
- var reference = referenceOfIndex(linkedType.typeParameterParameter);
- Element element = elementFactory.elementOfReference(reference);
- return TypeParameterTypeImpl(element);
- } else if (kind == LinkedNodeTypeKind.void_) {
- return VoidTypeImpl.instance;
- } else {
- throw UnimplementedError('$kind');
- }
- }
-
Reference referenceOfIndex(int index) {
var reference = _references[index];
if (reference != null) return reference;
@@ -147,16 +101,6 @@
return reference;
}
-
- ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
- if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
- return ParameterKind.NAMED;
- }
- if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
- return ParameterKind.POSITIONAL;
- }
- return ParameterKind.REQUIRED;
- }
}
class LinkedLibraryContext {
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index e16238f..88344cb 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -152,11 +152,6 @@
return _typeAlias(unit, reference);
}
- if (parentName == '@typeParameter') {
- var enclosing = elementOfReference(parent2) as TypeParameterizedElement;
- return _typeParameter(enclosing, reference);
- }
-
if (parentName == '@unit') {
elementOfReference(parent2);
// Creating a library fills all its units.
@@ -296,14 +291,6 @@
return reference.element;
}
- Element _typeParameter(
- TypeParameterizedElement enclosing, Reference reference) {
- enclosing.typeParameters;
- // Requesting type parameters sets elements for all their references.
- assert(reference.element != null);
- return reference.element;
- }
-
/// Index nodes for which we choose to create elements individually,
/// for example [ClassDeclaration], so that its [Reference] has the node,
/// and we can call the [ClassElementImpl] constructor.
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 4d82d2d..8a906fe 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -3,8 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
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/type.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -27,6 +29,17 @@
CompilationUnit _unit;
bool _hasDirectivesRead = false;
+ /// Mapping from identifiers to real or synthetic type parameters.
+ ///
+ /// Real type parameters have corresponding [TypeParameter] nodes, and are
+ /// referenced from other AST nodes.
+ ///
+ /// Synthetic type parameters are added when [readType] begins reading a
+ /// [FunctionType], and removed when reading is done.
+ final Map<int, TypeParameterElement> _typeParameters = {};
+
+ int _nextSyntheticTypeParameterId = 0x10000;
+
LinkedUnitContext(this.bundleContext, this.libraryContext,
this.indexInLibrary, this.uriStr, this.data,
{CompilationUnit unit})
@@ -59,6 +72,15 @@
return _unit;
}
+ /// Every [TypeParameter] node has [TypeParameterElement], which is created
+ /// during reading of this node. All type parameter nodes are read before
+ /// any nodes that reference them (bounds are read lazily later).
+ void addTypeParameter(int id, TypeParameter node) {
+ var element = TypeParameterElementImpl.forLinkedNode(null, null, node);
+ _typeParameters[id] = element;
+ node.name.staticElement = element;
+ }
+
/// Return the absolute URI referenced in the [directive].
Uri directiveUri(Uri libraryUri, UriBasedDirective directive) {
var relativeUriStr = directive.uri.stringValue;
@@ -269,7 +291,11 @@
}
InterfaceType getInterfaceType(LinkedNodeType linkedType) {
- return bundleContext.getInterfaceType(linkedType);
+ var type = readType(linkedType);
+ if (type is InterfaceType && !type.element.isEnum) {
+ return type;
+ }
+ return null;
}
List<Annotation> getLibraryMetadata(CompilationUnit unit) {
@@ -460,10 +486,8 @@
TypeParameterList getTypeParameters2(AstNode node) {
if (node is ClassDeclaration) {
- LazyClassDeclaration.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is ClassTypeAlias) {
- LazyClassTypeAlias.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is ConstructorDeclaration) {
return null;
@@ -471,21 +495,16 @@
LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
return getTypeParameters2(node.functionExpression);
} else if (node is FunctionExpression) {
- LazyFunctionExpression.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is FunctionTypeAlias) {
- LazyFunctionTypeAlias.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is GenericFunctionType) {
return node.typeParameters;
} else if (node is GenericTypeAlias) {
- LazyGenericTypeAlias.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is MethodDeclaration) {
- LazyMethodDeclaration.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is MixinDeclaration) {
- LazyMixinDeclaration.readTypeParameters(_astReader, node);
return node.typeParameters;
} else {
throw UnimplementedError('${node.runtimeType}');
@@ -671,6 +690,58 @@
return _astReader.readNode(linkedNode);
}
+ DartType readType(LinkedNodeType linkedType) {
+ if (linkedType == null) return null;
+
+ var kind = linkedType.kind;
+ if (kind == LinkedNodeTypeKind.bottom) {
+ return BottomTypeImpl.instance;
+ } else if (kind == LinkedNodeTypeKind.dynamic_) {
+ return DynamicTypeImpl.instance;
+ } else if (kind == LinkedNodeTypeKind.function) {
+ var typeParameterDataList = linkedType.functionTypeParameters;
+
+ var typeParameters = <TypeParameterElement>[];
+ for (var typeParameterData in typeParameterDataList) {
+ var element = TypeParameterElementImpl(typeParameterData.name, -1);
+ typeParameters.add(element);
+ _typeParameters[_nextSyntheticTypeParameterId++] = element;
+ }
+
+ var returnType = readType(linkedType.functionReturnType);
+ var formalParameters = linkedType.functionFormalParameters.map((p) {
+ var type = readType(p.type);
+ var kind = _formalParameterKind(p.kind);
+ return ParameterElementImpl.synthetic(p.name, type, kind);
+ }).toList();
+
+ for (var i = 0; i < typeParameterDataList.length; ++i) {
+ _typeParameters.remove(--_nextSyntheticTypeParameterId);
+ }
+
+ return FunctionTypeImpl.synthetic(
+ returnType,
+ typeParameters,
+ formalParameters,
+ );
+ } else if (kind == LinkedNodeTypeKind.interface) {
+ var element = bundleContext.elementOfIndex(linkedType.interfaceClass);
+ return InterfaceTypeImpl.explicit(
+ element,
+ linkedType.interfaceTypeArguments.map(readType).toList(),
+ );
+ } else if (kind == LinkedNodeTypeKind.typeParameter) {
+ var id = linkedType.typeParameterId;
+ var element = _typeParameters[id];
+ assert(element != null);
+ return TypeParameterTypeImpl(element);
+ } else if (kind == LinkedNodeTypeKind.void_) {
+ return VoidTypeImpl.instance;
+ } else {
+ throw UnimplementedError('$kind');
+ }
+ }
+
void setReturnType(LinkedNodeBuilder node, DartType type) {
throw UnimplementedError();
// var typeData = bundleContext.linking.writeType(type);
@@ -693,6 +764,16 @@
}
}
+ ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
+ if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
+ return ParameterKind.NAMED;
+ }
+ if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
+ return ParameterKind.POSITIONAL;
+ }
+ return ParameterKind.REQUIRED;
+ }
+
List<ClassMember> _getClassOrMixinMembers(ClassOrMixinDeclaration node) {
if (node is ClassDeclaration) {
LazyClassDeclaration.readMembers(_astReader, node);
diff --git a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
index 6a9fc44..06d86ce 100644
--- a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
@@ -5,7 +5,9 @@
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/dart/element/type_algebra.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -28,8 +30,35 @@
name: [''],
);
+ final Map<TypeParameterElement, int> _typeParameters = Map.identity();
+ int _nextTypeParameterId = 1;
+ int _nextSyntheticTypeParameterId = 0x10000;
+
LinkingBundleContext(this.dynamicReference);
+ void addTypeParameter(TypeParameterElement element) {
+ _typeParameters[element] = _nextTypeParameterId++;
+ }
+
+ int idOfTypeParameter(TypeParameterElement element) {
+ return _typeParameters[element];
+ }
+
+ int indexOfElement(Element element) {
+ if (element == null) return 0;
+
+ if (identical(element, DynamicElementImpl.instance)) {
+ return indexOfReference(dynamicReference);
+ }
+
+ if (element is Member) {
+ element = (element as Member).baseElement;
+ }
+
+ var reference = (element as ElementImpl).reference;
+ return indexOfReference(reference);
+ }
+
int indexOfReference(Reference reference) {
if (reference == null) return 0;
if (reference.parent == null) return 0;
@@ -56,29 +85,18 @@
kind: LinkedNodeTypeKind.dynamic_,
);
} else if (type is FunctionType) {
- return LinkedNodeTypeBuilder(
- kind: LinkedNodeTypeKind.function,
- 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),
- );
+ return _writeFunctionType(type);
} else if (type is InterfaceType) {
return LinkedNodeTypeBuilder(
kind: LinkedNodeTypeKind.interface,
- interfaceClass: _getReferenceIndex(type.element),
+ interfaceClass: indexOfElement(type.element),
interfaceTypeArguments: type.typeArguments.map(writeType).toList(),
);
} else if (type is TypeParameterType) {
+ TypeParameterElementImpl element = type.element;
return LinkedNodeTypeBuilder(
kind: LinkedNodeTypeKind.typeParameter,
- typeParameterParameter: _getReferenceIndex(type.element),
+ typeParameterId: _typeParameters[element],
);
} else if (type is VoidType) {
return LinkedNodeTypeBuilder(
@@ -89,7 +107,9 @@
}
}
- LinkedNodeFormalParameterKind _formalParameterKind(ParameterKind kind) {
+ LinkedNodeFormalParameterKind _formalParameterKind(ParameterElement p) {
+ // ignore: deprecated_member_use_from_same_package
+ var kind = p.parameterKind;
if (kind == ParameterKind.NAMED) {
return LinkedNodeFormalParameterKind.optionalNamed;
}
@@ -99,19 +119,57 @@
return LinkedNodeFormalParameterKind.required;
}
- int _getReferenceIndex(Element element) {
- if (element == null) return 0;
+ FunctionType _toSyntheticFunctionType(FunctionType type) {
+ var typeParameters = type.typeFormals;
- var reference = (element as ElementImpl).reference;
- return indexOfReference(reference);
+ if (typeParameters.isEmpty) return type;
+
+ var onlySyntheticTypeParameters = typeParameters.every((e) {
+ return e is TypeParameterElementImpl && e.linkedNode == null;
+ });
+ if (onlySyntheticTypeParameters) return type;
+
+ var parameters = getFreshTypeParameters(typeParameters);
+ return parameters.applyToFunctionType(type);
}
- List<int> _getReferences(List<Element> elements) {
- var result = List<int>(elements.length);
- for (var i = 0; i < elements.length; ++i) {
- var element = elements[i];
- result[i] = _getReferenceIndex(element);
+ LinkedNodeTypeBuilder _writeFunctionType(FunctionType type) {
+ type = _toSyntheticFunctionType(type);
+
+ var typeParameterBuilders = <LinkedNodeTypeTypeParameterBuilder>[];
+
+ var typeParameters = type.typeFormals;
+ for (var i = 0; i < typeParameters.length; ++i) {
+ var typeParameter = typeParameters[i];
+ _typeParameters[typeParameter] = _nextSyntheticTypeParameterId++;
+ typeParameterBuilders.add(
+ LinkedNodeTypeTypeParameterBuilder(name: typeParameter.name),
+ );
}
+
+ for (var i = 0; i < typeParameters.length; ++i) {
+ var typeParameter = typeParameters[i];
+ typeParameterBuilders[i].bound = writeType(typeParameter.bound);
+ }
+
+ var result = LinkedNodeTypeBuilder(
+ kind: LinkedNodeTypeKind.function,
+ functionFormalParameters: type.parameters
+ .map((p) => LinkedNodeTypeFormalParameterBuilder(
+ kind: _formalParameterKind(p),
+ name: p.name,
+ type: writeType(p.type),
+ ))
+ .toList(),
+ functionReturnType: writeType(type.returnType),
+ functionTypeParameters: typeParameterBuilders,
+ );
+
+ for (var typeParameter in typeParameters) {
+ _typeParameters.remove(typeParameter);
+ --_nextSyntheticTypeParameterId;
+ }
+
return result;
}
}
diff --git a/pkg/analyzer/lib/src/summary2/reference.dart b/pkg/analyzer/lib/src/summary2/reference.dart
index 7f8af39..989ab17 100644
--- a/pkg/analyzer/lib/src/summary2/reference.dart
+++ b/pkg/analyzer/lib/src/summary2/reference.dart
@@ -71,8 +71,6 @@
bool get isTypeAlias => parent != null && parent.name == '@typeAlias';
- bool get isTypeParameter => parent != null && parent.name == '@typeParameter';
-
int get numOfChildren => _children != null ? _children.length : 0;
/// Return the child with the given name, or `null` if does not exist.
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 28bb335..ddf9870 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linking_bundle_context.dart';
import 'package:analyzer/src/summary2/linking_node_scope.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/summary2/type_builder.dart';
@@ -510,6 +511,7 @@
/// the type is set, otherwise we keep it empty, so we will attempt to infer
/// it later).
class ReferenceResolver extends ThrowingAstVisitor<void> {
+ final LinkingBundleContext linkingContext;
final NodesToBuildType nodesToBuildType;
final LinkedElementFactory elementFactory;
final LibraryElement _libraryElement;
@@ -518,6 +520,7 @@
Scope scope;
ReferenceResolver(
+ this.linkingContext,
this.nodesToBuildType,
this.elementFactory,
this._libraryElement,
@@ -536,6 +539,7 @@
var name = node.name.name;
reference = reference.getChild('@class').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = ClassElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -564,6 +568,7 @@
var name = node.name.name;
reference = reference.getChild('@class').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = ClassElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -654,6 +659,7 @@
var name = node.name.name;
reference = reference.getChild('@function').getChild(name);
+ _createTypeParameterElements(node.functionExpression.typeParameters);
var element = FunctionElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -685,6 +691,7 @@
var name = node.name.name;
reference = reference.getChild('@typeAlias').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = GenericTypeAliasElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -719,6 +726,7 @@
var name = '${outerReference.numOfChildren}';
reference = reference.getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = GenericFunctionTypeElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -744,6 +752,7 @@
var name = node.name.name;
reference = reference.getChild('@typeAlias').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = GenericTypeAliasElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -772,6 +781,7 @@
var name = node.name.name;
reference = reference.getChild('@method').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = MethodElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -798,6 +808,7 @@
var name = node.name.name;
reference = reference.getChild('@class').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = ClassElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -879,4 +890,18 @@
void visitWithClause(WithClause node) {
node.mixinTypes.accept(this);
}
+
+ void _createTypeParameterElement(TypeParameter node) {
+ var element = TypeParameterElementImpl.forLinkedNode(null, null, node);
+ node.name.staticElement = element;
+ linkingContext.addTypeParameter(element);
+ }
+
+ void _createTypeParameterElements(TypeParameterList typeParameterList) {
+ if (typeParameterList == null) return;
+
+ for (var typeParameter in typeParameterList.typeParameters) {
+ _createTypeParameterElement(typeParameter);
+ }
+ }
}
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index 13a6dc4..b92d04b 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -231,9 +231,9 @@
var element = TypeBuilder.typeNameElementIndex(type.typeName_name);
var reference = _walker.bundleContext.referenceOfIndex(element);
- if (reference.isTypeParameter) {
- return allowTypeParameters;
- }
+// if (reference.isTypeParameter) {
+// return allowTypeParameters;
+// }
var arguments = type.typeName_typeArguments;
if (arguments == null) {
diff --git a/pkg/analyzer/lib/src/summary2/type_builder.dart b/pkg/analyzer/lib/src/summary2/type_builder.dart
index 3588181..7093935 100644
--- a/pkg/analyzer/lib/src/summary2/type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/type_builder.dart
@@ -9,7 +9,6 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/linking_bundle_context.dart';
@@ -70,21 +69,28 @@
}
}
- DartType _buildFunctionType(
+ FunctionType _buildFunctionType(
+ TypeParameterList typeParameterList,
TypeAnnotation returnTypeNode,
FormalParameterList parameterList,
) {
var returnType = returnTypeNode?.type ?? _dynamicType;
- // TODO(scheglov) type parameters
- var typeParameters = const <TypeParameterElement>[];
+ List<TypeParameterElement> typeParameters;
+ if (typeParameterList != null) {
+ typeParameters = typeParameterList.typeParameters
+ .map<TypeParameterElement>((p) => p.declaredElement)
+ .toList();
+ } else {
+ typeParameters = const <TypeParameterElement>[];
+ }
- var formalParameters = parameterList.parameters.map((p) {
- // TODO(scheglov) other types and kinds
+ var formalParameters = parameterList.parameters.map((parameter) {
return ParameterElementImpl.synthetic(
- (p as SimpleFormalParameter).identifier.name,
- LazyAst.getType(p),
- ParameterKind.REQUIRED,
+ parameter.identifier.name,
+ LazyAst.getType(parameter),
+ // ignore: deprecated_member_use_from_same_package
+ parameter.kind,
);
}).toList();
@@ -96,8 +102,11 @@
}
void _buildGenericFunctionType(GenericFunctionTypeImpl node) {
- // TODO(scheglov) Type parameters?
- node.type = _buildFunctionType(node.returnType, node.parameters);
+ node.type = _buildFunctionType(
+ node.typeParameters,
+ node.returnType,
+ node.parameters,
+ );
}
void _buildTypeName(TypeName node) {
@@ -214,7 +223,11 @@
void _fieldFormalParameter(FieldFormalParameter node) {
var parameterList = node.parameters;
if (parameterList != null) {
- var type = _buildFunctionType(node.type, parameterList);
+ var type = _buildFunctionType(
+ node.typeParameters,
+ node.type,
+ parameterList,
+ );
LazyAst.setType(node, type);
} else {
LazyAst.setType(node, node.type?.type ?? _dynamicType);
@@ -222,7 +235,11 @@
}
void _functionTypedFormalParameter(FunctionTypedFormalParameter node) {
- var type = _buildFunctionType(node.returnType, node.parameters);
+ var type = _buildFunctionType(
+ node.typeParameters,
+ node.returnType,
+ node.parameters,
+ );
LazyAst.setType(node, type);
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 313fe5d..3be71f3 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -308,12 +308,6 @@
@override
@failingTest
- test_const_reference_topLevelFunction_generic() async {
- await super.test_const_reference_topLevelFunction_generic();
- }
-
- @override
- @failingTest
test_const_reference_topLevelVariable_imported() async {
await super.test_const_reference_topLevelVariable_imported();
}
@@ -514,12 +508,6 @@
@override
@failingTest
- test_infer_generic_typedef_simple() async {
- await super.test_infer_generic_typedef_simple();
- }
-
- @override
- @failingTest
test_inference_issue_32394() async {
await super.test_inference_issue_32394();
}
@@ -850,12 +838,6 @@
@override
@failingTest
- test_typedef_generic_asFieldType() async {
- await super.test_typedef_generic_asFieldType();
- }
-
- @override
- @failingTest
test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async {
await super
.test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included();
@@ -945,12 +927,6 @@
@override
@failingTest
- test_unused_type_parameter() async {
- await super.test_unused_type_parameter();
- }
-
- @override
- @failingTest
test_variable_propagatedType_final_dep_inLib() async {
await super.test_variable_propagatedType_final_dep_inLib();
}