3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
5
import 'package:analyzer/dart/ast/standard_ast_factory.dart' ;
6
+ import 'package:analyzer/dart/element/element.dart' ;
6
7
import 'package:analyzer/dart/element/type.dart' ;
7
8
import 'package:analyzer/src/dart/element/element.dart' ;
8
9
import 'package:analyzer/src/dart/element/type.dart' ;
9
10
import 'package:analyzer/src/dart/resolver/scope.dart' ;
10
11
import 'package:analyzer/src/summary/format.dart' ;
11
12
import 'package:analyzer/src/summary/idl.dart' ;
12
13
import 'package:analyzer/src/summary2/ast_resolver.dart' ;
13
- import 'package:analyzer/src/summary2/builder/source_library_builder.dart' ;
14
14
import 'package:analyzer/src/summary2/link.dart' ;
15
+ import 'package:analyzer/src/summary2/linked_unit_context.dart' ;
15
16
import 'package:analyzer/src/summary2/reference.dart' ;
16
17
17
18
DartType _dynamicIfNull (DartType type) {
@@ -21,116 +22,121 @@ DartType _dynamicIfNull(DartType type) {
21
22
return type;
22
23
}
23
24
25
+ /// TODO(scheglov) This is not a valid implementation of top-level inference.
26
+ /// See https://bit.ly/2HYfAKg
27
+ ///
28
+ /// In general inference of constructor field formal parameters should be
29
+ /// interleaved with inference of fields. There are resynthesis tests that
30
+ /// fail because of this limitation.
24
31
class TopLevelInference {
25
32
final Linker linker;
26
- final Reference libraryRef;
27
- final UnitBuilder unit;
33
+ LibraryElementImpl _libraryElement;
34
+
35
+ Scope _libraryScope;
36
+ Scope _nameScope;
37
+
38
+ LinkedUnitContext _linkedContext;
28
39
CompilationUnitElementImpl unitElement;
29
40
30
- TopLevelInference (this .linker, this .libraryRef, this .unit ) {
31
- unitElement = linker.elementFactory.elementOfReference (
32
- libraryRef. getChild ( '@unit' ). getChild ( '${ unit . uri }' ),
33
- ) ;
41
+ TopLevelInference (this .linker, Reference libraryRef ) {
42
+ _libraryElement = linker.elementFactory.elementOfReference (libraryRef);
43
+ _libraryScope = LibraryScope (_libraryElement);
44
+ _nameScope = _libraryScope ;
34
45
}
35
46
36
47
void infer () {
48
+ _setOmittedReturnTypes ();
37
49
_inferFieldsTemporary ();
38
50
_inferConstructorFieldFormals ();
39
51
}
40
52
41
53
void _inferConstructorFieldFormals () {
42
- _visitClassList ((unitDeclaration) {
43
- var members = unitDeclaration.classOrMixinDeclaration_members;
44
-
45
- var fields = < String , LinkedNodeType > {};
46
- _visitClassFields (unitDeclaration, (field) {
47
- var name = unit.context.getVariableName (field);
48
- var type = field.variableDeclaration_type2;
49
- if (type == null ) {
50
- throw StateError ('Field $name should have a type.' );
54
+ for (CompilationUnitElementImpl unit in _libraryElement.units) {
55
+ this .unitElement = unit;
56
+ _linkedContext = unit.linkedContext;
57
+
58
+ for (var class_ in unit.types) {
59
+ var fields = < String , LinkedNodeType > {};
60
+ for (FieldElementImpl field in class_.fields) {
61
+ if (field.isSynthetic) continue ;
62
+
63
+ var name = field.name;
64
+ var type = field.linkedNode.variableDeclaration_type2;
65
+ if (type == null ) {
66
+ throw StateError ('Field $name should have a type.' );
67
+ }
68
+ fields[name] ?? = type;
51
69
}
52
- fields[name] ?? = type;
53
- });
54
-
55
- for (var member in members) {
56
- if (member.kind == LinkedNodeKind .constructorDeclaration) {
57
- for (var parameter in member.constructorDeclaration_parameters
58
- .formalParameterList_parameters) {
59
- if (parameter.kind == LinkedNodeKind .defaultFormalParameter) {
60
- parameter = parameter.defaultFormalParameter_parameter;
61
- }
62
- if (parameter.kind == LinkedNodeKind .fieldFormalParameter &&
63
- parameter.fieldFormalParameter_type2 == null ) {
64
- var name = unit.context.getSimpleName (
65
- parameter.normalFormalParameter_identifier,
66
- );
67
- var type = fields[name];
68
- if (type == null ) {
69
- type = LinkedNodeTypeBuilder (
70
- kind: LinkedNodeTypeKind .dynamic_,
71
- );
70
+
71
+ for (ConstructorElementImpl constructor in class_.constructors) {
72
+ for (ParameterElementImpl parameter in constructor.parameters) {
73
+ if (parameter is FieldFormalParameterElement ) {
74
+ LinkedNodeBuilder parameterNode = parameter.linkedNode;
75
+ if (parameterNode.kind == LinkedNodeKind .defaultFormalParameter) {
76
+ parameterNode = parameterNode.defaultFormalParameter_parameter;
77
+ }
78
+
79
+ if (parameterNode.fieldFormalParameter_type2 == null ) {
80
+ var name = parameter.name;
81
+ var type = fields[name];
82
+ if (type == null ) {
83
+ type = LinkedNodeTypeBuilder (
84
+ kind: LinkedNodeTypeKind .dynamic_,
85
+ );
86
+ }
87
+ parameterNode.fieldFormalParameter_type2 = type;
72
88
}
73
- parameter.fieldFormalParameter_type2 = type;
74
89
}
75
90
}
76
91
}
77
92
}
78
- });
93
+ }
79
94
}
80
95
81
96
void _inferFieldsTemporary () {
82
- var unitDeclarations = unit.node.compilationUnit_declarations;
83
- for (LinkedNodeBuilder unitDeclaration in unitDeclarations) {
84
- if (unitDeclaration.kind == LinkedNodeKind .classDeclaration ||
85
- unitDeclaration.kind == LinkedNodeKind .mixinDeclaration) {
86
- _visitClassFields (unitDeclaration, (field) {
87
- // var name = unit.context.getVariableName(field);
88
- // TODO(scheglov) Use inheritance
89
- // TODO(scheglov) infer in the correct order
90
- if (field.variableDeclaration_type2 == null ) {
91
- _inferVariableTypeFromInitializerTemporary (field);
92
- }
93
- });
94
-
95
- var members = unitDeclaration.classOrMixinDeclaration_members;
96
- for (var member in members) {
97
- if (member.kind == LinkedNodeKind .methodDeclaration) {
98
- // TODO(scheglov) Use inheritance
99
- if (member.methodDeclaration_returnType2 == null ) {
100
- if (unit.context.isSetter (member)) {
101
- member.methodDeclaration_returnType2 = LinkedNodeTypeBuilder (
102
- kind: LinkedNodeTypeKind .void_,
103
- );
104
- } else {
105
- member.methodDeclaration_returnType2 = LinkedNodeTypeBuilder (
106
- kind: LinkedNodeTypeKind .dynamic_,
107
- );
108
- }
109
- }
110
- }
111
- }
112
- } else if (unitDeclaration.kind == LinkedNodeKind .functionDeclaration) {
113
- if (unit.context.isSetter (unitDeclaration)) {
114
- unitDeclaration.functionDeclaration_returnType2 =
115
- LinkedNodeTypeBuilder (
116
- kind: LinkedNodeTypeKind .void_,
117
- );
118
- }
119
- } else if (unitDeclaration.kind ==
120
- LinkedNodeKind .topLevelVariableDeclaration) {
121
- var variableList =
122
- unitDeclaration.topLevelVariableDeclaration_variableList;
123
- for (var variable in variableList.variableDeclarationList_variables) {
124
- // TODO(scheglov) infer in the correct order
125
- if (variable.variableDeclaration_type2 == null ||
126
- unit.context.isConst (variable)) {
127
- _inferVariableTypeFromInitializerTemporary (variable);
128
- }
97
+ for (CompilationUnitElementImpl unit in _libraryElement.units) {
98
+ this .unitElement = unit;
99
+ _linkedContext = unit.linkedContext;
100
+
101
+ for (var class_ in unit.types) {
102
+ _inferFieldsTemporaryClass (class_);
103
+ }
104
+
105
+ for (var mixin_ in unit.mixins) {
106
+ _inferFieldsTemporaryClass (mixin_);
107
+ }
108
+
109
+ for (TopLevelVariableElementImpl variable in unit.topLevelVariables) {
110
+ if (variable.isSynthetic) continue ;
111
+ LinkedNodeBuilder variableNode = variable.linkedNode;
112
+ if (variableNode.variableDeclaration_type2 == null ||
113
+ _linkedContext.isConst (variableNode)) {
114
+ _inferVariableTypeFromInitializerTemporary (variableNode);
129
115
}
130
116
}
131
117
}
132
118
}
133
119
120
+ void _inferFieldsTemporaryClass (ClassElement class_) {
121
+ var prevScope = _nameScope;
122
+
123
+ _nameScope = TypeParameterScope (_nameScope, class_);
124
+ _nameScope = ClassScope (_nameScope, class_);
125
+
126
+ for (FieldElementImpl field in class_.fields) {
127
+ if (field.isSynthetic) continue ;
128
+ var fieldNode = field.linkedNode;
129
+
130
+ // TODO(scheglov) Use inheritance
131
+ // TODO(scheglov) infer in the correct order
132
+ if (fieldNode.variableDeclaration_type2 == null ) {
133
+ _inferVariableTypeFromInitializerTemporary (fieldNode);
134
+ }
135
+ }
136
+
137
+ _nameScope = prevScope;
138
+ }
139
+
134
140
void _inferVariableTypeFromInitializerTemporary (LinkedNodeBuilder node) {
135
141
var unresolvedNode = node.variableDeclaration_initializer;
136
142
@@ -141,15 +147,11 @@ class TopLevelInference {
141
147
return ;
142
148
}
143
149
144
- var expression = unit.context .readInitializer (unitElement, node);
150
+ var expression = _linkedContext .readInitializer (unitElement, node);
145
151
astFactory.expressionFunctionBody (null , null , expression, null );
146
152
147
- // TODO(scheglov) can be shared for the whole library
148
- var libraryElement = linker.elementFactory.elementOfReference (libraryRef);
149
- var libraryScope = LibraryScope (libraryElement);
150
- var astResolver = AstResolver (linker, libraryElement, libraryScope);
151
-
152
- var resolvedNode = astResolver.resolve (unit.context, expression);
153
+ var astResolver = AstResolver (linker, _libraryElement, _nameScope);
154
+ var resolvedNode = astResolver.resolve (_linkedContext, expression);
153
155
node.variableDeclaration_initializer = resolvedNode;
154
156
155
157
if (node.variableDeclaration_type2 == null ) {
@@ -163,26 +165,66 @@ class TopLevelInference {
163
165
}
164
166
}
165
167
166
- void _visitClassFields (
167
- LinkedNode class_, void Function (LinkedNodeBuilder ) f) {
168
- var members = class_.classOrMixinDeclaration_members;
168
+ void _setOmittedReturnTypes () {
169
+ for (CompilationUnitElementImpl unit in _libraryElement.units) {
170
+ this .unitElement = unit;
171
+ _linkedContext = unit.linkedContext;
172
+
173
+ for (var class_ in unit.types) {
174
+ _setOmittedReturnTypesClass (class_);
175
+ }
176
+
177
+ for (var mixin_ in unit.mixins) {
178
+ _setOmittedReturnTypesClass (mixin_);
179
+ }
180
+
181
+ for (FunctionElementImpl function in unit.functions) {
182
+ LinkedNodeBuilder functionNode = function.linkedNode;
183
+ if (functionNode.functionDeclaration_returnType == null ) {
184
+ functionNode.functionDeclaration_returnType2 = LinkedNodeTypeBuilder (
185
+ kind: LinkedNodeTypeKind .dynamic_,
186
+ );
187
+ }
188
+ }
169
189
170
- for (var member in members) {
171
- if (member.kind == LinkedNodeKind .fieldDeclaration) {
172
- var variableList = member.fieldDeclaration_fields;
173
- for (var field in variableList.variableDeclarationList_variables) {
174
- f (field);
190
+ for (PropertyAccessorElementImpl accessor in unit.accessors) {
191
+ if (accessor.isSynthetic) continue ;
192
+ if (accessor.isSetter) {
193
+ LinkedNodeBuilder node = accessor.linkedNode;
194
+ if (node.functionDeclaration_returnType == null ) {
195
+ node.functionDeclaration_returnType2 = LinkedNodeTypeBuilder (
196
+ kind: LinkedNodeTypeKind .void_,
197
+ );
198
+ }
175
199
}
176
200
}
177
201
}
178
202
}
179
203
180
- void _visitClassList (void Function (LinkedNodeBuilder ) f) {
181
- var unitDeclarations = unit.node.compilationUnit_declarations;
182
- for (LinkedNodeBuilder unitDeclaration in unitDeclarations) {
183
- if (unitDeclaration.kind == LinkedNodeKind .classDeclaration ||
184
- unitDeclaration.kind == LinkedNodeKind .mixinDeclaration) {
185
- f (unitDeclaration);
204
+ void _setOmittedReturnTypesClass (ClassElement class_) {
205
+ for (MethodElementImpl method in class_.methods) {
206
+ LinkedNodeBuilder methodNode = method.linkedNode;
207
+ if (methodNode.methodDeclaration_returnType == null ) {
208
+ methodNode.methodDeclaration_returnType2 = LinkedNodeTypeBuilder (
209
+ kind: LinkedNodeTypeKind .dynamic_,
210
+ );
211
+ }
212
+ }
213
+
214
+ for (PropertyAccessorElementImpl accessor in class_.accessors) {
215
+ if (accessor.isSynthetic) continue ;
216
+
217
+ LinkedNodeBuilder accessorNode = accessor.linkedNode;
218
+ if (accessorNode.methodDeclaration_returnType != null ) continue ;
219
+
220
+ if (accessor.isSetter) {
221
+ accessorNode.methodDeclaration_returnType2 = LinkedNodeTypeBuilder (
222
+ kind: LinkedNodeTypeKind .void_,
223
+ );
224
+ } else {
225
+ accessorNode.methodDeclaration_returnType2 = LinkedNodeTypeBuilder (
226
+ kind: LinkedNodeTypeKind .dynamic_,
227
+ );
186
228
}
187
229
}
188
230
}
0 commit comments