Version 2.14.0-199.0.dev

Merge commit 'bd4a6291e5985423cbeeee4d34222e4136e75936' into 'dev'
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index 2292405..bdd6ad3 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -391,7 +391,6 @@
     assertHasRegionTarget('BBB p', 'BBB {}');
   }
 
-  @failingTest
   Future<void> test_enum_constant() async {
     addTestFile('''
 enum E { a, b }
diff --git a/pkg/analysis_server/test/integration/analysis/navigation_test.dart b/pkg/analysis_server/test/integration/analysis/navigation_test.dart
index 23f6e7c..61365b1 100644
--- a/pkg/analysis_server/test/integration/analysis/navigation_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/navigation_test.dart
@@ -117,13 +117,13 @@
         'function(FunctionTypeAlias parameter)', ElementKind.FUNCTION);
     checkLocal('FunctionTypeAlias parameter', 'FunctionTypeAlias();',
         ElementKind.TYPE_ALIAS);
-    checkLocal('field)', 'field = (', ElementKind.GETTER);
+    checkLocal('field)', 'field = (', ElementKind.FIELD);
     checkRemote("'dart:async'", r'async\.dart$', ElementKind.LIBRARY);
     checkLocal(
         'localVariable.field', 'localVariable =', ElementKind.LOCAL_VARIABLE);
     checkLocal('method();', 'method() {', ElementKind.METHOD);
     checkLocal('parameter());', 'parameter) {', ElementKind.PARAMETER);
-    checkLocal('field = 1', 'field = (', ElementKind.SETTER);
+    checkLocal('field = 1', 'field = (', ElementKind.FIELD);
     checkLocal('topLevelVariable = 0;', 'topLevelVariable = 0;',
         ElementKind.TOP_LEVEL_VARIABLE);
     checkLocal('TypeParameter field = (', 'TypeParameter>',
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index 13c0f9b..e409097a 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -52,12 +52,7 @@
       this.collector, this.requestedOffset, this.requestedLength);
 
   void _addRegion(int offset, int length, Element? element) {
-    if (element != null && element.isSynthetic) {
-      var parent = element.enclosingElement;
-      if (parent is EnumElementImpl) {
-        element = parent;
-      }
-    }
+    element = element?.nonSynthetic;
     if (element is FieldFormalParameterElement) {
       element = element.field;
     }
@@ -442,10 +437,6 @@
     if (element == null) {
       return;
     }
-    // if a synthetic constructor, navigate to the class
-    if (element.isSynthetic) {
-      element = element.enclosingElement;
-    }
     // add regions
     var typeName = node.type;
     // [prefix].ClassName
diff --git a/sdk/lib/_http/websocket_impl.dart b/sdk/lib/_http/websocket_impl.dart
index 68d0f29..7de33f0 100644
--- a/sdk/lib/_http/websocket_impl.dart
+++ b/sdk/lib/_http/websocket_impl.dart
@@ -1014,6 +1014,8 @@
     }
     String nonce = _CryptoUtils.bytesToBase64(nonceData);
 
+    final callerStackTrace = StackTrace.current;
+
     uri = new Uri(
         scheme: uri.scheme == "wss" ? "https" : "http",
         userInfo: uri.userInfo,
@@ -1050,12 +1052,13 @@
 
       return request.close();
     }).then((response) {
-      Never error(String message) {
+      Future<WebSocket> error(String message) {
         // Flush data.
         response.detachSocket().then((socket) {
           socket.destroy();
         });
-        throw new WebSocketException(message);
+        return Future<WebSocket>.error(
+            new WebSocketException(message), callerStackTrace);
       }
 
       var connectionHeader = response.headers[HttpHeaders.connectionHeader];
@@ -1064,22 +1067,24 @@
           !connectionHeader.any((value) => value.toLowerCase() == "upgrade") ||
           response.headers.value(HttpHeaders.upgradeHeader)!.toLowerCase() !=
               "websocket") {
-        error("Connection to '$uri' was not upgraded to websocket");
+        return error("Connection to '$uri' was not upgraded to websocket");
       }
       String? accept = response.headers.value("Sec-WebSocket-Accept");
       if (accept == null) {
-        error("Response did not contain a 'Sec-WebSocket-Accept' header");
+        return error(
+            "Response did not contain a 'Sec-WebSocket-Accept' header");
       }
       _SHA1 sha1 = new _SHA1();
       sha1.add("$nonce$_webSocketGUID".codeUnits);
       List<int> expectedAccept = sha1.close();
       List<int> receivedAccept = _CryptoUtils.base64StringToBytes(accept);
       if (expectedAccept.length != receivedAccept.length) {
-        error("Response header 'Sec-WebSocket-Accept' is the wrong length");
+        return error(
+            "Response header 'Sec-WebSocket-Accept' is the wrong length");
       }
       for (int i = 0; i < expectedAccept.length; i++) {
         if (expectedAccept[i] != receivedAccept[i]) {
-          error("Bad response 'Sec-WebSocket-Accept' header");
+          return error("Bad response 'Sec-WebSocket-Accept' header");
         }
       }
       var protocol = response.headers.value('Sec-WebSocket-Protocol');
diff --git a/tests/standalone/io/socket_connect_dwarf_stacktrace_test.dart b/tests/standalone/io/socket_connect_dwarf_stacktrace_test.dart
new file mode 100644
index 0000000..09da91d
--- /dev/null
+++ b/tests/standalone/io/socket_connect_dwarf_stacktrace_test.dart
@@ -0,0 +1,50 @@
+// 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.
+//
+// VMOptions=--dwarf-stack-traces --save-debugging-info=socket_connect_debug.so
+//
+// Tests stack trace on socket exceptions.
+//
+
+import "dart:async";
+import "dart:convert";
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "package:native_stack_traces/native_stack_traces.dart";
+
+Future<List<String>> findFrames(
+    Dwarf dwarf, RegExp re, StackTrace stackTrace) async {
+  final dwarfed = await Stream.value(stackTrace.toString())
+      .transform(const LineSplitter())
+      .toList();
+  return Stream.fromIterable(dwarfed)
+      .transform(DwarfStackTraceDecoder(dwarf))
+      .where(re.hasMatch)
+      .toList();
+}
+
+Future<void> main() async {
+  asyncStart();
+  final dwarf = Dwarf.fromFile('socket_connect_debug.so')!;
+  // Test stacktrace when lookup fails
+  try {
+    await WebSocket.connect('ws://localhost.tld:0/ws');
+  } catch (err, stackTrace) {
+    Expect.contains('Failed host lookup', err.toString());
+    final decoded = await findFrames(dwarf, RegExp("main"), stackTrace);
+    Expect.equals(1, decoded.length);
+  }
+
+  // Test stacktrace when connection fails
+  try {
+    await WebSocket.connect('ws://localhost:0/ws');
+  } catch (err, stackTrace) {
+    Expect.contains('was not upgraded to websocket', err.toString());
+    final decoded = await findFrames(dwarf, RegExp("main"), stackTrace);
+    Expect.equals(1, decoded.length);
+  }
+  asyncEnd();
+}
diff --git a/tests/standalone/io/socket_connect_stacktrace_test.dart b/tests/standalone/io/socket_connect_stacktrace_test.dart
index 944bc4f..086823c 100644
--- a/tests/standalone/io/socket_connect_stacktrace_test.dart
+++ b/tests/standalone/io/socket_connect_stacktrace_test.dart
@@ -19,6 +19,7 @@
   try {
     await WebSocket.connect('ws://localhost.tld:0/ws');
   } catch (err, stackTrace) {
+    Expect.contains('Failed host lookup', err.toString());
     Expect.contains("main ", stackTrace.toString());
   }
 
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 3c981bc..6dba96d 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -16,6 +16,12 @@
 [ $builder_tag == asan ]
 io/process_detached_test: Slow, Pass
 
+[ $builder_tag == dwarf ]
+io/socket_connect_stacktrace_test: SkipByDesign # Assumes stacktrace can be inspected directly, without decoding
+
+[ $builder_tag != dwarf ]
+io/socket_connect_dwarf_stacktrace_test: SkipByDesign # Is set up to decode dwarf stack traces
+
 [ $builder_tag == no_ipv6 ]
 io/http_ipv6_test: SkipByDesign
 io/http_loopback_test: SkipByDesign
diff --git a/tests/standalone_2/io/socket_connect_dwarf_stacktrace_test.dart b/tests/standalone_2/io/socket_connect_dwarf_stacktrace_test.dart
new file mode 100644
index 0000000..d2f56b7
--- /dev/null
+++ b/tests/standalone_2/io/socket_connect_dwarf_stacktrace_test.dart
@@ -0,0 +1,55 @@
+// 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.
+//
+// VMOptions=--dwarf-stack-traces --save-debugging-info=socket_connect_debug.so
+//
+// Tests stack trace on socket exceptions.
+//
+
+import "dart:async";
+import "dart:convert";
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "package:native_stack_traces/native_stack_traces.dart";
+
+Future<List<String>> findFrames(
+    Dwarf dwarf, RegExp re, StackTrace stackTrace) async {
+  final dwarfed = await Stream.value(stackTrace.toString())
+      .transform(const LineSplitter())
+      .toList();
+  return Stream.fromIterable(dwarfed)
+      .transform(DwarfStackTraceDecoder(dwarf))
+      .where(re.hasMatch)
+      .toList();
+}
+
+Future<void> main() async {
+  asyncStart();
+  final dwarfFromFile = Dwarf.fromFile('socket_connect_debug.so');
+  if (dwarfFromFile == null) {
+    Expect.fail('Debug binary is missing');
+    return;
+  }
+  Dwarf dwarf = dwarfFromFile;
+  // Test stacktrace when lookup fails
+  try {
+    await WebSocket.connect('ws://localhost.tld:0/ws');
+  } catch (err, stackTrace) {
+    Expect.contains('Failed host lookup', err.toString());
+    final decoded = await findFrames(dwarf, RegExp("main"), stackTrace);
+    Expect.equals(1, decoded.length);
+  }
+
+  // Test stacktrace when connection fails
+  try {
+    await WebSocket.connect('ws://localhost:0/ws');
+  } catch (err, stackTrace) {
+    Expect.contains('was not upgraded to websocket', err.toString());
+    final decoded = await findFrames(dwarf, RegExp("main"), stackTrace);
+    Expect.equals(1, decoded.length);
+  }
+  asyncEnd();
+}
diff --git a/tests/standalone_2/io/socket_connect_stacktrace_test.dart b/tests/standalone_2/io/socket_connect_stacktrace_test.dart
index 944bc4f..086823c 100644
--- a/tests/standalone_2/io/socket_connect_stacktrace_test.dart
+++ b/tests/standalone_2/io/socket_connect_stacktrace_test.dart
@@ -19,6 +19,7 @@
   try {
     await WebSocket.connect('ws://localhost.tld:0/ws');
   } catch (err, stackTrace) {
+    Expect.contains('Failed host lookup', err.toString());
     Expect.contains("main ", stackTrace.toString());
   }
 
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index df81919..1745694 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -16,6 +16,12 @@
 [ $builder_tag == asan ]
 io/process_detached_test: Slow, Pass
 
+[ $builder_tag == dwarf ]
+io/socket_connect_stacktrace_test: SkipByDesign # Assumes stacktrace can be inspected directly, without decoding
+
+[ $builder_tag != dwarf ]
+io/socket_connect_dwarf_stacktrace_test: SkipByDesign # Is set up to decode dwarf stack traces
+
 [ $builder_tag == no_ipv6 ]
 io/http_ipv6_test: SkipByDesign
 io/http_loopback_test: SkipByDesign
diff --git a/tools/VERSION b/tools/VERSION
index 130a3c9..88bd277 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 198
+PRERELEASE 199
 PRERELEASE_PATCH 0
\ No newline at end of file