Version 2.17.0-209.0.dev

Merge commit '111101039b3a0f5363d3daca3e1458713feb4e6c' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart b/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart
index 5a96c10..ad5e78b 100644
--- a/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart
@@ -11,18 +11,55 @@
 set setter(_) => null;
 
 @ClassMacro()
-class Class1 {}
+class Class1 {
+  var field1;
+
+  Class1();
+}
 
 @ClassMacro()
 abstract class Class2 {}
 
 @ClassMacro()
-class Class3 extends Class2 {}
+class Class3 extends Class2 implements Interface1 {
+  var field1;
+  var field2;
 
-mixin Mixin {}
+  Class3.new();
+  Class3.named();
+  factory Class3.fact() => Class3.named();
+  factory Class3.redirect() = Class3.named;
+
+  void method1() {}
+  void method2() {}
+
+  get getter1 => null;
+  set setter1(_) {}
+
+  get property1 => null;
+  set property1(_) {}
+
+  static var staticField1;
+  static void staticMethod1() {}
+}
 
 @ClassMacro()
-class Class4 extends Class1 with Mixin {}
+class Class4 extends Class1 with Mixin1 {}
+
+@ClassMacro()
+class Class5 extends Class2
+    with Mixin1, Mixin2
+    implements Interface1, Interface2 {}
+
+mixin Mixin1 {}
+
+mixin Mixin2 {}
+
+@ClassMacro()
+abstract class Interface1 {}
+
+@ClassMacro()
+abstract class Interface2 {}
 
 @FunctionMacro()
 void topLevelFunction1(Class1 a, {Class1? b, required Class2? c}) {}
diff --git a/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart b/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
index c826563..fcbb437 100644
--- a/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
@@ -5,10 +5,50 @@
 import 'package:_fe_analyzer_shared/src/macros/api.dart';
 
 const Map<String, ClassData> expectedClassData = {
-  'Class1': ClassData(superclassOf: 'Object'),
+  'Class1': ClassData(
+      superclassOf: 'Object', fieldsOf: ['field1'], constructorsOf: ['']),
   'Class2': ClassData(isAbstract: true, superclassOf: 'Object'),
-  'Class3': ClassData(superclassOf: 'Class2', superSuperclassOf: 'Object'),
-  'Class4': ClassData(superclassOf: 'Class1', superSuperclassOf: 'Object'),
+  'Class3': ClassData(
+      superclassOf: 'Class2',
+      superSuperclassOf: 'Object',
+      interfacesOf: [
+        'Interface1'
+      ],
+      // TODO(johnniwinther): Should we require a specific order?
+      fieldsOf: [
+        'field1',
+        'field2',
+        'staticField1',
+      ],
+      // TODO(johnniwinther): Should we require a specific order?
+      methodsOf: [
+        'method1',
+        'method2',
+        'getter1',
+        'property1',
+        'staticMethod1',
+        'setter1',
+        'property1',
+      ],
+      // TODO(johnniwinther): Should we require a specific order?
+      constructorsOf: [
+        // TODO(johnniwinther): Should we normalize no-name constructor names?
+        '',
+        'named',
+        'fact',
+        'redirect',
+      ]),
+  'Class4': ClassData(
+      superclassOf: 'Class1',
+      superSuperclassOf: 'Object',
+      mixinsOf: ['Mixin1']),
+  'Class5': ClassData(
+      superclassOf: 'Class2',
+      superSuperclassOf: 'Object',
+      mixinsOf: ['Mixin1', 'Mixin2'],
+      interfacesOf: ['Interface1', 'Interface2']),
+  'Interface1': ClassData(isAbstract: true, superclassOf: 'Object'),
+  'Interface2': ClassData(isAbstract: true, superclassOf: 'Object'),
 };
 
 const Map<String, FunctionData> expectedFunctionData = {
@@ -90,6 +130,49 @@
         expect(expected.superSuperclassOf, superSuperclassOf?.identifier.name,
             '$name.superSuperclassOf');
       }
