Build new elements for GenericFunctionType in DeclarationResolver.
It seems that we don't really need to have the same elements for them
for resynthesizing element model and resolved AST.
R=brianwilkerson@google.com
Change-Id: I05efdf90671f596f2f8b85a3808eb2c4c87ea8c1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105003
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index e336eb9..d8abec8 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -32,13 +32,6 @@
/// element model.
ElementWalker _walker;
- /// Is `true` if the current [ClassDeclaration] has a const constructor.
- bool _hasConstConstructor = false;
-
- /// The number of [GenericFunctionType] nodes that we encountered so far.
- /// We use it to request the corresponding resolved node.
- int _nextGenericFunctionTypeId = 0;
-
DeclarationResolver();
/// Resolve the declarations within the given compilation [unit] to the
@@ -86,14 +79,6 @@
@override
void visitClassDeclaration(ClassDeclaration node) {
- _hasConstConstructor = false;
- for (var member in node.members) {
- if (member is ConstructorDeclaration && member.constKeyword != null) {
- _hasConstConstructor = true;
- break;
- }
- }
-
ClassElement element = _match(node.name, _walker.getClass());
_walk(new ElementWalker.forClass(element), () {
super.visitClassDeclaration(node);
@@ -203,10 +188,6 @@
super.visitFieldDeclaration(node);
FieldElement firstFieldElement = node.fields.variables[0].declaredElement;
resolveMetadata(node, node.metadata, firstFieldElement);
- if (node.fields.isConst ||
- !node.isStatic && node.fields.isFinal && _hasConstConstructor) {
- _consumeGenericFunctionTypeIds(node.fields);
- }
}
@override
@@ -289,19 +270,20 @@
@override
void visitGenericFunctionType(GenericFunctionType node) {
+ if (AnalysisDriver.useSummary2 && _enclosingUnit.linkedContext != null) {
+ var builder = new LocalElementBuilder(ElementHolder(), _enclosingUnit);
+ node.accept(builder);
+
+ var nodeImpl = node as GenericFunctionTypeImpl;
+ _enclosingUnit.encloseElement(
+ nodeImpl.declaredElement as GenericFunctionTypeElementImpl,
+ );
+ return;
+ }
if (_walker.elementBuilder != null) {
_walker.elementBuilder.visitGenericFunctionType(node);
} else {
- Element element;
- if (AnalysisDriver.useSummary2 && _enclosingUnit.linkedContext != null) {
- var id = _nextGenericFunctionTypeId++;
- var context = _enclosingUnit.linkedContext;
- var linkedNode = context.getGenericFunctionType(id);
- element = linkedNode.declaredElement;
- (node as GenericFunctionTypeImpl).declaredElement = element;
- } else {
- element = node.type?.element;
- }
+ var element = node.type?.element;
if (element is GenericFunctionTypeElement) {
_setGenericFunctionType(node.returnType, element.returnType);
_walk(new ElementWalker.forGenericFunctionType(element), () {
@@ -454,9 +436,6 @@
super.visitTopLevelVariableDeclaration(node);
VariableElement firstElement = node.variables.variables[0].declaredElement;
resolveMetadata(node, node.metadata, firstElement);
- if (node.variables.isConst) {
- _consumeGenericFunctionTypeIds(node.variables);
- }
}
@override
@@ -508,14 +487,6 @@
}
}
- /// See [_ConsumeGenericFunctionTypeIdsVisitor].
- void _consumeGenericFunctionTypeIds(VariableDeclarationList node) {
- if (AnalysisDriver.useSummary2) {
- var visitor = _ConsumeGenericFunctionTypeIdsVisitor(this);
- node.variables.accept(visitor);
- }
- }
-
/// Updates [identifier] to point to [element], after ensuring that the
/// element has the expected name.
///
@@ -991,24 +962,6 @@
static bool _isNotSynthetic(Element e) => !e.isSynthetic;
}
-/// For consistency we set identifiers for [GenericFunctionType]s in constant
-/// variable initializers, and instance final fields of classes with constant
-/// constructors. However [DeclarationResolver] does not visit these
-/// initializers, in builds separate local elements. We still need to consume
-/// them to ensure that identifiers expected by the element model, and by
-/// [DeclarationResolver] match.
-class _ConsumeGenericFunctionTypeIdsVisitor extends RecursiveAstVisitor<void> {
- final DeclarationResolver resolver;
-
- _ConsumeGenericFunctionTypeIdsVisitor(this.resolver);
-
- @override
- void visitGenericFunctionType(GenericFunctionType node) {
- resolver._nextGenericFunctionTypeId++;
- super.visitGenericFunctionType(node);
- }
-}
-
class _ElementMismatchException extends AnalysisException {
/// Creates an exception to refer to the given [compilationUnit], [element],
/// and [cause].
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index d9bbbf1..043be91 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -17212,7 +17212,6 @@
class LinkedNodeUnitBuilder extends Object
with _LinkedNodeUnitMixin
implements idl.LinkedNodeUnit {
- List<LinkedNodeBuilder> _genericFunctionTypes;
bool _isNNBD;
bool _isSynthetic;
List<int> _lineStarts;
@@ -17221,20 +17220,6 @@
String _uriStr;
@override
- List<LinkedNodeBuilder> get genericFunctionTypes =>
- _genericFunctionTypes ??= <LinkedNodeBuilder>[];
-
- /// All generic function types in the unit - in generic type aliases, or used
- /// directly as type annotations.
- ///
- /// They are requested in two cases: when we are reading a node that contains
- /// them (e.g. a return type of a method), or when we run over unresolved
- /// AST in declaration resolver.
- set genericFunctionTypes(List<LinkedNodeBuilder> value) {
- this._genericFunctionTypes = value;
- }
-
- @override
bool get isNNBD => _isNNBD ??= false;
set isNNBD(bool value) {
@@ -17279,15 +17264,13 @@
}
LinkedNodeUnitBuilder(
- {List<LinkedNodeBuilder> genericFunctionTypes,
- bool isNNBD,
+ {bool isNNBD,
bool isSynthetic,
List<int> lineStarts,
LinkedNodeBuilder node,
UnlinkedTokensBuilder tokens,
String uriStr})
- : _genericFunctionTypes = genericFunctionTypes,
- _isNNBD = isNNBD,
+ : _isNNBD = isNNBD,
_isSynthetic = isSynthetic,
_lineStarts = lineStarts,
_node = node,
@@ -17296,7 +17279,6 @@
/// Flush [informative] data recursively.
void flushInformative() {
- _genericFunctionTypes?.forEach((b) => b.flushInformative());
_lineStarts = null;
_node?.flushInformative();
_tokens?.flushInformative();
@@ -17310,27 +17292,14 @@
signature.addBool(this._node != null);
this._node?.collectApiSignature(signature);
signature.addBool(this._isSynthetic == true);
- if (this._genericFunctionTypes == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._genericFunctionTypes.length);
- for (var x in this._genericFunctionTypes) {
- x?.collectApiSignature(signature);
- }
- }
signature.addBool(this._isNNBD == true);
}
fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_genericFunctionTypes;
fb.Offset offset_lineStarts;
fb.Offset offset_node;
fb.Offset offset_tokens;
fb.Offset offset_uriStr;
- if (!(_genericFunctionTypes == null || _genericFunctionTypes.isEmpty)) {
- offset_genericFunctionTypes = fbBuilder.writeList(
- _genericFunctionTypes.map((b) => b.finish(fbBuilder)).toList());
- }
if (!(_lineStarts == null || _lineStarts.isEmpty)) {
offset_lineStarts = fbBuilder.writeListUint32(_lineStarts);
}
@@ -17344,11 +17313,8 @@
offset_uriStr = fbBuilder.writeString(_uriStr);
}
fbBuilder.startTable();
- if (offset_genericFunctionTypes != null) {
- fbBuilder.addOffset(5, offset_genericFunctionTypes);
- }
if (_isNNBD == true) {
- fbBuilder.addBool(6, true);
+ fbBuilder.addBool(5, true);
}
if (_isSynthetic == true) {
fbBuilder.addBool(3, true);
@@ -17385,7 +17351,6 @@
_LinkedNodeUnitImpl(this._bc, this._bcOffset);
- List<idl.LinkedNode> _genericFunctionTypes;
bool _isNNBD;
bool _isSynthetic;
List<int> _lineStarts;
@@ -17394,16 +17359,8 @@
String _uriStr;
@override
- List<idl.LinkedNode> get genericFunctionTypes {
- _genericFunctionTypes ??=
- const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
- return _genericFunctionTypes;
- }
-
- @override
bool get isNNBD {
- _isNNBD ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false);
+ _isNNBD ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false);
return _isNNBD;
}
@@ -17444,9 +17401,6 @@
@override
Map<String, Object> toJson() {
Map<String, Object> _result = <String, Object>{};
- if (genericFunctionTypes.isNotEmpty)
- _result["genericFunctionTypes"] =
- genericFunctionTypes.map((_value) => _value.toJson()).toList();
if (isNNBD != false) _result["isNNBD"] = isNNBD;
if (isSynthetic != false) _result["isSynthetic"] = isSynthetic;
if (lineStarts.isNotEmpty) _result["lineStarts"] = lineStarts;
@@ -17458,7 +17412,6 @@
@override
Map<String, Object> toMap() => {
- "genericFunctionTypes": genericFunctionTypes,
"isNNBD": isNNBD,
"isSynthetic": isSynthetic,
"lineStarts": lineStarts,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 69d782b..4ff5313 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -2036,15 +2036,7 @@
/// Information about a single library in a [LinkedNodeLibrary].
table LinkedNodeUnit {
- /// All generic function types in the unit - in generic type aliases, or used
- /// directly as type annotations.
- ///
- /// They are requested in two cases: when we are reading a node that contains
- /// them (e.g. a return type of a method), or when we run over unresolved
- /// AST in declaration resolver.
- genericFunctionTypes:[LinkedNode] (id: 5);
-
- isNNBD:bool (id: 6);
+ isNNBD:bool (id: 5);
isSynthetic:bool (id: 3);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 5ad8160..1dc7354 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -2036,16 +2036,7 @@
/// Information about a single library in a [LinkedNodeLibrary].
abstract class LinkedNodeUnit extends base.SummaryClass {
- /// All generic function types in the unit - in generic type aliases, or used
- /// directly as type annotations.
- ///
- /// They are requested in two cases: when we are reading a node that contains
- /// them (e.g. a return type of a method), or when we run over unresolved
- /// AST in declaration resolver.
@Id(5)
- List<LinkedNode> get genericFunctionTypes;
-
- @Id(6)
bool get isNNBD;
@Id(3)
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 723c8a3..864b976 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -52,67 +52,6 @@
InterfaceType get _stringType => _unitContext.typeProvider.stringType;
- /// This method is invoked by [LinkedUnitContext] to finish reading.
- void readGenericFunctionTypeFinish(
- LinkedNode data,
- GenericFunctionType node,
- ) {
- var typeParameterListData = data.genericFunctionType_typeParameters;
- if (typeParameterListData != null) {
- var dataList = typeParameterListData.typeParameterList_typeParameters;
- var typeParameters = node.typeParameters.typeParameters;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- var node = typeParameters[i];
- node.bound = _readNode(data.typeParameter_bound);
- }
- }
- node.returnType = readNode(data.genericFunctionType_returnType);
- node.parameters = _readNode(data.genericFunctionType_formalParameters);
- }
-
- /// This method is invoked by [LinkedUnitContext] to perform shallow reading.
- ///
- /// It reads [TypeParameter] names, and creates [GenericFunctionType] node,
- /// so that [LinkedUnitContext] can create elements for these nodes.
- ///
- /// But we cannot read the return type and formal parameters yet, until the
- /// corresponding elements are created.
- GenericFunctionType readGenericFunctionTypeShallow(LinkedNode data) {
- TypeParameterList typeParameterList;
- var typeParameterListData = data.genericFunctionType_typeParameters;
- if (typeParameterListData != null) {
- var dataList = typeParameterListData.typeParameterList_typeParameters;
- var typeParameters = List<TypeParameter>(dataList.length);
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- typeParameters[i] = astFactory.typeParameter(
- _readNode(data.annotatedNode_comment),
- _readNodeList(data.annotatedNode_metadata),
- _declaredIdentifier(data),
- data.typeParameter_bound != null ? _Tokens.EXTENDS : null,
- null,
- );
- }
- typeParameterList = astFactory.typeParameterList(
- _Tokens.LT,
- typeParameters,
- _Tokens.GT,
- );
- }
-
- GenericFunctionTypeImpl node = astFactory.genericFunctionType(
- null,
- _Tokens.FUNCTION,
- typeParameterList,
- null,
- question:
- AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
- );
- node.type = _readType(data.genericFunctionType_type);
- return node;
- }
-
AstNode readNode(LinkedNode data) {
timerAstBinaryReader.start();
try {
@@ -846,7 +785,58 @@
GenericFunctionType _read_genericFunctionType(LinkedNode data) {
var id = data.genericFunctionType_id;
- return _unitContext.getGenericFunctionType(id);
+
+ // Read type parameters, without bounds, to avoid forward references.
+ TypeParameterList typeParameterList;
+ var typeParameterListData = data.genericFunctionType_typeParameters;
+ if (typeParameterListData != null) {
+ var dataList = typeParameterListData.typeParameterList_typeParameters;
+ var typeParameters = List<TypeParameter>(dataList.length);
+ for (var i = 0; i < dataList.length; ++i) {
+ var data = dataList[i];
+ typeParameters[i] = astFactory.typeParameter(
+ _readNode(data.annotatedNode_comment),
+ _readNodeList(data.annotatedNode_metadata),
+ _declaredIdentifier(data),
+ data.typeParameter_bound != null ? _Tokens.EXTENDS : null,
+ null,
+ );
+ }
+ typeParameterList = astFactory.typeParameterList(
+ _Tokens.LT,
+ typeParameters,
+ _Tokens.GT,
+ );
+ }
+
+ GenericFunctionTypeImpl node = astFactory.genericFunctionType(
+ null,
+ _Tokens.FUNCTION,
+ typeParameterList,
+ null,
+ question:
+ AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
+ );
+ node.type = _readType(data.genericFunctionType_type);
+
+ // Create the node element, so now type parameter elements are available.
+ LazyAst.setGenericFunctionTypeId(node, id);
+ _unitContext.createGenericFunctionTypeElement(id, node);
+
+ // Finish reading.
+ if (typeParameterListData != null) {
+ var dataList = typeParameterListData.typeParameterList_typeParameters;
+ var typeParameters = typeParameterList.typeParameters;
+ for (var i = 0; i < dataList.length; ++i) {
+ var data = dataList[i];
+ var node = typeParameters[i];
+ node.bound = _readNode(data.typeParameter_bound);
+ }
+ }
+ node.returnType = readNode(data.genericFunctionType_returnType);
+ node.parameters = _readNode(data.genericFunctionType_formalParameters);
+
+ return node;
}
GenericTypeAlias _read_genericTypeAlias(LinkedNode data) {
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 8588d04..ea3ab89 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -28,9 +28,6 @@
class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
final LinkingBundleContext _linkingContext;
- /// The list stored [GenericFunctionType]s, as visited in depth-first order.
- final List<LinkedNodeBuilder> genericFunctionTypes = [];
-
/// Is `true` if the current [ClassDeclaration] has a const constructor,
/// so initializers of final fields should be written.
bool _hasConstConstructor = false;
@@ -682,10 +679,9 @@
LinkedNodeBuilder visitGenericFunctionType(GenericFunctionType node) {
var id = LazyAst.getGenericFunctionTypeId(node);
assert(id != null);
- assert(genericFunctionTypes.length == id);
- genericFunctionTypes.add(null);
var builder = LinkedNodeBuilder.genericFunctionType(
+ genericFunctionType_id: id,
genericFunctionType_returnType: node.returnType?.accept(this),
genericFunctionType_typeParameters: node.typeParameters?.accept(this),
genericFunctionType_formalParameters: node.parameters.accept(this),
@@ -696,12 +692,7 @@
);
_writeActualReturnType(builder, node);
- builder.genericFunctionType_id = id;
- genericFunctionTypes[id] = builder;
-
- return LinkedNodeBuilder.genericFunctionType(
- genericFunctionType_id: id,
- );
+ return builder;
}
@override
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 7d9f6f5..784b60e 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -192,7 +192,6 @@
lineStarts: unit.lineInfo.lineStarts,
node: unitLinkedNode,
isNNBD: unit.featureSet.isEnabled(Feature.non_nullable),
- genericFunctionTypes: writer.genericFunctionTypes,
),
);
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 9ce9558..3e8d48e 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -5,7 +5,6 @@
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
@@ -148,14 +147,6 @@
return _function(enclosing, reference);
}
- if (parentName == '@genericFunctionType') {
- CompilationUnitElementImpl enclosing = elementOfReference(parent2);
- var context = enclosing.linkedContext;
- var id = int.parse(reference.name);
- GenericFunctionTypeImpl node = context.getGenericFunctionType(id);
- return node.declaredElement as GenericFunctionTypeElementImpl;
- }
-
if (parentName == '@getter' || parentName == '@setter') {
var enclosing = elementOfReference(parent2);
return _accessor(enclosing, reference);
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 31e301b..9f7385e 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -28,10 +28,6 @@
final bool isSynthetic;
final LinkedNodeUnit data;
- /// This list is filled lazily with [GenericFunctionType] nodes as they
- /// are requested by [getGenericFunctionType].
- List<GenericFunctionType> _genericFunctionTypeNodeList;
-
AstBinaryReader _astReader;
CompilationUnit _unit;
@@ -57,12 +53,6 @@
_astReader = AstBinaryReader(this);
_astReader.isLazy = unit == null;
- if (data != null) {
- _genericFunctionTypeNodeList = List<GenericFunctionType>(
- data.genericFunctionTypes.length,
- );
- }
-
_unit = unit;
_hasDirectivesRead = _unit != null;
}
@@ -114,6 +104,17 @@
return _unit;
}
+ void createGenericFunctionTypeElement(int id, GenericFunctionTypeImpl node) {
+ var containerRef = this.reference.getChild('@genericFunctionType');
+ var reference = containerRef.getChild('$id');
+ var element = GenericFunctionTypeElementImpl.forLinkedNode(
+ this.reference.element,
+ reference,
+ node,
+ );
+ node.declaredElement = element;
+ }
+
/// Return the [LibraryElement] referenced in the [node].
LibraryElement directiveLibrary(UriBasedDirective node) {
var uriStr = LazyDirective.getSelectedUri(node);
@@ -337,28 +338,6 @@
}
}
- GenericFunctionTypeImpl getGenericFunctionType(int id) {
- GenericFunctionTypeImpl node = _genericFunctionTypeNodeList[id];
- if (node == null) {
- var data = this.data.genericFunctionTypes[id];
- node = _astReader.readGenericFunctionTypeShallow(data);
- LazyAst.setGenericFunctionTypeId(node, id);
- _genericFunctionTypeNodeList[id] = node;
-
- var containerRef = this.reference.getChild('@genericFunctionType');
- var reference = containerRef.getChild('$id');
- var element = GenericFunctionTypeElementImpl.forLinkedNode(
- this.reference.element,
- reference,
- node,
- );
- node.declaredElement = element;
-
- _astReader.readGenericFunctionTypeFinish(data, node);
- }
- return node;
- }
-
Reference getGenericFunctionTypeReference(GenericFunctionType node) {
var containerRef = reference.getChild('@genericFunctionType');
var id = LazyAst.getGenericFunctionTypeId(node);
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
index f8ff22c..bf87a5f 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -498,4 +498,13 @@
}
throw StateError('Not found: $name');
}
+
+ TopLevelVariableElement topVar(String name) {
+ for (var variable in definingUnit.topLevelVariables) {
+ if (variable.name == name) {
+ return variable;
+ }
+ }
+ throw StateError('Not found: $name');
+ }
}