[cfe] Account for compilation stage in invocations post-processing

Closes https://github.com/dart-lang/sdk/issues/55849
Closes https://github.com/dart-lang/sdk/issues/55755

Change-Id: I471830cafed76ec5c503fe726ade857c007ed712
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/369063
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index f387b61..e8efa88 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -273,8 +273,11 @@
         final DeclarationBuilder declarationBuilder =
             parent!.parent as DeclarationBuilder;
         Scope scope = declarationBuilder.scope;
-        BodyBuilderContext bodyBuilderContext =
-            new ParameterBodyBuilderContext(this);
+        BodyBuilderContext bodyBuilderContext = new ParameterBodyBuilderContext(
+            this,
+            inOutlineBuildingPhase: true,
+            inMetadata: false,
+            inConstFields: false);
         BodyBuilder bodyBuilder = libraryBuilder.loader
             .createBodyBuilderForOutlineExpression(
                 libraryBuilder, bodyBuilderContext, scope, fileUri);
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index bc2e5af..c3e73fa 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -252,6 +252,9 @@
     return _defaultValueNestingLevel > 0;
   }
 
+  /// True if the parser is between [beginMetadata] and [endMetadata].
+  bool _insideMetadataParsing = false;
+
   /// Numeric nestedness of formal parameter default values.
   ///
   /// The value of 0 means that the currently built part is not within a default
@@ -292,10 +295,36 @@
   /// values or inside the default values that aren't built as outline
   /// expressions need to be added during the second pass.
   bool get _createdStaticInvocationsNeedPostProcessing {
-    return _context.hasFormalParameters &&
-            !_insideOfFormalParameterDefaultValue ||
-        !_context.hasImmediateOutlineExpressionsBuilt ||
-        !_context.needsImmediateValuesBuiltAsOutlineExpressions;
+    return
+        // All invocations in outline building phase will be type-inferred, and
+        // they all should be added to the post-processing.
+        _context.inOutlineBuildingPhase ||
+
+            // Here we aren't in the outline mode, but rather in the
+            // body-building mode. If the current context has formal parameters,
+            // their default values should be skipped because in the
+            // body-building mode they aren't passed through type inference. An
+            // exception here is the default values of instance methods: they
+            // are actually inferred in body-building phase, and they aren't
+            // built at all during the outline phase.
+            (!_context.hasFormalParameters ||
+                    !_insideOfFormalParameterDefaultValue ||
+                    !isDeclarationInstanceContext) &&
+
+                // The invocations in the metadata should also be skipped in the
+                // body-building phase, since they aren't type-inferred. An
+                // exception here are the annotations within method bodies,
+                // field initializers, and on formal parameters.
+                !(_context.inMetadata ||
+                    _insideMetadataParsing &&
+                        !_inBody &&
+                        !inFormals &&
+                        !inFieldInitializer) &&
+
+                // Finally, the const fields in body-building phase aren't
+                // inferred and the invocations in them should be skipped during
+                // post-processing.
+                !_context.inConstFields;
   }
 
   bool get inFunctionType =>
@@ -315,6 +344,10 @@
 
   int functionNestingLevel = 0;
 
+  int _inBodyCount = 0;
+
+  bool get _inBody => _inBodyCount > 0;
+
   Statement? problemInLoopOrSwitch;
 
   Scope? switchScope;
@@ -475,6 +508,9 @@
   void enterLocalScope(Scope localScope) {
     push(scope);
     scope = localScope;
+    if (scope.kind == ScopeKind.functionBody) {
+      _inBodyCount++;
+    }
     assert(checkState(null, [
       ValueKinds.Scope,
     ]));
@@ -484,6 +520,9 @@
       {required String debugName, required ScopeKind kind}) {
     push(scope);
     scope = scope.createNestedScope(debugName: debugName, kind: kind);
+    if (kind == ScopeKind.functionBody) {
+      _inBodyCount++;
+    }
     assert(checkState(null, [
       ValueKinds.Scope,
     ]));
@@ -508,6 +547,9 @@
         declaredInCurrentGuard = null;
       }
     }
+    if (scope.kind == ScopeKind.functionBody) {
+      _inBodyCount--;
+    }
     scope = pop() as Scope;
   }
 
@@ -867,6 +909,7 @@
     super.push(constantContext);
     constantContext = ConstantContext.inferred;
     assert(checkState(token, [ValueKinds.ConstantContext]));
+    _insideMetadataParsing = true;
   }
 
   @override
@@ -941,6 +984,7 @@
       }
       constantContext = savedConstantContext;
     }
+    _insideMetadataParsing = false;
     assert(checkState(beginToken, [ValueKinds.Expression]));
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder_context.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder_context.dart
index 23d2e7a..ed08831 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder_context.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder_context.dart
@@ -43,16 +43,21 @@
 
   final bool isDeclarationInstanceMember;
 
+  final bool inOutlineBuildingPhase;
+
+  final bool inMetadata;
+
+  final bool inConstFields;
+
   BodyBuilderContext(
       LibraryBuilder libraryBuilder, DeclarationBuilder? declarationBuilder,
-      {required this.isDeclarationInstanceMember})
+      {required this.isDeclarationInstanceMember,
+      required this.inOutlineBuildingPhase,
+      required this.inMetadata,
+      required this.inConstFields})
       : _declarationContext = new BodyBuilderDeclarationContext(
             libraryBuilder, declarationBuilder);
 