+      List<ClassDeclaration> mixinsOf =
+          await classIntrospector.mixinsOf(declaration);
+      expect(
+          expected.mixinsOf.length, mixinsOf.length, '$name.mixinsOf.length');
+      for (int i = 0; i < mixinsOf.length; i++) {
+        expect(expected.mixinsOf[i], mixinsOf[i].identifier.name,
+            '$name.mixinsOf[$i]');
+      }
+      List<ClassDeclaration> interfacesOf =
+          await classIntrospector.interfacesOf(declaration);
+      expect(expected.interfacesOf.length, interfacesOf.length,
+          '$name.interfacesOf.length');
+      for (int i = 0; i < interfacesOf.length; i++) {
+        expect(expected.interfacesOf[i], interfacesOf[i].identifier.name,
+            '$name.interfacesOf[$i]');
+      }
+
+      List<FieldDeclaration> fieldsOf =
+          await classIntrospector.fieldsOf(declaration);
+      expect(
+          expected.fieldsOf.length, fieldsOf.length, '$name.fieldsOf.length');
+      for (int i = 0; i < fieldsOf.length; i++) {
+        expect(expected.fieldsOf[i], fieldsOf[i].identifier.name,
+            '$name.fieldsOf[$i]');
+      }
+
+      List<MethodDeclaration> methodsOf =
+          await classIntrospector.methodsOf(declaration);
+      expect(expected.methodsOf.length, methodsOf.length,
+          '$name.methodsOf.length');
+      for (int i = 0; i < methodsOf.length; i++) {
+        expect(expected.methodsOf[i], methodsOf[i].identifier.name,
+            '$name.methodsOf[$i]');
+      }
+
+      List<ConstructorDeclaration> constructorsOf =
+          await classIntrospector.constructorsOf(declaration);
+      expect(expected.constructorsOf.length, constructorsOf.length,
+          '$name.constructorsOf.length');
+      for (int i = 0; i < constructorsOf.length; i++) {
+        expect(expected.constructorsOf[i], constructorsOf[i].identifier.name,
+            '$name.constructorsOf[$i]');
+      }
     }
     // TODO(johnniwinther): Test more properties when there are supported.
   } else {
@@ -166,12 +249,22 @@
   final bool isExternal;
   final String superclassOf;
   final String? superSuperclassOf;
+  final List<String> interfacesOf;
+  final List<String> mixinsOf;
+  final List<String> fieldsOf;
+  final List<String> methodsOf;
+  final List<String> constructorsOf;
 
   const ClassData(
       {this.isAbstract: false,
       this.isExternal: false,
       required this.superclassOf,
-      this.superSuperclassOf});
+      this.superSuperclassOf,
+      this.interfacesOf: const [],
+      this.mixinsOf: const [],
+      this.fieldsOf: const [],
+      this.methodsOf: const [],
+      this.constructorsOf: const []});
 }
 
 class FunctionData {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
index f989538..088e4bf 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix.dart';
-import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -126,9 +125,7 @@
   new M(3);
 }
 ''');
-    await assertNoFix(
-        errorFilter: (error) =>
-            error.errorCode != CompileTimeErrorCode.MIXIN_INSTANTIATE);
+    await assertNoFix();
   }
 
   Future<void> test_named() async {
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 18a8a06..c27ae0c 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -1118,7 +1118,7 @@
       _visitPropertyFirst<FieldDeclaration>(node.members);
     });
 
-    if (holder.constructors.isEmpty) {
+    if (node is ClassDeclaration && holder.constructors.isEmpty) {
       holder.addConstructor(
         ConstructorElementImpl('', -1)..isSynthetic = true,
       );
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index 716f124..88d2563 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -101,7 +101,11 @@
     );
 
     newFile2('/workspace/WORKSPACE', '');
-    newFile2('/workspace/dart/test/BUILD', '');
+    newFile2('/workspace/dart/test/BUILD', r'''
+dart_package(
+  null_safety = True,
+)
+''');
     createFileResolver();
   }
 
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 4ac48f7..ab875d7 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -76,13 +76,12 @@
 
     newFile2(bPath, r'''
 import 'a.dart';
-A a;
-B b;
+void f(A a, B b) {}
 ''');
 
     result = await resolveFile(bPath);
     assertErrorsInResolvedUnit(result, [
-      error(CompileTimeErrorCode.UNDEFINED_CLASS, 22, 1),
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 29, 1),
     ]);
 
     newFile2(aPath, r'''
