Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e4fa78b

Browse files
author
Dart CI
committed
Version 2.14.0-359.0.dev
Merge commit 'f424f3a4cca306513e77c7747682f1c1c99e3307' into 'dev'
2 parents c9f1521 + f424f3a commit e4fa78b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1476
-387
lines changed

.dart_tool/package_config.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"constraint, update this by running tools/generate_package_config.dart."
1212
],
1313
"configVersion": 2,
14-
"generated": "2021-07-26T14:57:34.624319",
14+
"generated": "2021-07-27T19:27:52.638315",
1515
"generator": "tools/generate_package_config.dart",
1616
"packages": [
1717
{
@@ -244,7 +244,7 @@
244244
"name": "dds",
245245
"rootUri": "../pkg/dds",
246246
"packageUri": "lib/",
247-
"languageVersion": "2.12"
247+
"languageVersion": "2.14"
248248
},
249249
{
250250
"name": "dev_compiler",
@@ -725,7 +725,7 @@
725725
"name": "testing",
726726
"rootUri": "../pkg/testing",
727727
"packageUri": "lib/",
728-
"languageVersion": "2.0"
728+
"languageVersion": "2.12"
729729
},
730730
{
731731
"name": "typed_data",

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6217,6 +6217,18 @@ const MessageCode messageJsInteropEnclosingClassJSAnnotationContext =
62176217
severity: Severity.context,
62186218
message: r"""This is the enclosing class.""");
62196219

6220+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
6221+
const Code<Null> codeJsInteropExternalExtensionMemberNotOnJSClass =
6222+
messageJsInteropExternalExtensionMemberNotOnJSClass;
6223+
6224+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
6225+
const MessageCode messageJsInteropExternalExtensionMemberNotOnJSClass =
6226+
const MessageCode("JsInteropExternalExtensionMemberNotOnJSClass",
6227+
message:
6228+
r"""JS interop class required for 'external' extension members.""",
6229+
tip:
6230+
r"""Try adding a JS interop annotation to the on type class of the extension.""");
6231+
62206232
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
62216233
const Code<Null> codeJsInteropExternalMemberNotJSAnnotated =
62226234
messageJsInteropExternalMemberNotJSAnnotated;

pkg/_js_interop_checks/lib/js_interop_checks.dart

Lines changed: 86 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart'
1212
messageJsInteropAnonymousFactoryPositionalParameters,
1313
messageJsInteropEnclosingClassJSAnnotation,
1414
messageJsInteropEnclosingClassJSAnnotationContext,
15+
messageJsInteropExternalExtensionMemberNotOnJSClass,
1516
messageJsInteropExternalMemberNotJSAnnotated,
1617
messageJsInteropIndexNotSupported,
1718
messageJsInteropNamedParameters,
@@ -30,6 +31,7 @@ class JsInteropChecks extends RecursiveVisitor {
3031
bool _classHasJSAnnotation = false;
3132
bool _classHasAnonymousAnnotation = false;
3233
bool _libraryHasJSAnnotation = false;
34+
Map<Reference, Extension>? _libraryExtensionsIndex;
3335

3436
/// Libraries that use `external` to exclude from checks on external.
3537
static final Iterable<String> _pathsWithAllowedDartExternalUsage = <String>[
@@ -86,7 +88,8 @@ class JsInteropChecks extends RecursiveVisitor {
8688

8789
@override
8890
void defaultMember(Member member) {
89-
_checkJSInteropAnnotation(member);
91+
_checkInstanceMemberJSAnnotation(member);
92+
if (!_isJSInteropMember(member)) _checkDisallowedExternal(member);
9093
// TODO(43530): Disallow having JS interop annotations on non-external
9194
// members (class members or otherwise). Currently, they're being ignored.
9295
super.defaultMember(member);
@@ -165,11 +168,12 @@ class JsInteropChecks extends RecursiveVisitor {
165168
super.visitLibrary(lib);
166169
_libraryIsGlobalNamespace = false;
167170
_libraryHasJSAnnotation = false;
171+
_libraryExtensionsIndex = null;
168172
}
169173

170174
@override
171175
void visitProcedure(Procedure procedure) {
172-
_checkJSInteropAnnotation(procedure);
176+
_checkInstanceMemberJSAnnotation(procedure);
173177
if (_classHasJSAnnotation && !procedure.isExternal) {
174178
// If not one of few exceptions, member is not allowed to exclude
175179
// `external` inside of a JS interop class.
@@ -183,38 +187,45 @@ class JsInteropChecks extends RecursiveVisitor {
183187
procedure.fileUri);
184188
}
185189
}
186-
if (!_isJSInteropMember(procedure)) return;
187190

188-
if (!procedure.isStatic &&
189-
(procedure.name.text == '[]=' || procedure.name.text == '[]')) {
190-
_diagnosticsReporter.report(messageJsInteropIndexNotSupported,
191-
procedure.fileOffset, procedure.name.text.length, procedure.fileUri);
192-
}
193-
194-
var isAnonymousFactory =
195-
_classHasAnonymousAnnotation && procedure.isFactory;
196-
197-
if (isAnonymousFactory) {
198-
// ignore: unnecessary_null_comparison
199-
if (procedure.function != null &&
200-
!procedure.function.positionalParameters.isEmpty) {
201-
var firstPositionalParam = procedure.function.positionalParameters[0];
191+
if (!_isJSInteropMember(procedure)) {
192+
_checkDisallowedExternal(procedure);
193+
} else {
194+
// Check JS interop indexing.
195+
if (!procedure.isStatic &&
196+
(procedure.name.text == '[]=' || procedure.name.text == '[]')) {
202197
_diagnosticsReporter.report(
203-
messageJsInteropAnonymousFactoryPositionalParameters,
204-
firstPositionalParam.fileOffset,
205-
firstPositionalParam.name!.length,
206-
firstPositionalParam.location!.file);
198+
messageJsInteropIndexNotSupported,
199+
procedure.fileOffset,
200+
procedure.name.text.length,
201+
procedure.fileUri);
202+
}
203+
204+
// Check JS Interop positional and named parameters.
205+
var isAnonymousFactory =
206+
_classHasAnonymousAnnotation && procedure.isFactory;
207+
if (isAnonymousFactory) {
208+
// ignore: unnecessary_null_comparison
209+
if (procedure.function != null &&
210+
!procedure.function.positionalParameters.isEmpty) {
211+
var firstPositionalParam = procedure.function.positionalParameters[0];
212+
_diagnosticsReporter.report(
213+
messageJsInteropAnonymousFactoryPositionalParameters,
214+
firstPositionalParam.fileOffset,
215+
firstPositionalParam.name!.length,
216+
firstPositionalParam.location!.file);
217+
}
218+
} else {
219+
// Only factory constructors for anonymous classes are allowed to have
220+
// named parameters.
221+
_checkNoNamedParameters(procedure.function);
207222
}
208-
} else {
209-
// Only factory constructors for anonymous classes are allowed to have
210-
// named parameters.
211-
_checkNoNamedParameters(procedure.function);
212223
}
213224
}
214225

215226
@override
216227
void visitConstructor(Constructor constructor) {
217-
_checkJSInteropAnnotation(constructor);
228+
_checkInstanceMemberJSAnnotation(constructor);
218229
if (_classHasJSAnnotation &&
219230
!constructor.isExternal &&
220231
!constructor.isSynthetic) {
@@ -225,9 +236,12 @@ class JsInteropChecks extends RecursiveVisitor {
225236
constructor.name.text.length,
226237
constructor.fileUri);
227238
}
228-
if (!_isJSInteropMember(constructor)) return;
229239

230-
_checkNoNamedParameters(constructor.function);
240+
if (!_isJSInteropMember(constructor)) {
241+
_checkDisallowedExternal(constructor);
242+
} else {
243+
_checkNoNamedParameters(constructor.function);
244+
}
231245
}
232246

233247
/// Reports an error if [functionNode] has named parameters.
@@ -243,9 +257,9 @@ class JsInteropChecks extends RecursiveVisitor {
243257
}
244258
}
245259

246-
/// Reports an error if [member] does not correctly use the JS interop
247-
/// annotation or the keyword `external`.
248-
void _checkJSInteropAnnotation(Member member) {
260+
/// Reports an error if given instance [member] is JS interop, but inside a
261+
/// non JS interop class.
262+
void _checkInstanceMemberJSAnnotation(Member member) {
249263
var enclosingClass = member.enclosingClass;
250264

251265
if (!_classHasJSAnnotation &&
@@ -262,13 +276,24 @@ class JsInteropChecks extends RecursiveVisitor {
262276
enclosingClass.name.length)
263277
]);
264278
}
279+
}
265280

266-
// Check for correct `external` usage.
267-
if (member.isExternal &&
268-
!_isAllowedExternalUsage(member) &&
269-
!hasJSInteropAnnotation(member)) {
270-
if (member.enclosingClass != null && !_classHasJSAnnotation ||
271-
member.enclosingClass == null && !_libraryHasJSAnnotation) {
281+
/// Assumes given [member] is not JS interop, and reports an error if
282+
/// [member] is `external` and not an allowed `external` usage.
283+
void _checkDisallowedExternal(Member member) {
284+
if (member.isExternal) {
285+
// TODO(rileyporter): Allow extension members on some Native classes.
286+
if (member.isExtensionMember) {
287+
_diagnosticsReporter.report(
288+
messageJsInteropExternalExtensionMemberNotOnJSClass,
289+
member.fileOffset,
290+
member.name.text.length,
291+
member.fileUri);
292+
} else if (!hasJSInteropAnnotation(member) &&
293+
!_isAllowedExternalUsage(member)) {
294+
// Member could be JS annotated and not considered a JS interop member
295+
// if inside a non-JS interop class. Should not report an error in this
296+
// case, since a different error will already be produced.
272297
_diagnosticsReporter.report(
273298
messageJsInteropExternalMemberNotJSAnnotated,
274299
member.fileOffset,
@@ -289,18 +314,39 @@ class JsInteropChecks extends RecursiveVisitor {
289314
}
290315

291316
/// Returns whether [member] is considered to be a JS interop member.
317+
///
318+
/// A JS interop member is `external`, and is in a valid JS interop context,
319+
/// which can be:
320+
/// - inside a JS interop class
321+
/// - inside an extension on a JS interop class
322+
/// - a top level member that is JS interop annotated or in a JS interop
323+
/// library
324+
/// If a member belongs to a class, the class must be JS interop annotated.
292325
bool _isJSInteropMember(Member member) {
293326
if (member.isExternal) {
294327
if (_classHasJSAnnotation) return true;
328+
if (member.isExtensionMember) return _isJSExtensionMember(member);
295329
if (member.enclosingClass == null) {
296-
// In the case where the member does not belong to any class, a JS
297-
// annotation is not needed on the library to be considered JS interop
298-
// as long as the member has an annotation.
299330
return hasJSInteropAnnotation(member) || _libraryHasJSAnnotation;
300331
}
301332
}
302333

303334
// Otherwise, not JS interop.
304335
return false;
305336
}
337+
338+
/// Returns whether given extension [member] is in an extension that is on a
339+
/// JS interop class.
340+
bool _isJSExtensionMember(Member member) {
341+
assert(member.isExtensionMember);
342+
if (_libraryExtensionsIndex == null) {
343+
_libraryExtensionsIndex = {};
344+
member.enclosingLibrary.extensions.forEach((extension) =>
345+
extension.members.forEach((memberDescriptor) =>
346+
_libraryExtensionsIndex![memberDescriptor.member] = extension));
347+
}
348+
349+
var onType = _libraryExtensionsIndex![member.reference]!.onType;
350+
return onType is InterfaceType && hasJSInteropAnnotation(onType.classNode);
351+
}
306352
}

pkg/dds/dds_protocol.md

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Dart Development Service Protocol 1.2
1+
# Dart Development Service Protocol 1.3
22

3-
This document describes _version 1.2_ of the Dart Development Service Protocol.
3+
This document describes _version 1.3_ of the Dart Development Service Protocol.
44
This protocol is an extension of the Dart VM Service Protocol and implements it
55
in it's entirety. For details on the VM Service Protocol, see the [Dart VM Service Protocol Specification][service-protocol].
66

@@ -67,6 +67,29 @@ event being sent to the subscribing client for each existing service extension.
6767

6868
The DDS Protocol supports all [public RPCs defined in the VM Service protocol][service-protocol-public-rpcs].
6969

70+
### getAvailableCachedCpuSamples
71+
72+
```
73+
AvailableCachedCpuSamples getAvailableCachedCpuSamples();
74+
```
75+
76+
The _getAvailableCachedCpuSamples_ RPC is used to determine which caches of CPU samples
77+
are available. Caches are associated with individual _UserTag_ names and are specified
78+
when DDS is started via the _cachedUserTags_ parameter.
79+
80+
See [AvailableCachedCpuSamples](#availablecachedcpusamples).
81+
82+
### getCachedCpuSamples
83+
84+
```
85+
CachedCpuSamples getCachedCpuSamples(string isolateId, string userTag);
86+
```
87+
88+
The _getCachedCpuSamples_ RPC is used to retrieve a cache of CPU samples collected
89+
under a _UserTag_ with name _userTag_.
90+
91+
See [CachedCpuSamples](#cachedcpusamples).
92+
7093
### getClientName
7194

7295
```
@@ -181,6 +204,37 @@ See [Success](#success).
181204

182205
The DDS Protocol supports all [public types defined in the VM Service protocol][service-protocol-public-types].
183206

207+
### AvailableCachedCpuSamples
208+
209+
```
210+
class AvailableCachedCpuSamples extends Response {
211+
// A list of UserTag names associated with CPU sample caches.
212+
string[] cacheNames;
213+
}
214+
```
215+
216+
A collection of [UserTag] names associated with caches of CPU samples.
217+
218+
See [getAvailableCachedCpuSamples](#getavailablecachedcpusamples).
219+
220+
### CachedCpuSamples
221+
222+
```
223+
class CachedCpuSamples extends CpuSamples {
224+
// The name of the UserTag associated with this cache of samples.
225+
string userTag;
226+
227+
// Provided if the CPU sample cache has filled and older samples have been
228+
// dropped.
229+
bool truncated [optional];
230+
}
231+
```
232+
233+
An extension of [CpuSamples](#cpu-samples) which represents a set of cached
234+
samples, associated with a particular [UserTag] name.
235+
236+
See [getCachedCpuSamples](#getcachedcpusamples).
237+
184238
### ClientName
185239

186240
```
@@ -220,10 +274,12 @@ version | comments
220274
1.0 | Initial revision
221275
1.1 | Added `getDartDevelopmentServiceVersion` RPC.
222276
1.2 | Added `getStreamHistory` RPC.
277+
1.3 | Added `getAvailableCachedCpuSamples` and `getCachedCpuSamples` RPCs.
223278

224279
[resume]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#resume
225280
[success]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#success
226281
[version]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#version
282+
[cpu-samples]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#cpusamples
227283

228284
[service-protocol]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md
229285
[service-protocol-rpcs-requests-and-responses]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#rpcs-requests-and-responses

pkg/dds/lib/dds.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ abstract class DartDevelopmentService {
4242
Uri? serviceUri,
4343
bool enableAuthCodes = true,
4444
bool ipv6 = false,
45+
List<String> cachedUserTags = const [],
4546
DevToolsConfiguration? devToolsConfiguration,
4647
bool logRequests = false,
4748
}) async {
@@ -79,6 +80,7 @@ abstract class DartDevelopmentService {
7980
remoteVmServiceUri,
8081
serviceUri,
8182
enableAuthCodes,
83+
cachedUserTags,
8284
ipv6,
8385
devToolsConfiguration,
8486
logRequests,
@@ -136,9 +138,13 @@ abstract class DartDevelopmentService {
136138
/// requests.
137139
bool get isRunning;
138140

141+
/// The list of [UserTag]s used to determine which CPU samples are cached by
142+
/// DDS.
143+
List<String> get cachedUserTags;
144+
139145
/// The version of the DDS protocol supported by this [DartDevelopmentService]
140146
/// instance.
141-
static const String protocolVersion = '1.2';
147+
static const String protocolVersion = '1.3';
142148
}
143149

144150
class DartDevelopmentServiceException implements Exception {

pkg/dds/lib/src/client.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,19 @@ class DartDevelopmentServiceClient {
206206
return supportedProtocols;
207207
});
208208

209+
_clientPeer.registerMethod(
210+
'getAvailableCachedCpuSamples',
211+
(_) => {
212+
'type': 'AvailableCachedCpuSamples',
213+
'cacheNames': dds.cachedUserTags,
214+
},
215+
);
216+
217+
_clientPeer.registerMethod(
218+
'getCachedCpuSamples',
219+
dds.isolateManager.getCachedCpuSamples,
220+
);
221+
209222
// `evaluate` and `evaluateInFrame` actually consist of multiple RPC
210223
// invocations, including a call to `compileExpression` which can be
211224
// overridden by clients which provide their own implementation (e.g.,

0 commit comments

Comments
 (0)