Skip to content

Commit 6a7e6de

Browse files
author
Dart CI
committed
Version 2.18.0-170.0.dev
Merge commit '84402e7824bfd9e6c056ca3f89f5eb550c5fb2f5' into 'dev'
2 parents 431e71d + 84402e7 commit 6a7e6de

File tree

22 files changed

+234
-33
lines changed

22 files changed

+234
-33
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ them, you must set the lower bound on the SDK constraint for your package to
104104
105105
- Added `dartify` and a number of minor helper functions.
106106
107+
#### `dart:core`
108+
109+
- Allow omitting the `unencodedPath` positional argument to `Uri.http` and
110+
`Uri.https` to default to an empty path.
111+
107112
### Tools
108113
109114
#### Linter

DEPS

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ vars = {
8989
"chrome_rev": "19997",
9090
"cli_util_rev": "b0adbba89442b2ea6fef39c7a82fe79cb31e1168",
9191
"clock_rev": "f594d86da123015186d5680b0d0e8255c52fc162",
92-
"collection_rev": "69766daafbaa8535d1343fb7cd87e713f57c107f",
92+
"collection_rev": "f9b433dfc7dba5c8a987b1a8e6a9050292f5582e",
9393
"convert_rev": "00b251529c074df394b3391c7e3eea3dd9e5778e",
9494
"crypto_rev": "4297d240b0e1e780ec0a9eab23eaf1ad491f3e68",
9595
"csslib_rev": "518761b166974537f334dbf264e7f56cb157a96a",
@@ -145,7 +145,7 @@ vars = {
145145
"sse_rev": "9a54f1cdd91c8d79a6bf5ef8e849a12756607453",
146146
"stack_trace_rev": "17f09c2c6845bb31c7c385acecce5befb8527a13",
147147
"stream_channel_rev": "3fa3e40c75c210d617b8b943b9b8f580e9866a89",
148-
"string_scanner_rev": "6579871b528036767b3200b390a3ecef28e4900d",
148+
"string_scanner_rev": "c637deb8d998b72a5807afbd06aba8370db725c0",
149149
"sync_http_rev": "b6bd47965694dddffb6e62fb8a6c12d17c4ae4cd",
150150
"term_glyph_rev": "d0f205c67ea70eea47b9f41c8440129a72a9c86e",
151151
"test_descriptor_rev": "5ed5d7f6bf1191592995dcb8eedbbc17df69d386",

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6939,6 +6939,16 @@ const MessageCode messageJsInteropExternalMemberNotJSAnnotated = const MessageCo
69396939
correctionMessage:
69406940
r"""Try removing the 'external' keyword or adding a JS interop annotation.""");
69416941

6942+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
6943+
const Code<Null> codeJsInteropInvalidStaticClassMemberName =
6944+
messageJsInteropInvalidStaticClassMemberName;
6945+
6946+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
6947+
const MessageCode messageJsInteropInvalidStaticClassMemberName = const MessageCode(
6948+
"JsInteropInvalidStaticClassMemberName",
6949+
problemMessage:
6950+
r"""JS interop static class members cannot have '.' in their JS name.""");
6951+
69426952
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
69436953
const Template<
69446954
Message Function(

pkg/_js_interop_checks/lib/js_interop_checks.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart'
1414
messageJsInteropEnclosingClassJSAnnotationContext,
1515
messageJsInteropExternalExtensionMemberOnTypeInvalid,
1616
messageJsInteropExternalMemberNotJSAnnotated,
17+
messageJsInteropInvalidStaticClassMemberName,
1718
messageJsInteropNamedParameters,
1819
messageJsInteropNonExternalConstructor,
1920
messageJsInteropNonExternalMember,
@@ -274,6 +275,18 @@ class JsInteropChecks extends RecursiveVisitor {
274275
// named parameters.
275276
_checkNoNamedParameters(procedure.function);
276277
}
278+
279+
// JS static methods cannot use a JS name with dots.
280+
if (procedure.isStatic && procedure.enclosingClass != null) {
281+
String name = getJSName(procedure);
282+
if (name.contains('.')) {
283+
_diagnosticsReporter.report(
284+
messageJsInteropInvalidStaticClassMemberName,
285+
procedure.fileOffset,
286+
procedure.name.text.length,
287+
procedure.fileUri);
288+
}
289+
}
277290
}
278291

279292
if (_classHasStaticInteropAnnotation &&

pkg/analysis_server/lib/src/analytics/analytics_manager.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ abstract class AnalyticsManager {
2323
/// Record that the set of plugins known to the [pluginManager] has changed.
2424
void changedPlugins(PluginManager pluginManager);
2525

26+
/// Record that the given [notification] was received and has been handled.
27+
void handledNotificationMessage(
28+
{required NotificationMessage notification,
29+
required DateTime startTime,
30+
required DateTime endTime}) {}
31+
2632
/// Record that the given [response] was sent to the client.
2733
void sentResponse({required Response response});
2834

pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class GoogleAnalyticsManager implements AnalyticsManager {
3030
/// been responded to.
3131
final Map<String, _RequestData> _completedRequests = {};
3232

33+
/// A map from the name of a notification to data about all such notifications
34+
/// that have been handled.
35+
final Map<String, _NotificationData> _completedNotifications = {};
36+
3337
/// Initialize a newly created analytics manager to report to the [analytics]
3438
/// service.
3539
GoogleAnalyticsManager(this.analytics);
@@ -39,6 +43,23 @@ class GoogleAnalyticsManager implements AnalyticsManager {
3943
_pluginData.recordPlugins(pluginManager);
4044
}
4145

46+
@override
47+
void handledNotificationMessage(
48+
{required NotificationMessage notification,
49+
required DateTime startTime,
50+
required DateTime endTime}) {
51+
var method = notification.method.toString();
52+
var requestTime = notification.clientRequestTime;
53+
var start = startTime.millisecondsSinceEpoch;
54+
var end = endTime.millisecondsSinceEpoch;
55+
var data = _completedNotifications.putIfAbsent(
56+
method, () => _NotificationData(method));
57+
if (requestTime != null) {
58+
data.latencyTimes.addValue(start - requestTime);
59+
}
60+
data.handlingTimes.addValue(end - start);
61+
}
62+
4263
@override
4364
void sentResponse({required Response response}) {
4465
var sendTime = DateTime.now();
@@ -64,6 +85,7 @@ class GoogleAnalyticsManager implements AnalyticsManager {
6485
_sendSessionData(sessionData);
6586
_sendServerResponseTimes();
6687
_sendPluginResponseTimes();
88+
_sendNotificationHandlingTimes();
6789

6890
analytics.waitForLastPing(timeout: Duration(milliseconds: 200)).then((_) {
6991
analytics.close();
@@ -122,6 +144,17 @@ class GoogleAnalyticsManager implements AnalyticsManager {
122144
requestData.responseTimes.addValue(responseTime);
123145
}
124146

147+
/// Send information about the notifications handled by the server.
148+
void _sendNotificationHandlingTimes() {
149+
for (var data in _completedNotifications.values) {
150+
analytics.sendEvent('language_server', 'notification', parameters: {
151+
'latency': data.latencyTimes.toAnalyticsString(),
152+
'method': data.method,
153+
'duration': data.handlingTimes.toAnalyticsString(),
154+
});
155+
}
156+
}
157+
125158
/// Send information about the response times of plugins.
126159
void _sendPluginResponseTimes() {
127160
var responseTimes = PluginManager.pluginResponseTimes;
@@ -177,6 +210,27 @@ class _ActiveRequestData {
177210
_ActiveRequestData(this.requestName, this.clientRequestTime, this.startTime);
178211
}
179212

213+
/// Data about the notifications that have been handled that have the same
214+
/// method.
215+
class _NotificationData {
216+
/// The name of the notifications.
217+
final String method;
218+
219+
/// The percentile calculator for latency times. The _latency time_ is the
220+
/// time from when the client sent the request until the time the server
221+
/// started processing the request.
222+
final PercentileCalculator latencyTimes = PercentileCalculator();
223+
224+
/// The percentile calculator for handling times. The _handling time_ is the
225+
/// time from when the server started processing the notification until the
226+
/// handling was complete.
227+
final PercentileCalculator handlingTimes = PercentileCalculator();
228+
229+
/// Initialize a newly create data holder for notifications with the given
230+
/// [method].
231+
_NotificationData(this.method);
232+
}
233+
180234
/// Data about the plugins associated with the context roots.
181235
class _PluginData {
182236
/// The number of times that plugin information has been recorded.
@@ -219,7 +273,8 @@ class _PluginData {
219273
}
220274
}
221275

222-
/// Data about the requests that have been responded to that have the same name.
276+
/// Data about the requests that have been responded to that have the same
277+
/// method.
223278
class _RequestData {
224279
/// The name of the requests.
225280
final String method;

pkg/analysis_server/lib/src/analytics/noop_analytics_manager.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ class NoopAnalyticsManager implements AnalyticsManager {
1313
@override
1414
void changedPlugins(PluginManager pluginManager) {}
1515

16+
@override
17+
void handledNotificationMessage(
18+
{required NotificationMessage notification,
19+
required DateTime startTime,
20+
required DateTime endTime}) {}
21+
1622
@override
1723
void sentResponse({required Response response}) {}
1824

pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,10 @@ class LspAnalysisServer extends AbstractAnalysisServer {
374374
await _handleRequestMessage(message, messageInfo);
375375
} else if (message is NotificationMessage) {
376376
await _handleNotificationMessage(message, messageInfo);
377+
analyticsManager.handledNotificationMessage(
378+
notification: message,
379+
startTime: startTime,
380+
endTime: DateTime.now());
377381
} else {
378382
showErrorMessageToUser('Unknown incoming message type');
379383
}

pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'dart:convert';
66

7+
import 'package:analysis_server/lsp_protocol/protocol.dart';
78
import 'package:analysis_server/protocol/protocol.dart';
89
import 'package:analysis_server/src/analytics/google_analytics_manager.dart';
910
import 'package:analysis_server/src/analytics/percentile_calculator.dart';
@@ -41,6 +42,26 @@ class GoogleAnalyticsManagerTest {
4142
PluginManager.pluginResponseTimes.clear();
4243
}
4344

45+
void test_server_notification() {
46+
_defaultStartup();
47+
manager.handledNotificationMessage(
48+
notification: NotificationMessage(
49+
clientRequestTime: 2,
50+
jsonrpc: '',
51+
method: Method.workspace_didCreateFiles),
52+
startTime: _now(),
53+
endTime: _now());
54+
manager.shutdown();
55+
analytics.assertEvents([
56+
_ExpectedEvent.session(),
57+
_ExpectedEvent.notification(parameters: {
58+
'latency': _IsPercentiles(),
59+
'method': Method.workspace_didCreateFiles.toString(),
60+
'duration': _IsPercentiles(),
61+
}),
62+
]);
63+
}
64+
4465
void test_server_request() {
4566
_defaultStartup();
4667
manager.startedRequest(
@@ -160,6 +181,9 @@ class _ExpectedEvent {
160181
this.value, // ignore: unused_element
161182
this.parameters});
162183

184+
_ExpectedEvent.notification({Map<String, Object>? parameters})
185+
: this('language_server', 'notification', parameters: parameters);
186+
163187
_ExpectedEvent.pluginRequest({Map<String, Object>? parameters})
164188
: this('language_server', 'pluginRequest', parameters: parameters);
165189

pkg/analyzer/lib/src/dart/micro/utils.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,7 @@ class ReferencesCollector extends GeneralizingAstVisitor<void> {
307307
length = 0;
308308
}
309309
references.add(MatchInfo(offset, length, kind));
310-
}
311-
if (e!.enclosingElement == element) {
310+
} else if (e != null && e.enclosingElement == element) {
312311
kind = MatchKind.REFERENCE;
313312
offset = node.offset;
314313
length = element.nameLength;

pkg/compiler/lib/src/js_backend/native_data.dart

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -650,11 +650,16 @@ class NativeData implements NativeBasicData {
650650
String getFixedBackendName(MemberEntity element) {
651651
String name = _nativeMemberName[element];
652652
if (name == null && isJsInteropMember(element)) {
653-
// If an element isJsInterop but _isJsInterop is false that means it is
654-
// considered interop as the parent class is interop.
655-
name = element.isConstructor
656-
? _jsClassNameHelper(element.enclosingClass)
657-
: _jsMemberNameHelper(element);
653+
if (element.isConstructor) {
654+
name = _jsClassNameHelper(element.enclosingClass);
655+
} else {
656+
name = _jsMemberNameHelper(element);
657+
// Top-level static JS interop members can be associated with a dotted
658+
// name, if so, fixedBackendName is the last segment.
659+
if (element.isTopLevel && name.contains('.')) {
660+
name = name.substring(name.lastIndexOf('.') + 1);
661+
}
662+
}
658663
_nativeMemberName[element] = name;
659664
}
660665
return name;
@@ -705,6 +710,15 @@ class NativeData implements NativeBasicData {
705710
..write('.')
706711
..write(_jsClassNameHelper(element.enclosingClass));
707712
}
713+
714+
// Top-level static JS interop members can be associated with a dotted
715+
// name, if so, fixedBackendPath includes all but the last segment.
716+
final name = _jsMemberNameHelper(element);
717+
if (element.isTopLevel && name.contains('.')) {
718+
sb
719+
..write('.')
720+
..write(name.substring(0, name.lastIndexOf('.')));
721+
}
708722
return sb.toString();
709723
}
710724

pkg/compiler/lib/src/js_emitter/native_emitter.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ class NativeEmitter {
344344
1, indexOfLastOptionalArgumentInParameters + 1);
345345
} else {
346346
// Native methods that are not intercepted must be static.
347-
assert(member.isStatic, failedAt(member));
347+
assert(member.isStatic || member.isTopLevel, failedAt(member));
348348
arguments = argumentsBuffer.sublist(
349349
0, indexOfLastOptionalArgumentInParameters + 1);
350350
if (_nativeData.isJsInteropMember(member)) {

pkg/dev_compiler/lib/src/kernel/compiler.dart

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,16 +2645,9 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
26452645

26462646
js_ast.LiteralString _emitJSInteropStaticMemberName(NamedNode n) {
26472647
if (!usesJSInterop(n)) return null;
2648-
var name = _annotationName(n, isPublicJSAnnotation);
2649-
if (name != null) {
2650-
if (name.contains('.')) {
2651-
throw UnsupportedError(
2652-
'static members do not support "." in their names. '
2653-
'See https://github.com/dart-lang/sdk/issues/27926');
2654-
}
2655-
} else {
2656-
name = getTopLevelName(n);
2657-
}
2648+
var name = _annotationName(n, isPublicJSAnnotation) ?? getTopLevelName(n);
2649+
assert(name != null && !name.contains('.'),
2650+
'JS interop checker rejects dotted names on static class members');
26582651
return js.escapedString(name, "'");
26592652
}
26602653

pkg/front_end/messages.status

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,8 @@ JsInteropExternalExtensionMemberOnTypeInvalid/analyzerCode: Fail # Web compiler
562562
JsInteropExternalExtensionMemberOnTypeInvalid/example: Fail # Web compiler specific
563563
JsInteropExternalMemberNotJSAnnotated/analyzerCode: Fail # Web compiler specific
564564
JsInteropExternalMemberNotJSAnnotated/example: Fail # Web compiler specific
565+
JsInteropInvalidStaticClassMemberName/analyzerCode: Fail
566+
JsInteropInvalidStaticClassMemberName/example: Fail
565567
JsInteropJSClassExtendsDartClass/analyzerCode: Fail # Web compiler specific
566568
JsInteropJSClassExtendsDartClass/example: Fail # Web compiler specific
567569
JsInteropNamedParameters/analyzerCode: Fail # Web compiler specific

pkg/front_end/messages.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5173,6 +5173,9 @@ JsInteropOperatorsNotSupported:
51735173
problemMessage: "JS interop classes do not support operator methods."
51745174
correctionMessage: "Try replacing this with a normal method."
51755175

5176+
JsInteropInvalidStaticClassMemberName:
5177+
problemMessage: "JS interop static class members cannot have '.' in their JS name."
5178+
51765179
JsInteropStaticInteropWithInstanceMembers:
51775180
problemMessage: "JS interop class '#name' with `@staticInterop` annotation cannot declare instance members."
51785181
correctionMessage: "Try moving the instance member to a static extension."

sdk/lib/core/uri.dart

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,13 @@ abstract class Uri {
238238
/// The `path` component is set from the [unencodedPath]
239239
/// argument. The path passed must not be encoded as this constructor
240240
/// encodes the path.
241+
/// If omitted, the path defaults to being empty.
241242
///
242243
/// The `query` component is set from the optional [queryParameters]
243244
/// argument.
244-
factory Uri.http(String authority, String unencodedPath,
245-
[Map<String, dynamic>? queryParameters]) = _Uri.http;
245+
factory Uri.http(String authority,
246+
[String unencodedPath,
247+
Map<String, dynamic>? queryParameters]) = _Uri.http;
246248

247249
/// Creates a new `https` URI from authority, path and query.
248250
///
@@ -263,8 +265,9 @@ abstract class Uri {
263265
/// uri = Uri.https('example.org', '/a%2F');
264266
/// print(uri); // https://example.org/a%252F
265267
/// ```
266-
factory Uri.https(String authority, String unencodedPath,
267-
[Map<String, dynamic>? queryParameters]) = _Uri.https;
268+
factory Uri.https(String authority,
269+
[String unencodedPath,
270+
Map<String, dynamic>? queryParameters]) = _Uri.https;
268271

269272
/// Creates a new file URI from an absolute or relative file path.
270273
///
@@ -1667,14 +1670,14 @@ class _Uri implements Uri {
16671670
}
16681671

16691672
/// Implementation of [Uri.http].
1670-
factory _Uri.http(String authority, String unencodedPath,
1671-
[Map<String, dynamic>? queryParameters]) {
1673+
factory _Uri.http(String authority,
1674+
[String unencodedPath = '', Map<String, dynamic>? queryParameters]) {
16721675
return _makeHttpUri("http", authority, unencodedPath, queryParameters);
16731676
}
16741677

16751678
/// Implementation of [Uri.https].
1676-
factory _Uri.https(String authority, String unencodedPath,
1677-
[Map<String, dynamic>? queryParameters]) {
1679+
factory _Uri.https(String authority,
1680+
[String unencodedPath = '', Map<String, dynamic>? queryParameters]) {
16781681
return _makeHttpUri("https", authority, unencodedPath, queryParameters);
16791682
}
16801683

0 commit comments

Comments
 (0)