-  bool get hasImmediateOutlineExpressionsBuilt;
-
-  bool get needsImmediateValuesBuiltAsOutlineExpressions;
-
   bool get hasFormalParameters;
 
   String get memberName {
@@ -490,21 +495,15 @@
 }
 
 class LibraryBodyBuilderContext extends BodyBuilderContext {
-  LibraryBodyBuilderContext(SourceLibraryBuilder libraryBuilder)
-      : super(libraryBuilder, null, isDeclarationInstanceMember: false);
-
-  @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // Libraries don't have immediate values.
-    return false;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    // Libraries don't have immediate values relevant in outlines, so all of
-    // them from the empty set can be assumed to have been processed.
-    return true;
-  }
+  LibraryBodyBuilderContext(SourceLibraryBuilder libraryBuilder,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
+      : super(libraryBuilder, null,
+            isDeclarationInstanceMember: false,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get hasFormalParameters => false;
@@ -520,22 +519,15 @@
 
 class ClassBodyBuilderContext extends BodyBuilderContext
     with _DeclarationBodyBuilderContext<SourceClassBuilder> {
-  ClassBodyBuilderContext(SourceClassBuilder sourceClassBuilder)
+  ClassBodyBuilderContext(SourceClassBuilder sourceClassBuilder,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(sourceClassBuilder.libraryBuilder, sourceClassBuilder,
-            isDeclarationInstanceMember: false);
-
-  @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // Classes don't have immediate values.
-    return false;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    // Classes don't have immediate values relevant in outlines, so all of
-    // them from the empty set can be assumed to have been processed.
-    return true;
-  }
+            isDeclarationInstanceMember: false,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get hasFormalParameters => false;
@@ -543,22 +535,15 @@
 
 class EnumBodyBuilderContext extends BodyBuilderContext
     with _DeclarationBodyBuilderContext<SourceEnumBuilder> {
-  EnumBodyBuilderContext(SourceEnumBuilder sourceEnumBuilder)
+  EnumBodyBuilderContext(SourceEnumBuilder sourceEnumBuilder,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(sourceEnumBuilder.libraryBuilder, sourceEnumBuilder,
-            isDeclarationInstanceMember: false);
-
-  @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // Enums don't have immediate values relevant in outlines.
-    return false;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    // Enums don't have immediate values relevant in outlines, so all of
-    // them from the empty set can be assumed to have been processed.
-    return true;
-  }
+            isDeclarationInstanceMember: false,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get hasFormalParameters => false;
@@ -566,22 +551,15 @@
 
 class ExtensionBodyBuilderContext extends BodyBuilderContext
     with _DeclarationBodyBuilderContext<SourceExtensionBuilder> {
-  ExtensionBodyBuilderContext(SourceExtensionBuilder sourceExtensionBuilder)
+  ExtensionBodyBuilderContext(SourceExtensionBuilder sourceExtensionBuilder,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(sourceExtensionBuilder.libraryBuilder, sourceExtensionBuilder,
-            isDeclarationInstanceMember: false);
-
-  @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // Extensions don't have immediate values.
-    return false;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    // Extensions don't have immediate values relevant in outlines, so all of
-    // them from the empty set can be assumed to have been processed.
-    return true;
-  }
+            isDeclarationInstanceMember: false,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get hasFormalParameters => false;
@@ -591,46 +569,31 @@
     with _DeclarationBodyBuilderContext<SourceExtensionTypeDeclarationBuilder> {
   ExtensionTypeBodyBuilderContext(
       SourceExtensionTypeDeclarationBuilder
-          sourceExtensionTypeDeclarationBuilder)
+          sourceExtensionTypeDeclarationBuilder,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(sourceExtensionTypeDeclarationBuilder.libraryBuilder,
             sourceExtensionTypeDeclarationBuilder,
-            isDeclarationInstanceMember: false);
-
-  @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // Extension type declarations don't have immediate values.
-    return false;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    // Extension type declarations don't have immediate values relevant in
-    // outlines, so all of them from the empty set can be assumed to have been
-    // processed.
-    return true;
-  }
+            isDeclarationInstanceMember: false,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get hasFormalParameters => false;
 }
 
 class TypedefBodyBuilderContext extends BodyBuilderContext {
-  TypedefBodyBuilderContext(SourceTypeAliasBuilder sourceTypeAliasBuilder)
+  TypedefBodyBuilderContext(SourceTypeAliasBuilder sourceTypeAliasBuilder,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(sourceTypeAliasBuilder.libraryBuilder, null,
-            isDeclarationInstanceMember: false);
-
-  @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // Typedefs don't have immediate values.
-    return false;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    // Typedefs don't have immediate values relevant in outlines, so all of
-    // them from the empty set can be assumed to have been processed.
-    return true;
-  }
+            isDeclarationInstanceMember: false,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get hasFormalParameters => false;
@@ -662,9 +625,15 @@
   @override
   SourceFieldBuilder _member;
 
-  FieldBodyBuilderContext(this._member)
+  FieldBodyBuilderContext(this._member,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(_member.libraryBuilder, _member.declarationBuilder,
-            isDeclarationInstanceMember: _member.isDeclarationInstanceMember);
+            isDeclarationInstanceMember: _member.isDeclarationInstanceMember,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get isLateField => _member.isLate;
@@ -694,17 +663,6 @@
   }
 
   @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // Const field initializers are a part of outline.
-    return _member.isConst;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    return _member.hasOutlineExpressionsBuilt;
-  }
-
-  @override
   bool get hasFormalParameters => false;
 }
 
@@ -800,19 +758,15 @@
   @override
   final SourceProcedureBuilder _member;
 
-  ProcedureBodyBuilderContext(this._member)
+  ProcedureBodyBuilderContext(this._member,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(_member.libraryBuilder, _member.declarationBuilder,
-            isDeclarationInstanceMember: _member.isDeclarationInstanceMember);
-
-  @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    return _member.needsDefaultValuesBuiltAsOutlineExpressions;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    return _member.hasBuiltOutlineExpressions;
-  }
+            isDeclarationInstanceMember: _member.isDeclarationInstanceMember,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get hasFormalParameters => true;
@@ -882,9 +836,15 @@
   @override
   final DeclaredSourceConstructorBuilder _member;
 
-  ConstructorBodyBuilderContext(this._member)
+  ConstructorBodyBuilderContext(this._member,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(_member.libraryBuilder, _member.declarationBuilder,
-            isDeclarationInstanceMember: _member.isDeclarationInstanceMember);
+            isDeclarationInstanceMember: _member.isDeclarationInstanceMember,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool isConstructorCyclic(String name) {
@@ -898,19 +858,6 @@
   }
 
   @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // For modular compilation we need to include default values for optional
-    // and named parameters generative constructors to support forwarding
-    // constructors in mixin applications.
-    return true;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    return _member.hasBuiltOutlineExpressions;
-  }
-
-  @override
   bool get hasFormalParameters => true;
 }
 
@@ -923,9 +870,15 @@
   @override
   final SourceExtensionTypeConstructorBuilder _member;
 
-  ExtensionTypeConstructorBodyBuilderContext(this._member)
+  ExtensionTypeConstructorBodyBuilderContext(this._member,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(_member.libraryBuilder, _member.declarationBuilder,
-            isDeclarationInstanceMember: _member.isDeclarationInstanceMember);
+            isDeclarationInstanceMember: _member.isDeclarationInstanceMember,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool isConstructorCyclic(String name) {
@@ -933,19 +886,6 @@
   }
 
   @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // For modular compilation we need to include default values for optional
-    // and named parameters generative constructors to support forwarding
-    // constructors in mixin applications.
-    return true;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    return _member.hasBuiltOutlineExpressions;
-  }
-
-  @override
   bool get hasFormalParameters => true;
 }
 
@@ -956,9 +896,15 @@
   @override
   final SourceFactoryBuilder _member;
 
-  FactoryBodyBuilderContext(this._member)
+  FactoryBodyBuilderContext(this._member,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(_member.libraryBuilder, _member.declarationBuilder,
-            isDeclarationInstanceMember: _member.isDeclarationInstanceMember);
+            isDeclarationInstanceMember: _member.isDeclarationInstanceMember,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   void setAsyncModifier(AsyncMarker asyncModifier) {
@@ -971,19 +917,6 @@
   }
 
   @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // For modular compilation we need to include default values for optional
-    // and named parameters in several cases for const constructors to enable
-    // constant evaluation,
-    return _member.parent!.isFactory && _member.parent!.isConst;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    return _member.hasBuiltOutlineExpressions;
-  }
-
-  @override
   bool get hasFormalParameters => true;
 }
 
@@ -994,9 +927,15 @@
   @override
   final RedirectingFactoryBuilder _member;
 
-  RedirectingFactoryBodyBuilderContext(this._member)
+  RedirectingFactoryBodyBuilderContext(this._member,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(_member.libraryBuilder, _member.declarationBuilder,
-            isDeclarationInstanceMember: _member.isDeclarationInstanceMember);
+            isDeclarationInstanceMember: _member.isDeclarationInstanceMember,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get isRedirectingFactory => true;
@@ -1007,50 +946,37 @@
   }
 
   @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // For modular compilation we need to include default values for optional
