[cfe/ffi] Test `Finalizable`s in extension methods

`Finalizable`s with extension methods work by virtue of being
desugared into static methods and the `Finalizable`s being normal
arguments.

If we ever change the representation of extension methods,
`Finalizable`s would need to be treated specially. This test will
catch that.

TEST=pkg/vm/test/transformations/ffi_test.dart

Bug: https://github.com/dart-lang/sdk/issues/49643#issuecomment-1214847853

Change-Id: I68cfbc098386a88495d37417c6eb7295b89bfb95
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255123
Reviewed-by: Tess Strickland <sstrickl@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart b/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart
new file mode 100644
index 0000000..65e2d81
--- /dev/null
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2022, 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.16
+
+import 'dart:ffi';
+
+class Foo implements Finalizable {}
+
+void main() {
+  final foo = Foo();
+  foo.bar();
+  Object().baz(foo);
+}
+
+extension on Finalizable {
+  int bar() {
+    print('123');
+    // Should generate a fence for `this` before returning 4.
+    return 4;
+  }
+}
+
+extension on Object {
+  int baz(Foo foo) {
+    print('456');
+    // Should generate a fence for `foo` before returning 5.
+    return 5;
+  }
+}
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.expect b/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.expect
new file mode 100644
index 0000000..24ca399
--- /dev/null
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.expect
@@ -0,0 +1,59 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:ffi" as ffi;
+import "dart:_internal" as _in;
+
+import "dart:ffi";
+
+class Foo extends core::Object implements ffi::Finalizable {
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+}
+extension _extension#0 on ffi::Finalizable {
+  method bar = self::_extension#0|bar;
+  tearoff bar = self::_extension#0|get#bar;
+}
+extension _extension#1 on core::Object {
+  method baz = self::_extension#1|baz;
+  tearoff baz = self::_extension#1|get#baz;
+}
+static method main() → void {
+  final self::Foo foo = new self::Foo::•();
+  self::_extension#0|bar(foo);
+  self::_extension#1|baz(new core::Object::•(), foo);
+  _in::reachabilityFence(foo);
+}
+static method _extension#0|bar(lowered final ffi::Finalizable #this) → core::int {
+  core::print("123");
+  return block {
+    final core::int :expressionValueWrappedFinalizable = 4;
+    _in::reachabilityFence(#this);
+  } =>:expressionValueWrappedFinalizable;
+}
+static method _extension#0|get#bar(lowered final ffi::Finalizable #this) → () → core::int {
+  return block {
+    final () → core::int :expressionValueWrappedFinalizable = () → core::int {
+      return block {
+        final core::int :expressionValueWrappedFinalizable = self::_extension#0|bar(#this);
+        _in::reachabilityFence(#this);
+      } =>:expressionValueWrappedFinalizable;
+    };
+    _in::reachabilityFence(#this);
+  } =>:expressionValueWrappedFinalizable;
+}
+static method _extension#1|baz(lowered final core::Object #this, self::Foo foo) → core::int {
+  core::print("456");
+  return block {
+    final core::int :expressionValueWrappedFinalizable = 5;
+    _in::reachabilityFence(foo);
+  } =>:expressionValueWrappedFinalizable;
+}
+static method _extension#1|get#baz(lowered final core::Object #this) → (self::Foo) → core::int
+  return (self::Foo foo) → core::int {
+    return block {
+      final core::int :expressionValueWrappedFinalizable = self::_extension#1|baz(#this, foo);
+      _in::reachabilityFence(foo);
+    } =>:expressionValueWrappedFinalizable;
+  };