#1260: Finalizer tests updated.
diff --git a/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/detach_A01_t01.dart b/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/detach_A01_t01.dart
new file mode 100644
index 0000000..b1a0744
--- /dev/null
+++ b/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/detach_A01_t01.dart
@@ -0,0 +1,58 @@
+// 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.
+
+/// @assertion void detach(
+/// Object detachToken
+// )
+/// Detaches the finalizer from values attached with [detachToken].
+///
+/// Each attachment between this finalizer and a value, which was created by
+/// calling [attach] with the [detachToken] object as [detach] argument, is
+/// removed.
+///
+/// @description Checks that all attacments for the given token get removed
+/// after the [detach] call.
+/// @author iarkh@unipro.ru
+
+import "../../gc_utils_lib.dart";
+import "../../../../Utils/expect.dart";
+
+class Nonce {
+ final int value;
+ Nonce(this.value);
+}
+
+final finalizerTokens = <Nonce>{};
+
+final Finalizer finalizer = Finalizer((token) {
+ finalizerTokens.add(token);
+});
+
+@pragma('vm:never-inline')
+void test() {
+ Object object1 = Object();
+ Object object2 = Object();
+ List<int> object3 = List.filled(100, 1);
+ List object4 = List.filled(200, "abc");
+ Nonce object5 = Nonce(14);
+
+ Object finalizationToken = Nonce(1);
+
+ finalizer.attach(object1, "object1", detach: finalizationToken);
+ finalizer.attach(object2, "object2", detach: finalizationToken);
+ finalizer.attach(object3, "object3", detach: finalizationToken);
+ finalizer.attach(object4, "object4", detach: finalizationToken);
+ finalizer.attach(object5, "object5", detach: finalizationToken);
+ finalizer.detach(finalizationToken);
+}
+
+main() async {
+ test();
+ await triggerGcWithDelay();
+ Expect.setEquals({}, finalizerTokens);
+ await triggerGcWithDelay();
+ Expect.setEquals({}, finalizerTokens);
+ await triggerGcWithDelay();
+ Expect.setEquals({}, finalizerTokens);
+}
diff --git a/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/detach_A01_t02.dart b/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/detach_A01_t02.dart
new file mode 100644
index 0000000..3e630f0
--- /dev/null
+++ b/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/detach_A01_t02.dart
@@ -0,0 +1,59 @@
+// 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.
+
+/// @assertion void detach(
+/// Object detachToken
+// )
+/// Detaches the finalizer from values attached with [detachToken].
+///
+/// If the finalizer was attached multiple times to the same value with
+/// different detachment keys, only those attachments which used [detachToken]
+/// are removed.
+///
+/// @description Checks that only attachments which used given [detachToken]
+/// are removed.
+/// @author iarkh@unipro.ru
+
+import "../../gc_utils_lib.dart";
+import "../../../../Utils/expect.dart";
+
+class Nonce {
+ final int value;
+ Nonce(this.value);
+}
+
+final finalizerTokens = <Nonce>{};
+
+final Finalizer finalizer = Finalizer((token) {
+ finalizerTokens.add(token);
+});
+
+@pragma('vm:never-inline')
+void test() {
+ Object object1 = Object();
+ Object object2 = Object();
+ List<int> object3 = List.filled(100, 1);
+ List object4 = List.filled(200, "abc");
+ Nonce object5 = Nonce(14);
+
+ Object finalizationToken1 = Nonce(1);
+ Object finalizationToken2 = Nonce(2);
+
+ finalizer.attach(object1, "object1", detach: finalizationToken1);
+ finalizer.attach(object2, "object2", detach: finalizationToken2);
+ finalizer.attach(object3, "object3", detach: finalizationToken1);
+ finalizer.attach(object4, "object4", detach: finalizationToken1);
+ finalizer.attach(object5, "object5", detach: finalizationToken2);
+ finalizer.detach(finalizationToken1);
+}
+
+main() async {
+ test();
+ await triggerGcWithDelay();
+ Expect.setEquals({"Object2", "Object5"}, finalizerTokens);
+ await triggerGcWithDelay();
+ Expect.setEquals({"Object2", "Object5"}, finalizerTokens);
+ await triggerGcWithDelay();
+ Expect.setEquals({"Object2", "Object5"}, finalizerTokens);
+}
diff --git a/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/detach_A01_t03.dart b/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/detach_A01_t03.dart
new file mode 100644
index 0000000..43bdf80
--- /dev/null
+++ b/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/detach_A01_t03.dart
@@ -0,0 +1,60 @@
+// 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.
+
+/// @assertion void detach(
+/// Object detachToken
+// )
+/// Detaches the finalizer from values attached with [detachToken].
+///
+/// If the finalizer was attached multiple times to the same value with
+/// different detachment keys, only those attachments which used [detachToken]
+/// are removed.
+///
+/// @description Checks that detaching any token form finalizer does not affects
+/// object created without detachToken.
+/// @author iarkh@unipro.ru
+
+import "../../gc_utils_lib.dart";
+import "../../../../Utils/expect.dart";
+
+class Nonce {
+ final int value;
+ Nonce(this.value);
+}
+
+final finalizerTokens = <Nonce>{};
+
+final Finalizer finalizer = Finalizer((token) {
+ finalizerTokens.add(token);
+});
+
+@pragma('vm:never-inline')
+void test() {
+ Object object1 = Object();
+ Object object2 = Object();
+ List<int> object3 = List.filled(100, 1);
+ List object4 = List.filled(200, "abc");
+ Nonce object5 = Nonce(14);
+
+ Object finalizationToken1 = Nonce(1);
+ Object finalizationToken2 = Nonce(2);
+
+ finalizer.attach(object1, "object1");
+ finalizer.attach(object2, "object2", detach: finalizationToken2);
+ finalizer.attach(object3, "object3");
+ finalizer.attach(object4, "object4");
+ finalizer.attach(object5, "object5", detach: finalizationToken2);
+ finalizer.detach(finalizationToken2);
+}
+
+main() async {
+ test();
+ await triggerGcWithDelay();
+ Expect.setEquals({"Object1", "Object3", "Object4"}, finalizerTokens);
+ await triggerGcWithDelay();
+ Expect.setEquals({"Object1", "Object3", "Object4"}, finalizerTokens);
+ await triggerGcWithDelay();
+ Expect.setEquals({"Object1", "Object3", "Object4"}, finalizerTokens);
+}
+
diff --git a/LanguageFeatures/FinalizationRegistry/no_ffi/Finalizer/NoSuchMethod_A01_t01.dart b/LanguageFeatures/FinalizationRegistry/no_ffi/Finalizer/NoSuchMethod_A01_t01.dart
new file mode 100644
index 0000000..83e56fa
--- /dev/null
+++ b/LanguageFeatures/FinalizationRegistry/no_ffi/Finalizer/NoSuchMethod_A01_t01.dart
@@ -0,0 +1,26 @@
+// 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.
+
+/// @assertion noSuchMethod method
+// dynamic noSuchMethod(
+// Invocation invocation
+// )
+/// Invoked when a non-existent method or property is accessed.
+/// @description Checks that [NoSuchMethodError] is thrown if non-existing
+/// method or property is accessed.
+/// @author iarkh@unipro.ru
+
+import '../../../../Utils/expect.dart';
+
+dynamic finalizer = Finalizer((_) { throw "Should not reach here"; });
+
+main() {
+ Expect.throws(() {
+ finalizer.unexisting();
+ }, (e) => e is NoSuchMethodError);
+
+ Expect.throws(() {
+ finalizer.property;
+ }, (e) => e is NoSuchMethodError);
+}