@@ -66,14 +66,23 @@ class FieldFragment
6666 }
6767 }
6868
69+ /// Returns the token for the initializer of this field, if any.
70+ ///
71+ /// This can only be called once and will hand over the responsibility of
72+ /// the token to the caller.
6973 Token ? get initializerToken {
7074 Token ? result = _initializerToken;
7175 // Ensure that we don't hold onto the token.
7276 _initializerToken = null ;
7377 return result;
7478 }
7579
76- // Coverage-ignore(suite): Not run.
80+ /// Returns the token for the initializer of this field, if any. This is the
81+ /// same as [initializerToken] but is used to signal that the initializer
82+ /// needs to be computed for outline expressions.
83+ ///
84+ /// This can only be called once and will hand over the responsibility of
85+ /// the token to the caller.
7786 Token ? get constInitializerToken {
7887 Token ? result = _constInitializerToken;
7988 // Ensure that we don't hold onto the token.
@@ -173,13 +182,63 @@ class FieldFragment
173182 } else {
174183 // A field with no type and initializer or an instance field without
175184 // type and initializer need to have the type inferred.
176- _encoding.type =
177- new InferredType .fromFieldFragmentInitializer (this , token);
185+ _encoding.type = new InferredType (
186+ libraryBuilder: libraryBuilder,
187+ typeBuilder: type,
188+ inferType: inferType,
189+ computeType: _computeInferredType,
190+ fileUri: fileUri,
191+ name: name,
192+ nameOffset: nameOffset,
193+ nameLength: name.length,
194+ token: token);
178195 type.registerInferable (this );
179196 }
180197 }
181198 }
182199
200+ DartType _computeInferredType (
201+ ClassHierarchyBase classHierarchy, Token ? token) {
202+ DartType ? inferredType;
203+ SourceLibraryBuilder libraryBuilder = builder.libraryBuilder;
204+ DeclarationBuilder ? declarationBuilder = builder.declarationBuilder;
205+ if (token != null ) {
206+ InterfaceType ? enclosingClassThisType = declarationBuilder
207+ is SourceClassBuilder
208+ ? libraryBuilder.loader.typeInferenceEngine.coreTypes
209+ .thisInterfaceType (
210+ declarationBuilder.cls, libraryBuilder.library.nonNullable)
211+ : null ;
212+ TypeInferrer typeInferrer =
213+ libraryBuilder.loader.typeInferenceEngine.createTopLevelTypeInferrer (
214+ fileUri,
215+ enclosingClassThisType,
216+ libraryBuilder,
217+ builder
218+ .dataForTesting
219+ // Coverage-ignore(suite): Not run.
220+ ? .inferenceData);
221+ BodyBuilderContext bodyBuilderContext = createBodyBuilderContext ();
222+ BodyBuilder bodyBuilder = libraryBuilder.loader.createBodyBuilderForField (
223+ libraryBuilder,
224+ bodyBuilderContext,
225+ declarationBuilder? .scope ?? libraryBuilder.scope,
226+ typeInferrer,
227+ fileUri);
228+ bodyBuilder.constantContext =
229+ modifiers.isConst ? ConstantContext .inferred : ConstantContext .none;
230+ bodyBuilder.inFieldInitializer = true ;
231+ bodyBuilder.inLateFieldInitializer = modifiers.isLate;
232+ Expression initializer = bodyBuilder.parseFieldInitializer (token);
233+
234+ inferredType =
235+ typeInferrer.inferImplicitFieldType (bodyBuilder, initializer);
236+ } else {
237+ inferredType = const DynamicType ();
238+ }
239+ return inferredType;
240+ }
241+
183242 @override
184243 bool get isEnumElement => false ;
185244
@@ -240,13 +299,13 @@ class FieldFragment
240299 // For modular compilation we need to include initializers of all const
241300 // fields and all non-static final fields in classes with const constructors
242301 // into the outline.
302+ Token ? token = constInitializerToken;
243303 if ((modifiers.isConst ||
244304 (isFinal &&
245305 isClassInstanceMember &&
246306 (declarationBuilder as SourceClassBuilder )
247307 .declaresConstConstructor)) &&
248- _constInitializerToken != null ) {
249- Token initializerToken = _constInitializerToken! ;
308+ token != null ) {
250309 LookupScope scope = declarationBuilder? .scope ?? libraryBuilder.scope;
251310 BodyBuilder bodyBuilder = libraryBuilder.loader
252311 .createBodyBuilderForOutlineExpression (
@@ -255,18 +314,17 @@ class FieldFragment
255314 ? ConstantContext .inferred
256315 : ConstantContext .required ;
257316 Expression initializer = bodyBuilder.typeInferrer
258- .inferFieldInitializer (bodyBuilder, fieldType,
259- bodyBuilder.parseFieldInitializer (initializerToken ))
317+ .inferFieldInitializer (
318+ bodyBuilder, fieldType, bodyBuilder .parseFieldInitializer (token ))
260319 .expression;
261320 buildBody (classHierarchy.coreTypes, initializer);
262321 bodyBuilder.performBacklogComputations ();
263322 if (computeSharedExpressionForTesting) {
264323 // Coverage-ignore-block(suite): Not run.
265324 _initializerExpression = parseFieldInitializer (libraryBuilder.loader,
266- initializerToken , libraryBuilder.importUri, fileUri, scope);
325+ token , libraryBuilder.importUri, fileUri, scope);
267326 }
268327 }
269- _constInitializerToken = null ;
270328 }
271329
272330 @override
0 commit comments