-    // and named parameters in several cases for const constructors to enable
-    // constant evaluation,
-    return _member.parent!.isFactory && _member.parent!.isConst;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    return _member.hasBuiltOutlineExpressions;
-  }
-
-  @override
   bool get hasFormalParameters => true;
 }
 
 class ParameterBodyBuilderContext extends BodyBuilderContext {
   factory ParameterBodyBuilderContext(
-      FormalParameterBuilder formalParameterBuilder) {
+      FormalParameterBuilder formalParameterBuilder,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
     final DeclarationBuilder declarationBuilder =
         formalParameterBuilder.parent!.parent as DeclarationBuilder;
     return new ParameterBodyBuilderContext._(declarationBuilder.libraryBuilder,
-        declarationBuilder, formalParameterBuilder);
+        declarationBuilder, formalParameterBuilder,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
   }
 
   ParameterBodyBuilderContext._(
       LibraryBuilder libraryBuilder,
       DeclarationBuilder? declarationBuilder,
-      FormalParameterBuilder formalParameterBuilder)
+      FormalParameterBuilder formalParameterBuilder,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(libraryBuilder, declarationBuilder,
             isDeclarationInstanceMember:
-                formalParameterBuilder.isDeclarationInstanceMember);
-
-  @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // Parameters are covered by their parents rather than individually.
-    return false;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    // Parameters are covered by their parents rather than individually.
-    return true;
-  }
+                formalParameterBuilder.isDeclarationInstanceMember,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get hasFormalParameters => false;
@@ -1063,22 +989,15 @@
 
   ExpressionCompilerProcedureBodyBuildContext(
       DietListener listener, this._member,
-      {required bool isDeclarationInstanceMember})
+      {required bool isDeclarationInstanceMember,
+      required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields})
       : super(listener.libraryBuilder, listener.currentDeclaration,
-            isDeclarationInstanceMember: isDeclarationInstanceMember);
-
-  @override
-  bool get needsImmediateValuesBuiltAsOutlineExpressions {
-    // Expressions don't have immediate values relevant in outlines.
-    return false;
-  }
-
-  @override
-  bool get hasImmediateOutlineExpressionsBuilt {
-    // Expressions don't have immediate values relevant in outlines, so all of
-    // them from the empty set can be assumed to have been processed.
-    return true;
-  }
+            isDeclarationInstanceMember: isDeclarationInstanceMember,
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields);
 
   @override
   bool get hasFormalParameters => false;
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index 2f2810c..d354a1e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -135,7 +135,11 @@
               enclosingClassThisType,
               fieldBuilder.libraryBuilder,
               fieldBuilder.dataForTesting?.inferenceData);
-      BodyBuilderContext bodyBuilderContext = fieldBuilder.bodyBuilderContext;
+      BodyBuilderContext bodyBuilderContext =
+          fieldBuilder.createBodyBuilderContext(
+              inOutlineBuildingPhase: false,
+              inMetadata: false,
+              inConstFields: false);
       BodyBuilder bodyBuilder = fieldBuilder.libraryBuilder.loader
           .createBodyBuilderForField(
               fieldBuilder.libraryBuilder,
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index 0f698af..ae10670 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -1048,7 +1048,10 @@
   }
 
   @override
-  BodyBuilderContext get bodyBuilderContext {
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
     throw new UnsupportedError(
         '$runtimeType.bodyBuilderContextForAnnotations}');
   }
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index faeac47..7bd81e1 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -351,8 +351,11 @@
     if (name is ParserRecovery) return;
 
     Identifier identifier = name as Identifier;
-    final BodyBuilder listener =
-        createFunctionListener(_offsetMap.lookupProcedure(identifier));
+    final BodyBuilder listener = createFunctionListener(
+        _offsetMap.lookupProcedure(identifier),
+        inOutlineBuildingPhase: false,
+        inMetadata: false,
+        inConstFields: false);
     buildFunctionBody(listener, bodyToken, metadata, MemberKind.TopLevelMethod);
   }
 
@@ -551,7 +554,13 @@
 
     LibraryDependency? dependency =
         _offsetMap.lookupImport(importKeyword).libraryDependency;
-    parseMetadata(libraryBuilder.bodyBuilderContext, metadata, dependency);
+    parseMetadata(
+        libraryBuilder.createBodyBuilderContext(
+            inOutlineBuildingPhase: true,
+            inMetadata: true,
+            inConstFields: false),
+        metadata,
+        dependency);
   }
 
   @override
@@ -566,7 +575,13 @@
     Token? metadata = pop() as Token?;
     LibraryDependency dependency =
         _offsetMap.lookupExport(exportKeyword).libraryDependency;
-    parseMetadata(libraryBuilder.bodyBuilderContext, metadata, dependency);
+    parseMetadata(
+        libraryBuilder.createBodyBuilderContext(
+            inOutlineBuildingPhase: true,
+            inMetadata: true,
+            inConstFields: false),
+        metadata,
+        dependency);
   }
 
   @override
@@ -575,7 +590,13 @@
 
     Token? metadata = pop() as Token?;
     LibraryPart part = _offsetMap.lookupPart(partKeyword);
-    parseMetadata(libraryBuilder.bodyBuilderContext, metadata, part);
+    parseMetadata(
+        libraryBuilder.createBodyBuilderContext(
+            inOutlineBuildingPhase: true,
+            inMetadata: true,
+            inConstFields: false),
+        metadata,
+        part);
   }
 
   @override
@@ -623,7 +644,13 @@
       buildRedirectingFactoryMethod(
           bodyToken, builder, MemberKind.Factory, metadata);
     } else {
-      buildFunctionBody(createFunctionListener(builder), bodyToken, metadata,
+      buildFunctionBody(
+          createFunctionListener(builder,
+              inOutlineBuildingPhase: false,
+              inMetadata: false,
+              inConstFields: false),
+          bodyToken,
+          metadata,
           MemberKind.Factory);
     }
   }
@@ -761,7 +788,13 @@
           ? MemberKind.StaticMethod
           : MemberKind.NonStaticMethod;
       buildFunctionBody(
-          createFunctionListener(builder), beginParam, metadata, memberKind);
+          createFunctionListener(builder,
+              inOutlineBuildingPhase: false,
+              inMetadata: false,
+              inConstFields: false),
+          beginParam,
+          metadata,
+          memberKind);
     }
   }
 
@@ -816,12 +849,20 @@
       ..constantContext = constantContext;
   }
 
