[ddc] Ensure mixin class is emitted before use

Moves the class definition to appear before uses in compiled
code.

Change-Id: I00558040a510c7bc8668794b82fa3bd67dde64e9
Fixes: https://github.com/dart-lang/sdk/issues/47645
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220071
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index ba81acf..131d308 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1124,6 +1124,7 @@
     for (var i = 0; i < mixinApplications.length; i++) {
       var m = mixinApplications[i];
       var mixinClass = m.isAnonymousMixin ? m.mixedInClass : m;
+      _declareBeforeUse(mixinClass);
       var mixinType =
           _hierarchy.getClassAsInstanceOf(c, mixinClass).asInterfaceType;
       var mixinName =
diff --git a/tests/language/mixin/regress_47645_test.dart b/tests/language/mixin/regress_47645_test.dart
new file mode 100644
index 0000000..4482a73
--- /dev/null
+++ b/tests/language/mixin/regress_47645_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, 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.
+
+import "package:expect/expect.dart";
+
+// Regression test for https://github.com/dart-lang/sdk/issues/47645.
+// To reproduce the issue the class declaration must appear before the mixin
+// declaration.
+class C<T> with M<C<T>> {}
+
+mixin M<T> {
+  bool fn() => true;
+}
+
+void main() {
+  var c = C<int>();
+  Expect.isTrue(c.fn());
+}
diff --git a/tests/language_2/mixin/regress_47645_test.dart b/tests/language_2/mixin/regress_47645_test.dart
new file mode 100644
index 0000000..27885e9
--- /dev/null
+++ b/tests/language_2/mixin/regress_47645_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, 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.
+
+// @dart = 2.9
+
+import "package:expect/expect.dart";
+
+// Regression test for https://github.com/dart-lang/sdk/issues/47645.
+// To reproduce the issue the class declaration must appear before the mixin
+// declaration.
+class C<T> with M<C<T>> {}
+
+mixin M<T> {
+  bool fn() => true;
+}
+
+void main() {
+  var c = C<int>();
+  Expect.isTrue(c.fn());
+}