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>
This commit is contained in:
Konstantin Shcheglov 2019-04-11 17:22:42 +00:00 committed by commit-bot@chromium.org
parent 2723835b18
commit e104054059
18 changed files with 512 additions and 411 deletions

View file

@ -1060,31 +1060,6 @@ class ClassElementImpl extends AbstractClassElementImpl
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 @@ class TypeParameterElementImpl extends ElementImpl
@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 @@ mixin TypeParameterizedElementMixin
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();
}

View file

@ -8,6 +8,37 @@ import 'package:analyzer/src/dart/element/element.dart';
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 @@ DartType substitute(
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;

View file

@ -8174,6 +8174,12 @@ class LinkedNodeBuilder extends Object
return _variantField_16 ??= 0;
}
@override
int get typeParameter_id {
assert(kind == idl.LinkedNodeKind.typeParameter);
return _variantField_16 ??= 0;
}
@override
int get typeParameterList_rightBracket {
assert(kind == idl.LinkedNodeKind.typeParameterList);
@ -8508,6 +8514,12 @@ class LinkedNodeBuilder extends Object
_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 @@ class LinkedNodeBuilder extends Object
LinkedNodeBuilder typeParameter_bound,
int typeParameter_extendsKeyword,
LinkedNodeBuilder typeParameter_name,
int typeParameter_id,
int codeLength,
int codeOffset,
}) : _kind = idl.LinkedNodeKind.typeParameter,
@ -10657,6 +10670,7 @@ class LinkedNodeBuilder extends Object
_variantField_6 = typeParameter_bound,
_variantField_15 = typeParameter_extendsKeyword,
_variantField_7 = typeParameter_name,
_variantField_16 = typeParameter_id,
_variantField_34 = codeLength,
_variantField_33 = codeOffset;
@ -14399,6 +14413,14 @@ class _LinkedNodeImpl extends Object
return _variantField_16;
}
@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);
@ -16265,6 +16287,7 @@ abstract class _LinkedNodeMixin implements idl.LinkedNode {
_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 @@ abstract class _LinkedNodeMixin implements idl.LinkedNode {
"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 @@ class LinkedNodeTypeBuilder extends Object
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 @@ class LinkedNodeTypeBuilder extends Object
}
@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 @@ class LinkedNodeTypeBuilder extends Object
}
@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 @@ class LinkedNodeTypeBuilder extends Object
_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 @@ class LinkedNodeTypeBuilder extends Object
} 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 @@ class LinkedNodeTypeBuilder extends Object
}
}
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 @@ class LinkedNodeTypeBuilder extends Object
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 @@ class LinkedNodeTypeBuilder extends Object
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 @@ class _LinkedNodeTypeImpl extends Object
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 @@ class _LinkedNodeTypeImpl extends Object
}
@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 @@ class _LinkedNodeTypeImpl extends Object
}
@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 @@ abstract class _LinkedNodeTypeMixin implements idl.LinkedNodeType {
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 @@ abstract class _LinkedNodeTypeMixin implements idl.LinkedNodeType {
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 @@ abstract class _LinkedNodeTypeMixin implements idl.LinkedNodeType {
"interfaceClass": interfaceClass,
"interfaceTypeArguments": interfaceTypeArguments,
"kind": kind,
"typeParameterParameter": typeParameterParameter,
"typeParameterId": typeParameterId,
};
@override
@ -19381,6 +19407,116 @@ abstract class _LinkedNodeTypeFormalParameterMixin
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 {

View file

@ -406,8 +406,6 @@ enum LinkedNodeTypeKind : byte {
function,
genericTypeAlias,
interface,
typeParameter,
@ -1945,8 +1943,7 @@ table LinkedNodeType {
functionReturnType:LinkedNodeType (id: 1);
/// References to [LinkedNodeReferences].
functionTypeParameters:[uint] (id: 2);
functionTypeParameters:[LinkedNodeTypeTypeParameter] (id: 2);
genericTypeAliasReference:uint (id: 7);
@ -1959,8 +1956,7 @@ table LinkedNodeType {
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 @@ table LinkedNodeTypeFormalParameter {
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);

View file

@ -2222,6 +2222,9 @@ abstract class LinkedNode extends base.SummaryClass {
@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 @@ abstract class LinkedNodeType extends base.SummaryClass {
@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 @@ abstract class LinkedNodeType extends base.SummaryClass {
@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 @@ enum LinkedNodeTypeKind {
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)

View file

@ -9,7 +9,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/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 @@ class AstBinaryReader {
_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 @@ class AstBinaryReader {
_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 @@ class AstBinaryReader {
_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 @@ class AstBinaryReader {
_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 @@ class AstBinaryReader {
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 @@ class AstBinaryReader {
_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 @@ class AstBinaryReader {
_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 @@ class AstBinaryReader {
_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 @@ class AstBinaryReader {
_readNodeLazy(data.typeParameter_bound),
);
LazyTypeParameter.setData(node, data);
_unitContext.addTypeParameter(data.typeParameter_id, node);
return node;
}
@ -1588,57 +1588,6 @@ class AstBinaryReader {
}
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);
}
}

View file

@ -8,8 +8,6 @@ import 'package:analyzer/dart/ast/visitor.dart';
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 @@ import 'package:analyzer/src/summary2/tokens_context.dart';
/// 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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
/// in these declarations.
LinkedNodeVariablesDeclarationBuilder _variablesDeclaration;
AstBinaryWriter(this._linkingBundleContext, this._tokensContext);
AstBinaryWriter(this._linkingContext, this._tokensContext);
@override
LinkedNodeBuilder visitAdjacentStrings(AdjacentStrings node) {
@ -94,7 +92,7 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
@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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
@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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
@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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
@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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
}
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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
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 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
}
LinkedNodeTypeBuilder _writeType(DartType type) {
return _linkingBundleContext.writeType(type);
return _linkingContext.writeType(type);
}
}

View file

@ -299,6 +299,7 @@ class SourceLibraryBuilder {
var unitRef = reference.getChild('@unit');
var unitReference = unitRef.getChild(unitContext.uriStr);
var resolver = ReferenceResolver(
linker.linkingBundleContext,
nodesToBuildType,
linker.elementFactory,
element,

View file

@ -45,7 +45,6 @@ class LazyClassDeclaration {
bool _hasImplementsClause = false;
bool _hasMembers = false;
bool _hasMetadata = false;
bool _hasTypeParameters = false;
bool _hasWithClause = false;
LazyClassDeclaration(this.data);
@ -123,19 +122,6 @@ class LazyClassDeclaration {
}
}
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 @@ class LazyClassTypeAlias {
bool _hasImplementsClause = false;
bool _hasMetadata = false;
bool _hasSuperclass = false;
bool _hasTypeParameters = false;
bool _hasWithClause = false;
LazyClassTypeAlias(this.data);
@ -228,19 +213,6 @@ class LazyClassTypeAlias {
}
}
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 @@ class LazyFunctionDeclaration {
AstBinaryReader reader,
FunctionDeclaration node,
) {
readFunctionExpression(reader, node);
if (reader.isLazy) {
var lazy = get(node);
if (!lazy._hasReturnType) {
@ -698,7 +671,6 @@ class LazyFunctionExpression {
bool _hasBody = false;
bool _hasFormalParameters = false;
bool _hasTypeParameters = false;
LazyFunctionExpression(this.data);
@ -732,19 +704,6 @@ class LazyFunctionExpression {
}
}
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 @@ class LazyFunctionTypeAlias {
bool _hasFormalParameters = false;
bool _hasMetadata = false;
bool _hasReturnType = false;
bool _hasTypeParameters = false;
LazyFunctionTypeAlias(this.data);
@ -823,19 +781,6 @@ class LazyFunctionTypeAlias {
}
}
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 @@ class LazyGenericTypeAlias {
bool _hasDocumentationComment = false;
bool _hasFunction = false;
bool _hasTypeParameters = false;
LazyGenericTypeAlias(this.data);
@ -929,19 +873,6 @@ class LazyGenericTypeAlias {
}
}
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 @@ class LazyMethodDeclaration {
bool _hasFormalParameters = false;
bool _hasMetadata = false;
bool _hasReturnType = false;
bool _hasTypeParameters = false;
LazyMethodDeclaration(this.data);
@ -1034,19 +964,6 @@ class LazyMethodDeclaration {
}
}
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 @@ class LazyMixinDeclaration {
bool _hasOnClause = false;
bool _hasImplementsClause = false;
bool _hasMembers = false;
bool _hasTypeParameters = false;
LazyMixinDeclaration(this.data);
@ -1123,19 +1039,6 @@ class LazyMixinDeclaration {
}
}
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));
}

View file

@ -82,52 +82,6 @@ class LinkedBundleContext {
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 @@ class LinkedBundleContext {
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 {

View file

@ -152,11 +152,6 @@ class _ElementRequest {
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 @@ class _ElementRequest {
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.

View file

@ -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 @@ class LinkedUnitContext {
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 @@ class LinkedUnitContext {
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 @@ class LinkedUnitContext {
}
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 @@ class LinkedUnitContext {
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 @@ class LinkedUnitContext {
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 @@ class LinkedUnitContext {
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 @@ class LinkedUnitContext {
}
}
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);

View file

@ -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 @@ class LinkingBundleContext {
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 @@ class LinkingBundleContext {
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 @@ class LinkingBundleContext {
}
}
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 @@ class LinkingBundleContext {
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;
}
}

View file

@ -71,8 +71,6 @@ class Reference {
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.

View file

@ -10,6 +10,7 @@ import 'package:analyzer/src/dart/element/type.dart';
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 @@ import 'package:analyzer/src/summary2/type_builder.dart';
/// 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 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
Scope scope;
ReferenceResolver(
this.linkingContext,
this.nodesToBuildType,
this.elementFactory,
this._libraryElement,
@ -536,6 +539,7 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
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 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
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 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
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 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
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 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
var name = '${outerReference.numOfChildren}';
reference = reference.getChild(name);
_createTypeParameterElements(node.typeParameters);
var element = GenericFunctionTypeElementImpl.forLinkedNode(
outerReference.element,
reference,
@ -744,6 +752,7 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
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 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
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 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
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 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
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);
}
}
}

View file

@ -231,9 +231,9 @@ class SimplyBoundedNode extends graph.Node<SimplyBoundedNode> {
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) {

View file

@ -9,7 +9,6 @@ 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/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 @@ class TypeBuilder {
}
}
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 @@ class TypeBuilder {
}
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 @@ class TypeBuilder {
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 @@ class TypeBuilder {
}
void _functionTypedFormalParameter(FunctionTypedFormalParameter node) {
var type = _buildFunctionType(node.returnType, node.parameters);
var type = _buildFunctionType(
node.typeParameters,
node.returnType,
node.parameters,
);
LazyAst.setType(node, type);
}

View file

@ -306,12 +306,6 @@ T max<T extends num>(T a, T b) => null;
.test_const_parameterDefaultValue_initializingFormal_functionTyped();
}
@override
@failingTest
test_const_reference_topLevelFunction_generic() async {
await super.test_const_reference_topLevelFunction_generic();
}
@override
@failingTest
test_const_reference_topLevelVariable_imported() async {
@ -512,12 +506,6 @@ T max<T extends num>(T a, T b) => null;
await super.test_infer_generic_typedef_complex();
}
@override
@failingTest
test_infer_generic_typedef_simple() async {
await super.test_infer_generic_typedef_simple();
}
@override
@failingTest
test_inference_issue_32394() async {
@ -848,12 +836,6 @@ T max<T extends num>(T a, T b) => null;
await super.test_typedef_generic();
}
@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 {
@ -943,12 +925,6 @@ T max<T extends num>(T a, T b) => null;
await super.test_unresolved_import();
}
@override
@failingTest
test_unused_type_parameter() async {
await super.test_unused_type_parameter();
}
@override
@failingTest
test_variable_propagatedType_final_dep_inLib() async {