-  BodyBuilder createFunctionListener(SourceFunctionBuilder builder) {
+  BodyBuilder createFunctionListener(SourceFunctionBuilder builder,
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
     final Scope typeParameterScope =
         builder.computeTypeParameterScope(memberScope);
     final Scope formalParameterScope =
         builder.computeFormalParameterScope(typeParameterScope);
-    return createListener(builder.bodyBuilderContext, typeParameterScope,
+    return createListener(
+        builder.createBodyBuilderContext(
+            inOutlineBuildingPhase: inOutlineBuildingPhase,
+            inMetadata: inMetadata,
+            inConstFields: inConstFields),
+        typeParameterScope,
         thisVariable: builder.thisVariable,
         thisTypeParameters: builder.thisTypeParameters,
         formalParameterScope: formalParameterScope,
@@ -832,7 +873,8 @@
       MemberKind kind, Token? metadata) {
     _benchmarker?.beginSubdivide(
         BenchmarkSubdivides.diet_listener_buildRedirectingFactoryMethod);
-    final BodyBuilder listener = createFunctionListener(builder);
+    final BodyBuilder listener = createFunctionListener(builder,
+        inOutlineBuildingPhase: false, inMetadata: false, inConstFields: false);
     try {
       Parser parser = new Parser(listener,
           useImplicitCreationExpression: useImplicitCreationExpressionInCfe,
@@ -871,7 +913,12 @@
     // TODO(paulberry): don't re-parse the field if we've already parsed it
     // for type inference.
     _parseFields(
-        createListener(declaration.bodyBuilderContext, memberScope,
+        createListener(
+            declaration.createBodyBuilderContext(
+                inOutlineBuildingPhase: false,
+                inMetadata: false,
+                inConstFields: declaration.isConst),
+            memberScope,
             inferenceDataForTesting: declaration.dataForTesting?.inferenceData),
         token,
         metadata,
@@ -1025,7 +1072,12 @@
     SourceFunctionBuilder builder =
         _offsetMap.lookupPrimaryConstructor(beginToken);
     if (!builder.isConst) {
-      buildPrimaryConstructor(createFunctionListener(builder), formalsToken);
+      buildPrimaryConstructor(
+          createFunctionListener(builder,
+              inOutlineBuildingPhase: false,
+              inMetadata: false,
+              inConstFields: false),
+          formalsToken);
     }
 
     // The current declaration is set in [beginClassOrMixinOrExtensionBody],
@@ -1081,8 +1133,11 @@
       DeclaredSourceConstructorBuilder? defaultConstructorBuilder =
           enumBuilder.synthesizedDefaultConstructorBuilder;
       if (defaultConstructorBuilder != null) {
-        BodyBuilder bodyBuilder =
-            createFunctionListener(defaultConstructorBuilder);
+        BodyBuilder bodyBuilder = createFunctionListener(
+            defaultConstructorBuilder,
+            inOutlineBuildingPhase: false,
+            inMetadata: false,
+            inConstFields: false);
         bodyBuilder.finishConstructor(AsyncMarker.Sync, new EmptyStatement(),
             superParametersAsArguments: null);
       }
diff --git a/pkg/front_end/lib/src/fasta/source/source_builder_mixins.dart b/pkg/front_end/lib/src/fasta/source/source_builder_mixins.dart
index fa2a2a1..3a81867 100644
--- a/pkg/front_end/lib/src/fasta/source/source_builder_mixins.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_builder_mixins.dart
@@ -142,19 +142,33 @@
     });
   }
 
-  BodyBuilderContext get bodyBuilderContext;
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields});
 
   void buildOutlineExpressions(
       ClassHierarchy classHierarchy,
       List<DelayedActionPerformer> delayedActionPerformers,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
-    MetadataBuilder.buildAnnotations(annotatable, metadata, bodyBuilderContext,
-        libraryBuilder, fileUri, libraryBuilder.scope);
+    MetadataBuilder.buildAnnotations(
+        annotatable,
+        metadata,
+        createBodyBuilderContext(
+            inOutlineBuildingPhase: true,
+            inMetadata: true,
+            inConstFields: false),
+        libraryBuilder,
+        fileUri,
+        libraryBuilder.scope);
     if (typeParameters != null) {
       for (int i = 0; i < typeParameters!.length; i++) {
         typeParameters![i].buildOutlineExpressions(
             libraryBuilder,
-            bodyBuilderContext,
+            createBodyBuilderContext(
+                inOutlineBuildingPhase: true,
+                inMetadata: true,
+                inConstFields: false),
             classHierarchy,
             delayedActionPerformers,
             scope.parent!);
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index c5f967d..fd67ab7 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -334,8 +334,15 @@
     return cls;
   }
 
-  BodyBuilderContext get bodyBuilderContext =>
-      new ClassBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new ClassBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   void buildOutlineExpressions(
       ClassHierarchy classHierarchy,
@@ -347,14 +354,25 @@
           classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
     }
 
-    MetadataBuilder.buildAnnotations(isAugmenting ? origin.cls : cls, metadata,
-        bodyBuilderContext, libraryBuilder, fileUri, libraryBuilder.scope,
+    MetadataBuilder.buildAnnotations(
+        isAugmenting ? origin.cls : cls,
+        metadata,
+        createBodyBuilderContext(
+            inOutlineBuildingPhase: true,
+            inMetadata: true,
+            inConstFields: false),
+        libraryBuilder,
+        fileUri,
+        libraryBuilder.scope,
         createFileUriExpression: isAugmenting);
     if (typeVariables != null) {
       for (int i = 0; i < typeVariables!.length; i++) {
         typeVariables![i].buildOutlineExpressions(
             libraryBuilder,
-            bodyBuilderContext,
+            createBodyBuilderContext(
+                inOutlineBuildingPhase: true,
+                inMetadata: true,
+                inConstFields: false),
             classHierarchy,
             delayedActionPerformers,
             scope.parent!);
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
index 1d9fdee..098a07b 100644
--- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -314,7 +314,13 @@
       }
       BodyBuilder bodyBuilder = libraryBuilder.loader
           .createBodyBuilderForOutlineExpression(
-              libraryBuilder, bodyBuilderContext, declarationScope, fileUri,
+              libraryBuilder,
+              createBodyBuilderContext(
+                  inOutlineBuildingPhase: true,
+                  inMetadata: false,
+                  inConstFields: false),
+              declarationScope,
+              fileUri,
               formalParameterScope: formalParameterScope);
       if (isConst) {
         bodyBuilder.constantContext = ConstantContext.required;
@@ -626,8 +632,14 @@
       List<Initializer>? initializers;
       if (beginInitializers != null) {
         BodyBuilder bodyBuilder = libraryBuilder.loader
-            .createBodyBuilderForOutlineExpression(libraryBuilder,
-                bodyBuilderContext, declarationBuilder.scope, fileUri);
+            .createBodyBuilderForOutlineExpression(
+                libraryBuilder,
+                createBodyBuilderContext(
+                    inOutlineBuildingPhase: false,
+                    inMetadata: false,
+                    inConstFields: false),
+                declarationBuilder.scope,
+                fileUri);
         if (isConst) {
           bodyBuilder.constantContext = ConstantContext.required;
         }
@@ -953,8 +965,15 @@
   }
 
   @override
-  BodyBuilderContext get bodyBuilderContext =>
-      new ConstructorBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new ConstructorBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   // TODO(johnniwinther): Add annotations to tear-offs.
   @override
@@ -1362,8 +1381,15 @@
   }
 
   @override
-  BodyBuilderContext get bodyBuilderContext =>
-      new ExtensionTypeConstructorBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new ExtensionTypeConstructorBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   // TODO(johnniwinther): Add annotations to tear-offs.
   @override
diff --git a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
index 01b9e0b..92d88e3 100644
--- a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
@@ -659,7 +659,15 @@
   }
 
   @override
-  BodyBuilderContext get bodyBuilderContext => new EnumBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new EnumBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   DartType buildElement(SourceFieldBuilder fieldBuilder, CoreTypes coreTypes) {
     DartType selfType =
@@ -720,7 +728,13 @@
       // be built via a body builder to detect potential errors.
       BodyBuilder bodyBuilder = libraryBuilder.loader
           .createBodyBuilderForOutlineExpression(
-              libraryBuilder, bodyBuilderContext, scope, fileUri);
+              libraryBuilder,
+              createBodyBuilderContext(
+                  inOutlineBuildingPhase: true,
+                  inMetadata: false,
+                  inConstFields: false),
+              scope,
+              fileUri);
       bodyBuilder.constantContext = ConstantContext.inferred;
 
       if (enumConstantInfo.argumentsBeginToken != null) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index f32e393..4164048 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -84,8 +84,15 @@
   Extension get extension => isAugmenting ? origin._extension : _extension;
 
   @override
-  BodyBuilderContext get bodyBuilderContext =>
-      new ExtensionBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new ExtensionBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   @override
   Annotatable get annotatable => extension;
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart
index 627311b..1498e7d 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart
@@ -749,8 +749,15 @@
   bool get isMixinDeclaration => false;
 
   @override
-  BodyBuilderContext get bodyBuilderContext =>
-      new ExtensionTypeBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new ExtensionTypeBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   /// Return a map whose keys are the supertypes of this
   /// [SourceExtensionTypeDeclarationBuilder] after expansion of type aliases,
diff --git a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
index 6069769..f4e4d35 100644
--- a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
@@ -313,8 +313,15 @@
   void _checkRedirectingFactory(TypeEnvironment typeEnvironment) {}
 
   @override
-  BodyBuilderContext get bodyBuilderContext =>
-      new FactoryBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new FactoryBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   @override
   String get fullNameForErrors {
@@ -489,8 +496,14 @@
           .createLocalTypeInferrer(
               fileUri, declarationBuilder.thisType, libraryBuilder, null);
       InferenceHelper helper = libraryBuilder.loader
-          .createBodyBuilderForOutlineExpression(libraryBuilder,
-              bodyBuilderContext, declarationBuilder.scope, fileUri);
+          .createBodyBuilderForOutlineExpression(
+              libraryBuilder,
+              createBodyBuilderContext(
+                  inOutlineBuildingPhase: true,
+                  inMetadata: false,
+                  inConstFields: false),
+              declarationBuilder.scope,
+              fileUri);
       Builder? targetBuilder = redirectionTarget.target;
       if (targetBuilder is SourceMemberBuilder) {
         // Ensure that target has been built.
@@ -836,6 +849,13 @@
   }
 
   @override
-  BodyBuilderContext get bodyBuilderContext =>
-      new RedirectingFactoryBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new RedirectingFactoryBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
index 94fd149..353926e 100644
--- a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
@@ -433,8 +433,15 @@
   }
 
   @override
-  BodyBuilderContext get bodyBuilderContext =>
-      new FieldBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new FieldBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   @override
   Iterable<Annotatable> get annotatables => _fieldEncoding.annotatables;
@@ -448,7 +455,10 @@
       MetadataBuilder.buildAnnotations(
           annotatable,
           metadata,
-          bodyBuilderContext,
+          createBodyBuilderContext(
+              inOutlineBuildingPhase: true,
+              inMetadata: true,
+              inConstFields: false),
           libraryBuilder,
           fileUri,
           declarationBuilder?.scope ?? libraryBuilder.scope);
@@ -466,7 +476,13 @@
       Scope scope = declarationBuilder?.scope ?? libraryBuilder.scope;
       BodyBuilder bodyBuilder = libraryBuilder.loader
           .createBodyBuilderForOutlineExpression(
-              libraryBuilder, bodyBuilderContext, scope, fileUri);
+              libraryBuilder,
+              createBodyBuilderContext(
+                  inOutlineBuildingPhase: true,
+                  inMetadata: false,
+                  inConstFields: false),
+              scope,
+              fileUri);
       bodyBuilder.constantContext =
           isConst ? ConstantContext.inferred : ConstantContext.required;
       Expression initializer = bodyBuilder.typeInferrer
diff --git a/pkg/front_end/lib/src/fasta/source/source_function_builder.dart b/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
index 7ed9c94..d56e3cc 100644
--- a/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
@@ -485,15 +485,26 @@
       Scope parentScope =
           classOrExtensionBuilder?.scope ?? libraryBuilder.scope;
       for (Annotatable annotatable in annotatables) {
-        MetadataBuilder.buildAnnotations(annotatable, metadata,
-            bodyBuilderContext, libraryBuilder, fileUri, parentScope,
+        MetadataBuilder.buildAnnotations(
+            annotatable,
+            metadata,
+            createBodyBuilderContext(
+                inOutlineBuildingPhase: true,
+                inMetadata: true,
+                inConstFields: false),
+            libraryBuilder,
+            fileUri,
+            parentScope,
             createFileUriExpression: isAugmented);
       }
       if (typeVariables != null) {
         for (int i = 0; i < typeVariables!.length; i++) {
           typeVariables![i].buildOutlineExpressions(
               libraryBuilder,
-              bodyBuilderContext,
+              createBodyBuilderContext(
+                  inOutlineBuildingPhase: true,
+                  inMetadata: true,
+                  inConstFields: false),
               classHierarchy,
               delayedActionPerformers,
               computeTypeParameterScope(parentScope));
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 6e69f93..4854fac 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -3682,8 +3682,15 @@
     return builder;
   }
 
-  BodyBuilderContext get bodyBuilderContext =>
-      new LibraryBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new LibraryBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   void buildOutlineExpressions(
       ClassHierarchy classHierarchy,
@@ -3699,7 +3706,15 @@
     }
 
     MetadataBuilder.buildAnnotations(
-        library, metadata, bodyBuilderContext, this, fileUri, scope,
+        library,
+        metadata,
+        createBodyBuilderContext(
+            inOutlineBuildingPhase: true,
+            inMetadata: true,
+            inConstFields: false),
+        this,
+        fileUri,
+        scope,
         createFileUriExpression: isAugmenting);
 
     Iterator<Builder> iterator = localMembersIterator;
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 97dec8b..17f85da 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -1247,7 +1247,10 @@
       ..parent = parent;
     BodyBuilder listener = dietListener.createListener(
         new ExpressionCompilerProcedureBodyBuildContext(dietListener, builder,
-            isDeclarationInstanceMember: isClassInstanceMember),
+            isDeclarationInstanceMember: isClassInstanceMember,
+            inOutlineBuildingPhase: false,
+            inMetadata: false,
+            inConstFields: false),
         dietListener.memberScope,
         thisVariable: extensionThis);
     builder.procedure.function = parameters..parent = builder.procedure;
diff --git a/pkg/front_end/lib/src/fasta/source/source_member_builder.dart b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
index 37de262..8b6dbc1 100644
--- a/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
@@ -63,7 +63,10 @@
 
   AugmentSuperTarget? get augmentSuperTarget;
 
-  BodyBuilderContext get bodyBuilderContext;
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields});
 }
 
 mixin SourceMemberBuilderMixin implements SourceMemberBuilder {
@@ -99,7 +102,10 @@
   }
 
   @override
-  BodyBuilderContext get bodyBuilderContext {
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
     throw new UnimplementedError('$runtimeType.bodyBuilderContext');
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
index 8170d90..5ca96f5 100644
--- a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
@@ -655,8 +655,15 @@
   }
 
   @override
-  BodyBuilderContext get bodyBuilderContext =>
-      new ProcedureBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new ProcedureBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   // TODO(johnniwinther): Add annotations to tear-offs.
   @override
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index e3a850e..5b8e423 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -317,20 +317,38 @@
         growable: true);
   }
 
-  BodyBuilderContext get bodyBuilderContext =>
-      new TypedefBodyBuilderContext(this);
+  BodyBuilderContext createBodyBuilderContext(
+      {required bool inOutlineBuildingPhase,
+      required bool inMetadata,
+      required bool inConstFields}) {
+    return new TypedefBodyBuilderContext(this,
+        inOutlineBuildingPhase: inOutlineBuildingPhase,
+        inMetadata: inMetadata,
+        inConstFields: inConstFields);
+  }
 
   void buildOutlineExpressions(
       ClassHierarchy classHierarchy,
       List<DelayedActionPerformer> delayedActionPerformers,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
-    MetadataBuilder.buildAnnotations(typedef, metadata, bodyBuilderContext,
-        libraryBuilder, fileUri, libraryBuilder.scope);
+    MetadataBuilder.buildAnnotations(
+        typedef,
+        metadata,
+        createBodyBuilderContext(
+            inOutlineBuildingPhase: true,
+            inMetadata: true,
+            inConstFields: false),
+        libraryBuilder,
+        fileUri,
+        libraryBuilder.scope);
     if (typeVariables != null) {
       for (int i = 0; i < typeVariables!.length; i++) {
         typeVariables![i].buildOutlineExpressions(
             libraryBuilder,
-            bodyBuilderContext,
+            createBodyBuilderContext(
+                inOutlineBuildingPhase: true,
+                inMetadata: true,
+                inConstFields: false),
             classHierarchy,
             delayedActionPerformers,
             computeTypeParameterScope(libraryBuilder.scope));
diff --git a/pkg/front_end/test/coverage_suite.dart b/pkg/front_end/test/coverage_suite.dart
index db241fa8..a398091 100644
--- a/pkg/front_end/test/coverage_suite.dart
+++ b/pkg/front_end/test/coverage_suite.dart
@@ -108,8 +108,7 @@
   "package:front_end/src/fasta/crash.dart": 59.09090909090909,
   "package:front_end/src/fasta/dill/dill_builder_mixins.dart": 100.0,
   "package:front_end/src/fasta/dill/dill_class_builder.dart": 92.34972677595628,
-  "package:front_end/src/fasta/dill/dill_extension_builder.dart":
-      86.74698795180723,
+  "package:front_end/src/fasta/dill/dill_extension_builder.dart": 80,
   "package:front_end/src/fasta/dill/dill_extension_member_builder.dart":
       70.29702970297029,
   "package:front_end/src/fasta/dill/dill_extension_type_declaration_builder.dart":
@@ -177,7 +176,7 @@
   "package:front_end/src/fasta/kernel/invalid_type.dart": 74.13793103448276,
   "package:front_end/src/fasta/kernel/kernel_constants.dart": 45.45454545454545,
   "package:front_end/src/fasta/kernel/kernel_helper.dart": 98.95833333333334,
-  "package:front_end/src/fasta/kernel/kernel_target.dart": 79.03103709311128,
+  "package:front_end/src/fasta/kernel/kernel_target.dart": 78,
   "package:front_end/src/fasta/kernel/kernel_variable_builder.dart":
       61.111111111111114,
   "package:front_end/src/fasta/kernel/late_lowering.dart": 100.0,
@@ -232,8 +231,7 @@
       84.0,
   "package:front_end/src/fasta/source/source_factory_builder.dart":
       92.22222222222223,
-  "package:front_end/src/fasta/source/source_field_builder.dart":
-      90.0990099009901,
+  "package:front_end/src/fasta/source/source_field_builder.dart": 89,
   "package:front_end/src/fasta/source/source_function_builder.dart":
       89.29663608562691,
   "package:front_end/src/fasta/source/source_library_builder.dart":
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 050a562..7531520 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -115,7 +115,10 @@
 
     BodyBuilder helper = new BodyBuilder(
         libraryBuilder: libraryBuilder,
-        context: new LibraryBodyBuilderContext(libraryBuilder),
+        context: new LibraryBodyBuilderContext(libraryBuilder,
+            inOutlineBuildingPhase: false,
+            inMetadata: false,
+            inConstFields: false),
         uri: uri,
         enclosingScope: new Scope.immutable(kind: ScopeKind.functionBody),
         coreTypes: coreTypes,
diff --git a/pkg/front_end/testcases/general/issue55755.dart b/pkg/front_end/testcases/general/issue55755.dart
new file mode 100644
index 0000000..d0b1a9a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55755.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class {
+  const Class([a]);
+  const Class.named({a, b});
+}
+
+class GenericClass<X, Y> {
+  const GenericClass();
+  const GenericClass.named({a, b});
+}
+
+typedef Alias = Class;
+typedef ComplexAlias<X> = Class;
+typedef GenericAlias<X, Y> = GenericClass<X, Y>;
+
+@Class(Alias.named())
+@Class(ComplexAlias())
+@Class(ComplexAlias.named())
+@Class(GenericAlias())
+@Class(GenericAlias.named())
+void type() {}
diff --git a/pkg/front_end/testcases/general/issue55755.dart.strong.expect b/pkg/front_end/testcases/general/issue55755.dart.strong.expect
new file mode 100644
index 0000000..502c4a1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55755.dart.strong.expect
@@ -0,0 +1,47 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Alias = self::Class;
+typedef ComplexAlias<unrelated X extends core::Object? = dynamic> = self::Class;
+typedef GenericAlias<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = self::GenericClass<X%, Y%>;
+class Class extends core::Object /*hasConstConstructor*/  {
+  const constructor •([dynamic a = #C1]) → self::Class
+    : super core::Object::•()
+    ;
+  const constructor named({dynamic a = #C1, dynamic b = #C1}) → self::Class
+    : super core::Object::•()
+    ;
+}
+class GenericClass<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::GenericClass<self::GenericClass::X%, self::GenericClass::Y%>
+    : super core::Object::•()
+    ;
+  const constructor named({dynamic a = #C1, dynamic b = #C1}) → self::GenericClass<self::GenericClass::X%, self::GenericClass::Y%>
+    : super core::Object::•()
+    ;
+}
+@#C2
+@#C2
+@#C2
+@#C2
+@#C2
+static method type() → void {}
+static method _#ComplexAlias#new#tearOff<unrelated X extends core::Object? = dynamic>([dynamic a = #C1]) → self::Class
+  return new self::Class::•(a);
+static method _#ComplexAlias#named#tearOff<unrelated X extends core::Object? = dynamic>({dynamic a = #C1, dynamic b = #C1}) → self::Class
+  return new self::Class::named(a: a, b: b);
+
+constants  {
+  #C1 = null
+  #C2 = self::Class {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue55755.dart:
+- Class.named (from org-dartlang-testcase:///issue55755.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
+- Class. (from org-dartlang-testcase:///issue55755.dart:6:9)
+- GenericClass. (from org-dartlang-testcase:///issue55755.dart:11:9)
+- GenericClass.named (from org-dartlang-testcase:///issue55755.dart:12:9)
diff --git a/pkg/front_end/testcases/general/issue55755.dart.strong.modular.expect b/pkg/front_end/testcases/general/issue55755.dart.strong.modular.expect
new file mode 100644
index 0000000..502c4a1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55755.dart.strong.modular.expect
@@ -0,0 +1,47 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Alias = self::Class;
+typedef ComplexAlias<unrelated X extends core::Object? = dynamic> = self::Class;
+typedef GenericAlias<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = self::GenericClass<X%, Y%>;
+class Class extends core::Object /*hasConstConstructor*/  {
+  const constructor •([dynamic a = #C1]) → self::Class
+    : super core::Object::•()
+    ;
+  const constructor named({dynamic a = #C1, dynamic b = #C1}) → self::Class
+    : super core::Object::•()
+    ;
+}
+class GenericClass<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::GenericClass<self::GenericClass::X%, self::GenericClass::Y%>
+    : super core::Object::•()
+    ;
+  const constructor named({dynamic a = #C1, dynamic b = #C1}) → self::GenericClass<self::GenericClass::X%, self::GenericClass::Y%>
+    : super core::Object::•()
+    ;
+}
+@#C2
+@#C2
+@#C2
+@#C2
+@#C2
+static method type() → void {}
+static method _#ComplexAlias#new#tearOff<unrelated X extends core::Object? = dynamic>([dynamic a = #C1]) → self::Class
+  return new self::Class::•(a);
+static method _#ComplexAlias#named#tearOff<unrelated X extends core::Object? = dynamic>({dynamic a = #C1, dynamic b = #C1}) → self::Class
+  return new self::Class::named(a: a, b: b);
+
+constants  {
+  #C1 = null
+  #C2 = self::Class {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue55755.dart:
+- Class.named (from org-dartlang-testcase:///issue55755.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
+- Class. (from org-dartlang-testcase:///issue55755.dart:6:9)
+- GenericClass. (from org-dartlang-testcase:///issue55755.dart:11:9)
+- GenericClass.named (from org-dartlang-testcase:///issue55755.dart:12:9)
diff --git a/pkg/front_end/testcases/general/issue55755.dart.strong.outline.expect b/pkg/front_end/testcases/general/issue55755.dart.strong.outline.expect
new file mode 100644
index 0000000..0d70fbd
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55755.dart.strong.outline.expect
@@ -0,0 +1,43 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Alias = self::Class;
+typedef ComplexAlias<unrelated X extends core::Object? = dynamic> = self::Class;
+typedef GenericAlias<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = self::GenericClass<X%, Y%>;
+class Class extends core::Object /*hasConstConstructor*/  {
+  const constructor •([dynamic a = null]) → self::Class
+    : super core::Object::•()
+    ;
+  const constructor named({dynamic a = null, dynamic b = null}) → self::Class
+    : super core::Object::•()
+    ;
+}
+class GenericClass<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::GenericClass<self::GenericClass::X%, self::GenericClass::Y%>
+    : super core::Object::•()
+    ;
+  const constructor named({dynamic a = null, dynamic b = null}) → self::GenericClass<self::GenericClass::X%, self::GenericClass::Y%>
+    : super core::Object::•()
+    ;
+}
+@self::Class::•(const self::Class::named())
+@self::Class::•(const self::Class::•())
+@self::Class::•(const self::Class::named())
+@self::Class::•(const self::GenericClass::•<dynamic, dynamic>())
+@self::Class::•(const self::GenericClass::named<dynamic, dynamic>())
+static method type() → void
+  ;
+static method _#ComplexAlias#new#tearOff<unrelated X extends core::Object? = dynamic>([dynamic a]) → self::Class
+  return new self::Class::•(a);
+static method _#ComplexAlias#named#tearOff<unrelated X extends core::Object? = dynamic>({dynamic a, dynamic b}) → self::Class
+  return new self::Class::named(a: a, b: b);
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue55755.dart:19:2 -> InstanceConstant(const Class{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue55755.dart:20:2 -> InstanceConstant(const Class{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue55755.dart:21:2 -> InstanceConstant(const Class{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue55755.dart:22:2 -> InstanceConstant(const Class{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue55755.dart:23:2 -> InstanceConstant(const Class{})
+Extra constant evaluation: evaluated: 10, effectively constant: 5
diff --git a/pkg/front_end/testcases/general/issue55755.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue55755.dart.strong.transformed.expect
new file mode 100644
index 0000000..502c4a1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55755.dart.strong.transformed.expect
@@ -0,0 +1,47 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Alias = self::Class;
+typedef ComplexAlias<unrelated X extends core::Object? = dynamic> = self::Class;
+typedef GenericAlias<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = self::GenericClass<X%, Y%>;
+class Class extends core::Object /*hasConstConstructor*/  {
+  const constructor •([dynamic a = #C1]) → self::Class
+    : super core::Object::•()
+    ;
+  const constructor named({dynamic a = #C1, dynamic b = #C1}) → self::Class
+    : super core::Object::•()
+    ;
+}
+class GenericClass<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::GenericClass<self::GenericClass::X%, self::GenericClass::Y%>
+    : super core::Object::•()
+    ;
+  const constructor named({dynamic a = #C1, dynamic b = #C1}) → self::GenericClass<self::GenericClass::X%, self::GenericClass::Y%>
+    : super core::Object::•()
+    ;
+}
+@#C2
+@#C2
+@#C2
+@#C2
+@#C2
+static method type() → void {}
+static method _#ComplexAlias#new#tearOff<unrelated X extends core::Object? = dynamic>([dynamic a = #C1]) → self::Class
+  return new self::Class::•(a);
+static method _#ComplexAlias#named#tearOff<unrelated X extends core::Object? = dynamic>({dynamic a = #C1, dynamic b = #C1}) → self::Class
+  return new self::Class::named(a: a, b: b);
+
+constants  {
+  #C1 = null
+  #C2 = self::Class {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue55755.dart:
+- Class.named (from org-dartlang-testcase:///issue55755.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
+- Class. (from org-dartlang-testcase:///issue55755.dart:6:9)
+- GenericClass. (from org-dartlang-testcase:///issue55755.dart:11:9)
+- GenericClass.named (from org-dartlang-testcase:///issue55755.dart:12:9)
diff --git a/pkg/front_end/testcases/general/issue55755.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue55755.dart.textual_outline.expect
new file mode 100644
index 0000000..05922f2
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55755.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+class Class {
+  const Class([a]);
+  const Class.named({a, b});
+}
+
+class GenericClass<X, Y> {
+  const GenericClass();
+  const GenericClass.named({a, b});
+}
+
+typedef Alias = Class;
+
+typedef ComplexAlias<X> = Class;
+
+typedef GenericAlias<X, Y> = GenericClass<X, Y>;
+
+@Class(Alias.named())
+@Class(ComplexAlias())
+@Class(ComplexAlias.named())
+@Class(GenericAlias())
+@Class(GenericAlias.named())
+void type() {}
diff --git a/pkg/front_end/testcases/general/issue55755.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue55755.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05922f2
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55755.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+class Class {
+  const Class([a]);
+  const Class.named({a, b});
+}
+
+class GenericClass<X, Y> {
+  const GenericClass();
+  const GenericClass.named({a, b});
+}
+
+typedef Alias = Class;
+
+typedef ComplexAlias<X> = Class;
+
+typedef GenericAlias<X, Y> = GenericClass<X, Y>;
+
+@Class(Alias.named())
+@Class(ComplexAlias())
+@Class(ComplexAlias.named())
+@Class(GenericAlias())
+@Class(GenericAlias.named())
+void type() {}
diff --git a/pkg/front_end/testcases/general/issue55849.dart b/pkg/front_end/testcases/general/issue55849.dart
new file mode 100644
index 0000000..0ecf8a6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<X> {
+  const A.foo(X x);
+}
+
+typedef F<Y> = A<Y>;
+
+@F.foo("foo")
+void bar() {}
diff --git a/pkg/front_end/testcases/general/issue55849.dart.strong.expect b/pkg/front_end/testcases/general/issue55849.dart.strong.expect
new file mode 100644
index 0000000..150a660
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849.dart.strong.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<Y extends core::Object? = dynamic> = self::A<Y%>;
+class A<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor foo(self::A::X% x) → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+@#C1
+static method bar() → void {}
+
+constants  {
+  #C1 = self::A<core::String> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue55849.dart:
+- A.foo (from org-dartlang-testcase:///issue55849.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/issue55849.dart.strong.modular.expect b/pkg/front_end/testcases/general/issue55849.dart.strong.modular.expect
new file mode 100644
index 0000000..150a660
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849.dart.strong.modular.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<Y extends core::Object? = dynamic> = self::A<Y%>;
+class A<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor foo(self::A::X% x) → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+@#C1
+static method bar() → void {}
+
+constants  {
+  #C1 = self::A<core::String> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue55849.dart:
+- A.foo (from org-dartlang-testcase:///issue55849.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/issue55849.dart.strong.outline.expect b/pkg/front_end/testcases/general/issue55849.dart.strong.outline.expect
new file mode 100644
index 0000000..a073140
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849.dart.strong.outline.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<Y extends core::Object? = dynamic> = self::A<Y%>;
+class A<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor foo(self::A::X% x) → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+@self::A::foo<core::String>("foo")
+static method bar() → void
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue55849.dart:12:6 -> InstanceConstant(const A<String>{})
+Extra constant evaluation: evaluated: 1, effectively constant: 1
diff --git a/pkg/front_end/testcases/general/issue55849.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue55849.dart.strong.transformed.expect
new file mode 100644
index 0000000..150a660
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<Y extends core::Object? = dynamic> = self::A<Y%>;
+class A<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor foo(self::A::X% x) → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+@#C1
+static method bar() → void {}
+
+constants  {
+  #C1 = self::A<core::String> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue55849.dart:
+- A.foo (from org-dartlang-testcase:///issue55849.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/issue55849.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue55849.dart.textual_outline.expect
new file mode 100644
index 0000000..b34d156
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<X> {
+  const A.foo(X x);
+}
+
+typedef F<Y> = A<Y>;
+
+@F.foo("foo")
+void bar() {}
diff --git a/pkg/front_end/testcases/general/issue55849.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue55849.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b34d156
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A<X> {
+  const A.foo(X x);
+}
+
+typedef F<Y> = A<Y>;
+
+@F.foo("foo")
+void bar() {}
diff --git a/pkg/front_end/testcases/general/issue55849_2.dart b/pkg/front_end/testcases/general/issue55849_2.dart
new file mode 100644
index 0000000..fafc4f1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849_2.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  const A(int x);
+  const factory A.redir(int x) = A;
+}
+
+@A.redir(1)
+foo(@A.redir(2) String y) {
+  @A.redir(3) dynamic z;
+}
+
+main() {
+  () => (<@A.redir(0) T>() => null);
+}
diff --git a/pkg/front_end/testcases/general/issue55849_2.dart.strong.expect b/pkg/front_end/testcases/general/issue55849_2.dart.strong.expect
new file mode 100644
index 0000000..ae13b5a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849_2.dart.strong.expect
@@ -0,0 +1,28 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •(core::int x) → self::A
+    : super core::Object::•()
+    ;
+  static factory redir(core::int x) → self::A /* redirection-target: self::A::• */
+    return new self::A::•(x);
+}
+@#C1
+static method foo(@#C1 core::String y) → dynamic {
+  @#C1 dynamic z;
+}
+static method main() → dynamic {
+  () → <T extends core::Object? = dynamic>() → Null => <@#C1 T extends core::Object? = dynamic>() → Null => null;
+}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue55849_2.dart:
+- A. (from org-dartlang-testcase:///issue55849_2.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/issue55849_2.dart.strong.modular.expect b/pkg/front_end/testcases/general/issue55849_2.dart.strong.modular.expect
new file mode 100644
index 0000000..ae13b5a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849_2.dart.strong.modular.expect
@@ -0,0 +1,28 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •(core::int x) → self::A
+    : super core::Object::•()
+    ;
+  static factory redir(core::int x) → self::A /* redirection-target: self::A::• */
+    return new self::A::•(x);
+}
+@#C1
+static method foo(@#C1 core::String y) → dynamic {
+  @#C1 dynamic z;
+}
+static method main() → dynamic {
+  () → <T extends core::Object? = dynamic>() → Null => <@#C1 T extends core::Object? = dynamic>() → Null => null;
+}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue55849_2.dart:
+- A. (from org-dartlang-testcase:///issue55849_2.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/issue55849_2.dart.strong.outline.expect b/pkg/front_end/testcases/general/issue55849_2.dart.strong.outline.expect
new file mode 100644
index 0000000..a89931f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849_2.dart.strong.outline.expect
@@ -0,0 +1,21 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •(core::int x) → self::A
+    : super core::Object::•()
+    ;
+  static factory redir(core::int x) → self::A /* redirection-target: self::A::• */
+    return new self::A::•(x);
+}
+@self::A::•(1)
+static method foo(core::String y) → dynamic
+  ;
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue55849_2.dart:10:2 -> InstanceConstant(const A{})
+Extra constant evaluation: evaluated: 3, effectively constant: 1
diff --git a/pkg/front_end/testcases/general/issue55849_2.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue55849_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..ae13b5a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849_2.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •(core::int x) → self::A
+    : super core::Object::•()
+    ;
+  static factory redir(core::int x) → self::A /* redirection-target: self::A::• */
+    return new self::A::•(x);
+}
+@#C1
+static method foo(@#C1 core::String y) → dynamic {
+  @#C1 dynamic z;
+}
+static method main() → dynamic {
+  () → <T extends core::Object? = dynamic>() → Null => <@#C1 T extends core::Object? = dynamic>() → Null => null;
+}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue55849_2.dart:
+- A. (from org-dartlang-testcase:///issue55849_2.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/issue55849_2.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue55849_2.dart.textual_outline.expect
new file mode 100644
index 0000000..443c22b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849_2.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+  const A(int x);
+  const factory A.redir(int x) = A;
+}
+
+@A.redir(1)
+foo(@A.redir(2) String y) {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue55849_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue55849_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..443c22b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue55849_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+  const A(int x);
+  const factory A.redir(int x) = A;
+}
+
+@A.redir(1)
+foo(@A.redir(2) String y) {}
+
+main() {}