Version 3.14.0-118.0.dev

Merge 705d53ad3b6bb529d56ebc2320b5d68435bf1ce1 into dev
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/move_annotation_to_library_directive.dart b/pkg/analysis_server/lib/src/services/correction/dart/move_annotation_to_library_directive.dart
index f032147..431eecf 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/move_annotation_to_library_directive.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/move_annotation_to_library_directive.dart
@@ -33,9 +33,7 @@
       return;
     }
 
-    var firstDirective = compilationUnit.directives.isEmpty
-        ? null
-        : compilationUnit.directives.first;
+    var firstDirective = compilationUnit.directives.firstOrNull;
     if (firstDirective is LibraryDirective) {
       await _moveToExistingLibraryDirective(
         builder,
@@ -71,23 +69,18 @@
     });
   }
 
+  /// Creates a new unnamed library directive and moves [annotation]
+  /// immediately above it.
   Future<void> _moveToNewLibraryDirective(
     ChangeBuilder builder,
     Annotation annotation,
     CompilationUnit compilationUnit,
   ) async {
     var annotationRange = utils.getLinesRange(range.node(annotation));
-    // Create a new, unnamed library directive, and move the annotation to just
-    // above the directive.
     var token = compilationUnit.beginToken;
 
-    if (token.type == TokenType.SCRIPT_TAG) {
-      // TODO(srawlins): Handle this case.
-      return;
-    }
-
+    // Do not "move" the annotation. Just slip a library directive below it.
     if (token == annotation.beginToken) {
-      // Do not "move" the annotation. Just slip a library directive below it.
       await builder.addDartFileEdit(file, (builder) {
         var eol = builder.eol;
         builder.addSimpleInsertion(annotationRange.end, 'library;$eol$eol');
@@ -97,28 +90,42 @@
 
     await builder.addDartFileEdit(file, (builder) {
       var eol = builder.eol;
-      int insertionOffset;
-      String prefix;
+      var insertionOffset = 0;
+      var prefix = '';
+
+      // Move past the script tag.
+      if (token.type == TokenType.SCRIPT_TAG) {
+        insertionOffset = token.end;
+        prefix = eol;
+        token = token.next!;
+      }
+
+      // Move past headers such as copyright and language-version comments.
       Token? commentOnFirstToken = token.precedingComments;
       if (commentOnFirstToken != null) {
         while (commentOnFirstToken!.next != null) {
           commentOnFirstToken = commentOnFirstToken.next!;
         }
-        // `token` is now the last of the leading comments (perhaps a Copyright
-        // notice, a Dart language version, etc.)
         insertionOffset = commentOnFirstToken.end;
         prefix = '$eol$eol';
-      } else {
-        insertionOffset = 0;
-        prefix = '';
       }
 
-      builder.addDeletion(annotationRange);
-      var annotationText = utils.getRangeText(annotationRange);
-      builder.addSimpleInsertion(
-        insertionOffset,
-        '$prefix${annotationText}library;$eol$eol',
+      // Extend the replacement through whitespace before the next token.
+      var leadingWhitespace = utils.getRangeText(
+        range.startOffsetEndOffset(insertionOffset, annotation.offset),
       );
+      var leadingWhitespaceLength = RegExp(r'^\s*')
+          .firstMatch(leadingWhitespace)!
+          .end;
+      var insertionRange = range.startOffsetLength(
+        insertionOffset,
+        leadingWhitespaceLength,
+      );
+
+      var annotationText = utils.getRangeText(annotationRange);
+      var replacement = '$prefix${annotationText}library;$eol$eol';
+      builder.addDeletion(annotationRange);
+      builder.addSimpleReplacement(insertionRange, replacement);
     });
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/move_annotation_to_library_directive_test.dart b/pkg/analysis_server/test/src/services/correction/fix/move_annotation_to_library_directive_test.dart
index 243ff48..b52c08b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/move_annotation_to_library_directive_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/move_annotation_to_library_directive_test.dart
@@ -59,7 +59,7 @@
   }
 
   Future<void>
-  test_noExistingLibraryDirective_annotherAnnotationIsFirst() async {
+  test_noExistingLibraryDirective_anotherAnnotationIsFirst() async {
     await resolveTestCode('''
 @deprecated
 @pragma('dart2js:late:trust')
@@ -116,7 +116,6 @@
 
 void f(Completer c) {}
 ''');
-    // TODO(srawlins): Fix the 4 newlines below; should be 2.
     await assertHasFix('''
 // Comment 1.
 
@@ -125,7 +124,50 @@
 @pragma('dart2js:late:trust')
 library;
 
+@deprecated
+import 'dart:async';
 
+void f(Completer c) {}
+''');
+  }
+
+  Future<void> test_noExistingLibraryDirective_scriptTag() async {
+    await resolveTestCode('''
+#!/usr/bin/env dart
+@pragma('dart2js:late:trust')
+import 'dart:async';
+
+void f(Completer c) {}
+''');
+    await assertHasFix('''
+#!/usr/bin/env dart
+@pragma('dart2js:late:trust')
+library;
+
+import 'dart:async';
+
+void f(Completer c) {}
+''');
+  }
+
+  Future<void>
+  test_noExistingLibraryDirective_scriptTag_withCommentsAndAnnotations() async {
+    await resolveTestCode('''
+#!/usr/bin/env dart
+// Copyright notice.
+
+@deprecated
+@pragma('dart2js:late:trust')
+import 'dart:async';
+
+void f(Completer c) {}
+''');
+    await assertHasFix('''
+#!/usr/bin/env dart
+// Copyright notice.
+
+@pragma('dart2js:late:trust')
+library;
 
 @deprecated
 import 'dart:async';
diff --git a/runtime/vm/compiler/assembler/disassembler_test.cc b/runtime/vm/compiler/assembler/disassembler_test.cc
index ab72b02..04ff7f5 100644
--- a/runtime/vm/compiler/assembler/disassembler_test.cc
+++ b/runtime/vm/compiler/assembler/disassembler_test.cc
@@ -23,7 +23,8 @@
   // Only verify that the disassembler does not crash.
   AssemblerTest test("Disassembler", &assembler, Thread::Current()->zone());
   test.Assemble();
-  Disassembler::Disassemble(test.entry(), test.entry() + assembler.CodeSize());
+  Disassembler::Disassemble(test.entry_unsigned(),
+                            test.entry_unsigned() + assembler.CodeSize());
 }
 
 ISOLATE_UNIT_TEST_CASE(Disassembler_InvalidInput) {
diff --git a/runtime/vm/compiler/relocation_test.cc b/runtime/vm/compiler/relocation_test.cc
index c1e9c7c..5183f86 100644
--- a/runtime/vm/compiler/relocation_test.cc
+++ b/runtime/vm/compiler/relocation_test.cc
@@ -194,6 +194,12 @@
         }
       }
     }
+
+#if defined(TARGET_ARCH_ARM64E)
+    entrypoint = reinterpret_cast<uword>(ptrauth_sign_unauthenticated(
+        reinterpret_cast<void*>(entrypoint), ptrauth_key_function_pointer, 0));
+#endif
+
     typedef intptr_t (*Fun)() DART_UNUSED;
 #if defined(TARGET_ARCH_X64)
     EXPECT_EQ(42, reinterpret_cast<Fun>(entrypoint)());
diff --git a/runtime/vm/heap/freelist_test.cc b/runtime/vm/heap/freelist_test.cc
index ac8ae8f..770b5db 100644
--- a/runtime/vm/heap/freelist_test.cc
+++ b/runtime/vm/heap/freelist_test.cc
@@ -222,7 +222,12 @@
   blob->WriteProtectCode();  // not writable
   Allocate(free_list.get(), alloc_size, /*is_protected=*/true);
   VirtualMemory::WriteProtectCode(blob->address(), alloc_size);
-  reinterpret_cast<void (*)()>(other_code)();
+
+  auto func = reinterpret_cast<void (*)()>(other_code);
+#if defined(HOST_ARCH_ARM64E)
+  func = ptrauth_sign_unauthenticated(func, ptrauth_key_function_pointer, 0);
+#endif
+  func();
 }
 
 TEST_CASE(Regress38528) {
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index b933183..ef605ab 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -511,6 +511,7 @@
 #endif
     return result;
   }
+  uword entry_unsigned() const { return code_.EntryPoint(); }
 
 // Invoke/InvokeWithCodeAndThread is used to call assembler test functions
 // using the ABI calling convention.
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index b1c70854..8607121 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -20,6 +20,7 @@
 #endif
 
 #if defined(DART_HOST_OS_MACOS)
+#include <mach/mach_error.h>
 #include <mach/mach_init.h>
 #include <mach/vm_map.h>
 #endif
@@ -836,7 +837,6 @@
 }
 
 #if defined(DART_HOST_OS_MACOS)
-// TODO(52579): Reenable on Fuchsia.
 bool VirtualMemory::DuplicateRX(VirtualMemory* target) {
   const intptr_t aligned_size = Utils::RoundUp(size(), PageSize());
   ASSERT_LESS_OR_EQUAL(aligned_size, target->size());
@@ -860,6 +860,7 @@
       /*copy=*/true, &current_protection, &max_protection,
       /*inheritance=*/VM_INHERIT_NONE);
   if (status != KERN_SUCCESS) {
+    OS::PrintErr("DuplicateRX failed: %s\n", mach_error_string(status));
     return false;
   }
   ASSERT(reinterpret_cast<void*>(target_address) == target->address());
diff --git a/runtime/vm/virtual_memory_test.cc b/runtime/vm/virtual_memory_test.cc
index 6980c8b..edee6d5 100644
--- a/runtime/vm/virtual_memory_test.cc
+++ b/runtime/vm/virtual_memory_test.cc
@@ -99,7 +99,11 @@
 NO_SANITIZE_UNDEFINED_FUNCTION  // See https://dartbug.com/52440
 VM_UNIT_TEST_CASE(DuplicateRXVirtualMemory) {
   const uword page_size = VirtualMemory::PageSize();
-  const uword pointer = reinterpret_cast<uword>(&testFunction);
+  auto* func_pointer = &testFunction;
+#if defined(HOST_ARCH_ARM64E)
+  func_pointer = ptrauth_strip(func_pointer, ptrauth_key_function_pointer);
+#endif
+  const uword pointer = reinterpret_cast<uword>(func_pointer);
   const uword page_start = Utils::RoundDown(pointer, page_size);
   const uword offset = pointer - page_start;
 
@@ -117,6 +121,10 @@
   EXPECT_EQ(true, ok);
 
   auto testFunction2 = reinterpret_cast<int (*)(int)>(vm2->start() + offset);
+#if defined(HOST_ARCH_ARM64E)
+  testFunction2 = ptrauth_sign_unauthenticated(testFunction2,
+                                               ptrauth_key_function_pointer, 0);
+#endif
   EXPECT_NE(&testFunction, testFunction2);
 
   EXPECT_EQ(246, testFunction2(123));
diff --git a/tools/VERSION b/tools/VERSION
index c8663c0..f1dee2a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 3
 MINOR 14
 PATCH 0
-PRERELEASE 117
+PRERELEASE 118
 PRERELEASE_PATCH 0