@@ -222,7 +221,7 @@
 @reflectiveTest
 class FileResolverTest extends FileResolutionTest {
   @override
-  bool isNullSafetyEnabled = false;
+  bool get isNullSafetyEnabled => true;
 
   test_analysisOptions_default_fromPackageUri() async {
     newFile2('/workspace/dart/analysis_options/lib/default.yaml', r'''
@@ -317,13 +316,6 @@
     ]);
   }
 
-  test_analysisOptions_no() async {
-    await assertNoErrorsInCode(r'''
-num a = 0;
-int b = a;
-''');
-  }
-
   test_basic() async {
     await assertNoErrorsInCode(r'''
 int a = 0;
@@ -908,14 +900,6 @@
   }
 
   test_nullSafety_enabled() async {
-    isNullSafetyEnabled = true;
-
-    newFile2('/workspace/dart/test/BUILD', r'''
-dart_package(
-  null_safety = True,
-)
-''');
-
     await assertNoErrorsInCode(r'''
 void f(int? a) {
   if (a != null) {
@@ -931,7 +915,7 @@
   }
 
   test_nullSafety_notEnabled() async {
-    isNullSafetyEnabled = true;
+    newFile2('/workspace/dart/test/BUILD', '');
 
     await assertErrorsInCode(r'''
 void f(int? a) {}
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_instantiate_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_instantiate_test.dart
index 7bcc0e2..665bf45 100644
--- a/pkg/analyzer/test/src/diagnostics/mixin_instantiate_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mixin_instantiate_test.dart
@@ -92,7 +92,7 @@
         staticElement: self::@mixin::M
         staticType: null
       type: M
-    staticElement: self::@mixin::M::@constructor::•
+    staticElement: <null>
   argumentList: ArgumentList
     leftParenthesis: (
     rightParenthesis: )
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 43204fb..47a6243 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -308,8 +308,12 @@
       _writeElements('fields', e.fields, _writePropertyInducingElement);
 
       var constructors = e.constructors;
-      expect(constructors, isNotEmpty);
-      _writeElements('constructors', constructors, _writeConstructorElement);
+      if (e.isMixin) {
+        expect(constructors, isEmpty);
+      } else {
+        expect(constructors, isNotEmpty);
+        _writeElements('constructors', constructors, _writeConstructorElement);
+      }
 
       _writeElements('accessors', e.accessors, _writePropertyAccessorElement);
       _writeElements('methods', e.methods, _writeMethodElement);
diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart
index c9ce53b..f96b17d 100644
--- a/pkg/analyzer/test/src/summary/elements_test.dart
+++ b/pkg/analyzer/test/src/summary/elements_test.dart
@@ -16819,8 +16819,6 @@
       mixin M @68
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -17105,16 +17103,12 @@
       mixin A @6
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
       mixin A @17
         superclassConstraints
           Object
         fields
           x @27
             type: dynamic
-        constructors
-          synthetic @-1
         accessors
           synthetic get x @-1
             returnType: dynamic
@@ -17129,8 +17123,6 @@
         fields
           y @48
             type: int
-        constructors
-          synthetic @-1
         accessors
           synthetic get y @-1
             returnType: int
@@ -18687,8 +18679,6 @@
       mixin M @6
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -18752,16 +18742,12 @@
             defaultType: dynamic
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
       mixin M2 @21
         typeParameters
           covariant T @24
             defaultType: dynamic
         superclassConstraints
           M1<T>
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -21710,8 +21696,6 @@
             defaultType: void Function()
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -21751,8 +21735,6 @@
       mixin M @20
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -26006,8 +25988,6 @@
       mixin B @38
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -26341,8 +26321,6 @@
       mixin B @32
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -28020,8 +27998,6 @@
       mixin M @38
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
         methods
           m @54
             metadata
@@ -28150,8 +28126,6 @@
               IntegerLiteral
                 literal: 1 @60
                 staticType: int
-        constructors
-          synthetic @-1
         accessors
           synthetic static get foo @-1
             returnType: int
@@ -28208,8 +28182,6 @@
             element: self::@getter::b
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
     topLevelVariables
       static const a @6
         type: dynamic
@@ -28537,8 +28509,6 @@
       mixin M @33
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
     topLevelVariables
       static const foo @6
         type: int
@@ -28885,8 +28855,6 @@
                 element: self::@getter::foo
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
     topLevelVariables
       static const foo @6
         type: int
@@ -30147,8 +30115,6 @@
             type: U
           synthetic s @-1
             type: int
-        constructors
-          synthetic @-1
         accessors
           synthetic get f @-1
             returnType: T
@@ -30188,8 +30154,6 @@
         fields
           final x @18
             type: int
-        constructors
-          synthetic @-1
         accessors
           synthetic get x @-1
             returnType: int
@@ -30219,8 +30183,6 @@
       mixin M @6
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -30257,8 +30219,6 @@
             defaultType: dynamic
         superclassConstraints
           A<U*>*
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -30294,8 +30254,6 @@
             defaultType: dynamic
         superclassConstraints
           A<U>
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -30397,8 +30355,6 @@
       mixin B @17
         superclassConstraints
           A
-        constructors
-          synthetic @-1
         methods
           A @33
             returnType: void
@@ -30417,8 +30373,6 @@
             defaultType: dynamic
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -30434,8 +30388,6 @@
             defaultType: dynamic
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -30451,8 +30403,6 @@
             defaultType: dynamic
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -30472,8 +30422,6 @@
             defaultType: dynamic
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -30878,8 +30826,6 @@
             defaultType: dynamic
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -31383,9 +31329,6 @@
           foo @16
             type: int
             nonSynthetic: self::@mixin::M::@field::foo
-        constructors
-          synthetic @-1
-            nonSynthetic: self::@mixin::M
         accessors
           synthetic get foo @-1
             returnType: int
@@ -31420,9 +31363,6 @@
           synthetic foo @-1
             type: int
             nonSynthetic: self::@mixin::M::@getter::foo
-        constructors
-          synthetic @-1
-            nonSynthetic: self::@mixin::M
         accessors
           get foo @20
             returnType: int
@@ -31450,9 +31390,6 @@
           synthetic foo @-1
             type: int
             nonSynthetic: self::@mixin::M::@setter::foo
-        constructors
-          synthetic @-1
-            nonSynthetic: self::@mixin::M
         accessors
           set foo @16
             parameters
@@ -32730,8 +32667,6 @@
       mixin M @112
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 
@@ -35948,13 +35883,9 @@
       mixin M1 @41
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
       mixin M2 @53
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
     typeAliases
       X @8
         aliasedType: A<int>?
@@ -35992,13 +35923,9 @@
       mixin M1 @41
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
       mixin M2 @53
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
     typeAliases
       X @8
         aliasedType: A<int?>
diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart
index 1495f4e..be36b5a 100644
--- a/pkg/analyzer/test/src/summary/macro_test.dart
+++ b/pkg/analyzer/test/src/summary/macro_test.dart
@@ -70,8 +70,6 @@
       mixin M @6
         superclassConstraints
           Object
-        constructors
-          synthetic @-1
 ''');
   }
 }
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index 39e5ea4..94b0141 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -222,8 +222,6 @@
       final bool debugDds = args['debug-dds'];
 
       bool disableServiceAuthCodes = args['disable-service-auth-codes'];
-      final bool enableServicePortFallback =
-          args['enable-service-port-fallback'];
 
       // If the user wants to start a debugging session we need to do some extra
       // work and spawn a Dart Development Service (DDS) instance. DDS is a VM
@@ -239,7 +237,6 @@
           disableServiceAuthCodes,
           launchDevTools,
           debugDds,
-          enableServicePortFallback,
         )) {
           return errorExitCode;
         }
@@ -277,7 +274,6 @@
     bool disableServiceAuthCodes,
     bool enableDevTools,
     bool debugDds,
-    bool enableServicePortFallback,
   ) async {
     final sdkDir = dirname(sdk.dart);
     final fullSdk = sdkDir.endsWith('bin');
@@ -307,7 +303,6 @@
         enableDevTools.toString(),
         devToolsBinaries,
         debugDds.toString(),
-        enableServicePortFallback.toString(),
       ],
       mode: ProcessStartMode.detachedWithStdio,
     );
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index bf0f031..40978d9 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -333,25 +333,6 @@
     expect(result.exitCode, 0);
   });
 
-  test('--enable-service-port-fallback', () async {
-    final p = project(mainSrc: '''void main() {}''');
-    final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
-    final result = await p.run(
-      [
-        'run',
-        '--enable-vm-service=${server.port}',
-        '--enable-service-port-fallback',
-        p.relativeFilePath,
-      ],
-    );
-    final regexp = RegExp(
-        r'Observatory listening on http:\/\/127.0.0.1:(\d*)\/[a-zA-Z0-9_-]+=\/\n.*');
-    final vmServicePort =
-        int.parse(regexp.firstMatch(result.stdout)!.group(1)!);
-    expect(server.port != vmServicePort, isTrue);
-    await server.close();
-  });
-
   test('without verbose CFE info', () async {
     final p = project(mainSrc: '''void main() {}''');
 
diff --git a/pkg/dds/bin/dds.dart b/pkg/dds/bin/dds.dart
index 7e43c19..2ae2f5a 100644
--- a/pkg/dds/bin/dds.dart
+++ b/pkg/dds/bin/dds.dart
@@ -18,7 +18,6 @@
 ///   - Start DevTools
 ///   - DevTools build directory
 ///   - Enable logging
-///   - Enable service port fallback
 Future<void> main(List<String> args) async {
   if (args.isEmpty) return;
 
@@ -47,7 +46,6 @@
     devToolsBuildDirectory = Uri.file(args[5]);
   }
   final logRequests = args[6] == 'true';
-  final enableServicePortFallback = args[7] == 'true';
   try {
     // TODO(bkonyi): add retry logic similar to that in vmservice_server.dart
     // See https://github.com/dart-lang/sdk/issues/43192.
@@ -63,7 +61,6 @@
             )
           : null,
       logRequests: logRequests,
-      enableServicePortFallback: enableServicePortFallback,
     );
     stderr.write(json.encode({
       'state': 'started',
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index 7d833ab..4d8a5e7 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.dart
@@ -37,15 +37,11 @@
   ///
   /// [ipv6] controls whether or not DDS is served via IPv6. IPv4 is enabled by
   /// default.
-  ///
-  /// If [enablesServicePortFallback] is enabled, DDS will attempt to bind to any
-  /// available port if the specified port is unavailable.
   static Future<DartDevelopmentService> startDartDevelopmentService(
     Uri remoteVmServiceUri, {
     Uri? serviceUri,
     bool enableAuthCodes = true,
     bool ipv6 = false,
-    bool enableServicePortFallback = false,
     List<String> cachedUserTags = const [],
     DevToolsConfiguration? devToolsConfiguration,
     bool logRequests = false,
@@ -88,7 +84,6 @@
       ipv6,
       devToolsConfiguration,
       logRequests,
-      enableServicePortFallback,
     );
     await service.startService();
     return service;
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index 8de53ff..000a15b 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -59,7 +59,6 @@
     this._ipv6,
     this._devToolsConfiguration,
     this.shouldLogRequests,
-    this._enableServicePortFallback,
   ) {
     _clientManager = ClientManager(this);
     _expressionEvaluator = ExpressionEvaluator(this);
@@ -137,7 +136,7 @@
     final host = uri?.host ??
         (_ipv6 ? InternetAddress.loopbackIPv6 : InternetAddress.loopbackIPv4)
             .host;
-    var port = uri?.port ?? 0;
+    final port = uri?.port ?? 0;
     var pipeline = const Pipeline();
     if (shouldLogRequests) {
       pipeline = pipeline.addMiddleware(
@@ -156,25 +155,16 @@
     late String errorMessage;
     final tmpServer = await runZonedGuarded(
       () async {
-        Future<HttpServer?> startServer() async {
-          try {
-            return await io.serve(handler, host, port);
-          } on SocketException catch (e) {
-            if (_enableServicePortFallback && port != 0) {
-              // Try again, this time with a random port.
-              port = 0;
-              return await startServer();
-            }
-            errorMessage = e.message;
-            if (e.osError != null) {
-              errorMessage += ' (${e.osError!.message})';
-            }
-            errorMessage += ': ${e.address?.host}:${e.port}';
-            return null;
+        try {
+          return await io.serve(handler, host, port);
+        } on SocketException catch (e) {
+          errorMessage = e.message;
+          if (e.osError != null) {
+            errorMessage += ' (${e.osError!.message})';
           }
+          errorMessage += ': ${e.address?.host}:${e.port}';
+          return null;
         }
-
-        return await startServer();
       },
       (error, stack) {
         if (shouldLogRequests) {
@@ -397,7 +387,6 @@
   String? get authCode => _authCode;
   String? _authCode;
 
-  final bool _enableServicePortFallback;
   final bool shouldLogRequests;
 
   Uri get remoteVmServiceUri => _remoteVmServiceUri;
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/hierarchy_node.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/hierarchy_node.dart
index 2bd09ac..9756c9d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/hierarchy_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/hierarchy_node.dart
@@ -51,10 +51,11 @@
     List<Supertype> interfacesList;
     int maxInheritancePath;
 
+    ClassHierarchyNode? mixedInNode;
     List<ClassHierarchyNode>? interfaceNodes;
 
     if (classBuilder.isMixinApplication) {
-      inferMixinApplication();
+      mixedInNode = inferMixinApplication();
     }
 
     if (supernode == null) {
@@ -164,8 +165,8 @@
       }
     }
 
-    return new ClassHierarchyNode(classBuilder, supernode, interfaceNodes,
-        superclasses, interfacesList, maxInheritancePath);
+    return new ClassHierarchyNode(classBuilder, supernode, mixedInNode,
+        interfaceNodes, superclasses, interfacesList, maxInheritancePath);
   }
 
   Supertype recordSupertype(Supertype supertype) {
@@ -275,12 +276,16 @@
     interfaces[type.classNode] = type;
   }
 
-  void inferMixinApplication() {
+  ClassHierarchyNode? inferMixinApplication() {
     Class cls = classBuilder.cls;
     Supertype? mixedInType = cls.mixedInType;
-    if (mixedInType == null) return;
+    if (mixedInType == null) return null;
+    ClassHierarchyNode? mixinNode =
+        hierarchy.getNodeFromClass(mixedInType.classNode);
     List<DartType> typeArguments = mixedInType.typeArguments;
-    if (typeArguments.isEmpty || typeArguments.first is! UnknownType) return;
+    if (typeArguments.isEmpty || typeArguments.first is! UnknownType) {
+      return mixinNode;
+    }
     new BuilderMixinInferrer(
             classBuilder,
             hierarchy.coreTypes,
@@ -294,6 +299,7 @@
     NamedTypeBuilder mixedInTypeBuilder =
         classBuilder.mixedInTypeBuilder as NamedTypeBuilder;
     mixedInTypeBuilder.arguments = inferredArguments;
+    return mixinNode;
   }
 
   /// The class Function from dart:core is supposed to be ignored when used as
@@ -324,6 +330,10 @@
   /// `null` if this is `Object`.
   final ClassHierarchyNode? directSuperClassNode;
 
+  /// The [ClassHierarchyNode] for the mixed in class, if [classBuilder] is a
+  /// mixin application, or `null` otherwise;
+  final ClassHierarchyNode? mixedInNode;
+
   /// The [ClassHierarchyNode]s for the direct super interfaces of
   /// [classBuilder].
   final List<ClassHierarchyNode>? directInterfaceNodes;
@@ -344,11 +354,17 @@
   ClassHierarchyNode(
       this.classBuilder,
       this.directSuperClassNode,
+      this.mixedInNode,
       this.directInterfaceNodes,
       this.superclasses,
       this.interfaces,
       this.maxInheritancePath);
 
+  /// Returns `true` if [classBuilder] is a mixin application.
+  ///
+  /// If `true`, [mixedInNode] is non-null.
+  bool get isMixinApplication => mixedInNode != null;
+
   /// Returns a list of all supertypes of [classBuilder], including this node.
   List<ClassHierarchyNode> computeAllSuperNodes(
       ClassHierarchyBuilder hierarchy) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart
index 8779439..738e753 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart
@@ -864,10 +864,7 @@
         // TODO(johnniwinther): Should we support synthesized constructors?
         result.add(macroApplications._getMemberDeclaration(memberBuilder)
             as macro.ConstructorDeclaration);
-      }
-    });
-    classBuilder.forEach((_, Builder memberBuilder) {
-      if (memberBuilder is SourceFactoryBuilder) {
+      } else if (memberBuilder is SourceFactoryBuilder) {
         result.add(macroApplications._getMemberDeclaration(memberBuilder)
             as macro.ConstructorDeclaration);
       }
@@ -891,8 +888,19 @@
   @override
   Future<List<macro.ClassDeclaration>> interfacesOf(
       macro.ClassDeclaration clazz) {
-    // TODO: implement interfacesOf
-    throw new UnimplementedError('_ClassIntrospector.interfacesOf');
+    ClassBuilder classBuilder = macroApplications._getClassBuilder(clazz);
+    ClassHierarchyNode node =
+        classHierarchy.getNodeFromClassBuilder(classBuilder);
+    List<ClassHierarchyNode>? directInterfaceNodes = node.directInterfaceNodes;
+    if (directInterfaceNodes != null) {
+      List<macro.ClassDeclaration> list = [];
+      for (ClassHierarchyNode interfaceNode in directInterfaceNodes) {
+        list.add(
+            macroApplications._getClassDeclaration(interfaceNode.classBuilder));
+      }
+      return new Future.value(list);
+    }
+    return new Future.value(const []);
   }
 
   @override
@@ -911,8 +919,17 @@
 
   @override
   Future<List<macro.ClassDeclaration>> mixinsOf(macro.ClassDeclaration clazz) {
-    // TODO: implement mixinsOf
-    throw new UnimplementedError('_ClassIntrospector.mixinsOf');
+    ClassBuilder classBuilder = macroApplications._getClassBuilder(clazz);
+    ClassHierarchyNode node =
+        classHierarchy.getNodeFromClassBuilder(classBuilder);
+    ClassHierarchyNode? superNode = node.directSuperClassNode;
+    List<macro.ClassDeclaration>? list;
+    while (superNode != null && superNode.isMixinApplication) {
+      (list ??= []).add(macroApplications
+          ._getClassDeclaration(superNode.mixedInNode!.classBuilder));
+      superNode = superNode.directSuperClassNode;
+    }
+    return new Future.value(list?.reversed.toList() ?? const []);
   }
 
   @override
diff --git a/pkg/front_end/test/macros/application/data/tests/declarations.dart b/pkg/front_end/test/macros/application/data/tests/declarations.dart
index a225e74..a172251 100644
--- a/pkg/front_end/test/macros/application/data/tests/declarations.dart
+++ b/pkg/front_end/test/macros/application/data/tests/declarations.dart
@@ -56,7 +56,7 @@
 void Class1GeneratedMethod_() {}
 
 void Class1Introspection() {
-  print("constructors=''");
+  print("constructors='','redirect','fact'");
   print("fields='instanceField1','instanceField2','instanceField3'");
   print("methods='instanceMethod1','instanceGetter1','[]','instanceSetter1'");
 }
diff --git a/pkg/front_end/test/macros/application/data/tests/declarations.dart.expect b/pkg/front_end/test/macros/application/data/tests/declarations.dart.expect
index 27bb5b1..215ac30 100644
--- a/pkg/front_end/test/macros/application/data/tests/declarations.dart.expect
+++ b/pkg/front_end/test/macros/application/data/tests/declarations.dart.expect
@@ -81,7 +81,7 @@
 static method /* from org-dartlang-augmentation:/a/b/c/main.dart-7 */ topLevelSetter1GeneratedMethod_s() → void {}
 static method /* from org-dartlang-augmentation:/a/b/c/main.dart-8 */ Class1GeneratedMethod_() → void {}
 static method /* from org-dartlang-augmentation:/a/b/c/main.dart-9 */ Class1Introspection() → void {
-  core::print("constructors=''");
+  core::print("constructors='','redirect','fact'");
   core::print("fields='instanceField1','instanceField2','instanceField3'");
   core::print("methods='instanceMethod1','instanceGetter1','[]','instanceSetter1'");
 }
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 7cb1c3f..83c1408 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -666,10 +666,6 @@
         if (implicitly_use_dart_dev && Options::vm_service_auth_disabled()) {
           dart_options->AddArgument("--disable-service-auth-codes");
         }
-        if (implicitly_use_dart_dev &&
-            Options::enable_service_port_fallback()) {
-          dart_options->AddArgument("--enable-service-port-fallback");
-        }
       }
       first_option = false;
     }
diff --git a/sdk/lib/_internal/vm/bin/vmservice_io.dart b/sdk/lib/_internal/vm/bin/vmservice_io.dart
index 033a9cf..3df0e4c 100644
--- a/sdk/lib/_internal/vm/bin/vmservice_io.dart
+++ b/sdk/lib/_internal/vm/bin/vmservice_io.dart
@@ -103,7 +103,6 @@
         enableDevTools.toString(),
         devToolsBinaries,
         enableLogging.toString(),
-        _enableServicePortFallback.toString(),
       ],
       mode: ProcessStartMode.detachedWithStdio,
     );
diff --git a/sdk/lib/_internal/vm/bin/vmservice_server.dart b/sdk/lib/_internal/vm/bin/vmservice_server.dart
index 0cdf1f2..c8e61b2 100644
--- a/sdk/lib/_internal/vm/bin/vmservice_server.dart
+++ b/sdk/lib/_internal/vm/bin/vmservice_server.dart
@@ -409,8 +409,11 @@
       // Already running.
       return this;
     }
+
     // Startup HTTP server.
-    Future<void> startServer() async {
+    var pollError;
+    var pollStack;
+    Future<bool> poll() async {
       try {
         var address;
         var addresses = await InternetAddress.lookup(_ip);
@@ -420,22 +423,33 @@
           if (address.type == InternetAddressType.IPv4) break;
         }
         _server = await HttpServer.bind(address, _port);
+        return true;
       } catch (e, st) {
-        if (_port != 0 && _enableServicePortFallback) {
-          serverPrint('Failed to bind Observatory HTTP server to port $_port. '
-              'Falling back to automatic port selection');
-          _port = 0;
-          await startServer();
-        } else {
-          serverPrint('Could not start Observatory HTTP server:\n'
-              '$e\n$st');
-          _notifyServerState('');
-          onServerAddressChange(null);
-        }
+        pollError = e;
+        pollStack = st;
+        return false;
       }
     }
 
-    await startServer();
+    // poll for the network for ~10 seconds.
+    int attempts = 0;
+    final maxAttempts = 10;
+    while (!await poll()) {
+      attempts++;
+      serverPrint('Observatory server failed to start after $attempts tries');
+      if (attempts > maxAttempts) {
+        serverPrint('Could not start Observatory HTTP server:\n'
+            '$pollError\n$pollStack\n');
+        _notifyServerState('');
+        onServerAddressChange(null);
+        return this;
+      }
+      if (_port != 0 && _enableServicePortFallback && attempts >= 3) {
+        _port = 0;
+        serverPrint('Falling back to automatic port selection');
+      }
+      await Future<void>.delayed(const Duration(seconds: 1));
+    }
     if (_service.isExiting) {
       serverPrint('Observatory HTTP server exiting before listening as '
           'vm service has received exit request\n');
diff --git a/tools/VERSION b/tools/VERSION
index 90afb1e..4471376 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 208
+PRERELEASE 209
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index adbceae..cf5a954 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -1776,6 +1776,29 @@
     },
     {
       "builders": [
+        "vm-kernel-msvc-windows"
+      ],
+      "meta": {
+        "description": "This configuration builds the VM with MSVC."
+      },
+      "steps": [
+        {
+          "name": "build dart x64",
+          "script": "tools/build.py",
+          "arguments": [
+            "--mode=all",
+            "--arch=x64",
+            "--no-clang",
+            "--no-goma",
+            "dart_precompiled_runtime",
+            "gen_snapshot",
+            "runtime"
+          ]
+        }
+      ]
+    },
+    {
+      "builders": [
         "vm-kernel-linux-debug-simarm",
         "vm-kernel-linux-debug-simarm64",
         "vm-kernel-linux-debug-simarm64c",
@@ -4175,4 +4198,4 @@
     "macos": "buildtools/mac-x64/clang/bin/llvm-symbolizer",
     "windows": "buildtools/win-x64/clang/bin/llvm-symbolizer.exe"
   }
-}
+}
\ No newline at end of file