Skip to content

Commit 277d641

Browse files
author
Dart CI
committed
Version 2.19.0-366.0.dev
Merge dee7aa0 into dev
2 parents 94ac8f6 + dee7aa0 commit 277d641

File tree

101 files changed

+6060
-5813
lines changed

Some content is hidden

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

101 files changed

+6060
-5813
lines changed

pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart

Lines changed: 103 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ class JsUtilWasmOptimizer extends Transformer {
5353
final Procedure _allowInteropTarget;
5454
final Procedure _numToInt;
5555
final Class _wasmExternRefClass;
56-
final Class _objectClass;
5756
final Class _pragmaClass;
5857
final Field _pragmaName;
5958
final Field _pragmaOptions;
@@ -91,7 +90,6 @@ class JsUtilWasmOptimizer extends Transformer {
9190
.getClass('dart:core', 'num')
9291
.procedures
9392
.firstWhere((p) => p.name.text == 'toInt'),
94-
_objectClass = _coreTypes.objectClass,
9593
_pragmaClass = _coreTypes.pragmaClass,
9694
_pragmaName = _coreTypes.pragmaName,
9795
_pragmaOptions = _coreTypes.pragmaOptions,
@@ -232,88 +230,117 @@ class JsUtilWasmOptimizer extends Transformer {
232230
DartType get _nonNullableObjectType =>
233231
_coreTypes.objectRawType(Nullability.nonNullable);
234232

235-
Expression? _getInitializerFromTearOff(InstanceTearOff tearOff, int i) =>
236-
tearOff.interfaceTargetReference.asProcedure.function
237-
.positionalParameters[i].initializer;
233+
Expression _variableCheckConstant(
234+
VariableDeclaration variable, Constant constant) =>
235+
StaticInvocation(_coreTypes.identicalProcedure,
236+
Arguments([VariableGet(variable), ConstantExpression(constant)]));
237+
238+
Expression _variableNullCheck(VariableDeclaration variable) =>
239+
_variableCheckConstant(variable, NullConstant());
240+
241+
List<Expression> _generateCallbackArguments(
242+
FunctionType function, List<VariableDeclaration> positionalParameters,
243+
[int? requiredParameterCount]) {
244+
List<Expression> callbackArguments = [];
245+
int length = requiredParameterCount ?? function.positionalParameters.length;
246+
for (int i = 0; i < length; i++) {
247+
callbackArguments.add(AsExpression(VariableGet(positionalParameters[i]),
248+
function.positionalParameters[i]));
249+
}
250+
return callbackArguments;
251+
}
252+
253+
Statement _generateDispatchCase(
254+
FunctionType function,
255+
VariableDeclaration callbackVariable,
256+
List<VariableDeclaration> positionalParameters,
257+
[int? requiredParameterCount]) =>
258+
ReturnStatement(StaticInvocation(
259+
_jsifyRawTarget,
260+
Arguments([
261+
FunctionInvocation(
262+
FunctionAccessKind.FunctionType,
263+
AsExpression(VariableGet(callbackVariable), function),
264+
Arguments(_generateCallbackArguments(
265+
function, positionalParameters, requiredParameterCount)),
266+
functionType: function),
267+
])));
268+
269+
/// Builds the body of a function trampoline. To support default arguments, we
270+
/// find the last defined argument in JS, that is the last argument which was
271+
/// explicitly passed by the user, and then we dispatch to a Dart function
272+
/// with the right number of arguments.
273+
Statement _createFunctionTrampolineBody(
274+
FunctionType function,
275+
VariableDeclaration callbackVariable,
276+
VariableDeclaration lastDefinedArgument,
277+
List<VariableDeclaration> positionalParameters) {
278+
// Handle cases where some or all arguments are undefined.
279+
// TODO(joshualitt): Consider using a switch instead.
280+
List<Statement> dispatchCases = [];
281+
for (int i = function.requiredParameterCount - 1;
282+
i < function.positionalParameters.length;
283+
i++) {
284+
// In this case, [i] is the last defined argument which can range from
285+
// -1(no arguments defined), to an actual index in the positional
286+
// parameters. [_generateDispatchCase] must also take the required
287+
// parameter count, which is always the index of the last defined argument
288+
// + 1, i.e. the total number of defined arguments.
289+
int requiredParameterCount = i + 1;
290+
dispatchCases.add(IfStatement(
291+
_variableCheckConstant(
292+
lastDefinedArgument, DoubleConstant(i.toDouble())),
293+
_generateDispatchCase(function, callbackVariable,
294+
positionalParameters, requiredParameterCount),
295+
null));
296+
}
297+
298+
// Finally handle the case where all arguments are defined.
299+
dispatchCases.add(_generateDispatchCase(
300+
function, callbackVariable, positionalParameters));
301+
302+
return Block(dispatchCases);
303+
}
238304

239305
/// Creates a callback trampoline for the given [function]. This callback
240-
/// trampoline expects a Dart callback as its first argument, followed by all
241-
/// of the arguments to the Dart callback as Dart objects. The trampoline will
242-
/// cast all incoming Dart objects to the appropriate types, dispatch, and
243-
/// then `jsifyRaw` any returned value. [_createFunctionTrampoline] Returns a
244-
/// [String] function name representing the name of the wrapping function.
306+
/// trampoline expects a Dart callback as its first argument, then an integer
307+
/// value(double type) indicating the position of the last defined argument,
308+
/// followed by all of the arguments to the Dart callback as Dart objects. We
309+
/// will always pad the argument list up to the maximum number of positional
310+
/// arguments with `undefined` values. The trampoline will cast all incoming
311+
/// Dart objects to the appropriate types, dispatch, and then `jsifyRaw` any
312+
/// returned value. [_createFunctionTrampoline] Returns a [String] function
313+
/// name representing the name of the wrapping function.
245314
/// TODO(joshualitt): Share callback trampolines if the [FunctionType]
246315
/// matches.
247-
String _createFunctionTrampoline(
248-
Procedure node, FunctionType function, Expression argument) {
316+
/// TODO(joshualitt): Simplify the trampoline in JS for the case where there
317+
/// are no default arguments.
318+
String _createFunctionTrampoline(Procedure node, FunctionType function) {
249319
int fileOffset = node.fileOffset;
250320

251321
// Create arguments for each positional parameter in the function. These
252322
// arguments will be converted in JS to Dart objects. The generated wrapper
253323
// will cast each argument to the correct type. The first argument to this
254324
// function will be the Dart callback, which will be cast to the supplied
255-
// [FunctionType] before being invoked.
325+
// [FunctionType] before being invoked. The second argument will be the
326+
// last defined argument which is necessary to support default arguments in
327+
// callbacks.
256328
int parameterId = 1;
257-
DartType nonNullableObjectType =
258-
_objectClass.getThisType(_coreTypes, Nullability.nonNullable);
259329
final callbackVariable =
260-
VariableDeclaration('callback', type: nonNullableObjectType);
261-
List<VariableDeclaration> positionalParameters = [callbackVariable];
262-
List<Expression> callbackArguments = [];
263-
DartType nullableObjectType =
264-
_objectClass.getThisType(_coreTypes, Nullability.nullable);
265-
for (int i = 0; i < function.positionalParameters.length; i++) {
266-
DartType type = function.positionalParameters[i];
267-
Expression? defaultExpression;
268-
bool hasDefault = i >= function.requiredParameterCount;
269-
if (hasDefault) {
270-
// We can only generate default values if we have a statically typed
271-
// function argument.
272-
Expression? initializer;
273-
if (argument is ConstantExpression) {
274-
Procedure callbackTarget = (argument.constant as TearOffConstant)
275-
.targetReference
276-
.asProcedure;
277-
initializer =
278-
callbackTarget.function.positionalParameters[i].initializer;
279-
} else if (argument is FunctionExpression) {
280-
initializer = argument.function.positionalParameters[i].initializer;
281-
} else if (argument is InstanceTearOff) {
282-
initializer = _getInitializerFromTearOff(argument, i);
283-
} else if (argument is AsExpression &&
284-
argument.operand is InstanceTearOff) {
285-
initializer = _getInitializerFromTearOff(
286-
argument.operand as InstanceTearOff, i);
287-
} else {
288-
throw 'Cannot pass default arguments.';
289-
}
290-
291-
// The initializer for a default argument must be a
292-
// [ConstantExpression].
293-
ConstantExpression init = initializer as ConstantExpression;
294-
defaultExpression = ConstantExpression(init.constant, init.type);
295-
}
296-
VariableDeclaration variable =
297-
VariableDeclaration('x${parameterId++}', type: nullableObjectType);
298-
positionalParameters.add(variable);
299-
Expression body;
300-
if (hasDefault) {
301-
body = ConditionalExpression(
302-
StaticInvocation(
303-
_coreTypes.identicalProcedure,
304-
Arguments([
305-
VariableGet(variable),
306-
ConstantExpression(NullConstant())
307-
])),
308-
defaultExpression ?? ConstantExpression(NullConstant()),
309-
VariableGet(variable),
310-
nullableObjectType);
311-
} else {
312-
body = VariableGet(variable);
313-
}
314-
callbackArguments.add(AsExpression(body, type));
330+
VariableDeclaration('callback', type: _nonNullableObjectType);
331+
final lastDefinedArgument = VariableDeclaration('lastDefinedArgument',
332+
type: _coreTypes.doubleNonNullableRawType);
333+
334+
// Initialize variable declarations.
335+
List<VariableDeclaration> positionalParameters = [];
336+
for (int j = 0; j < function.positionalParameters.length; j++) {
337+
positionalParameters.add(
338+
VariableDeclaration('x${parameterId++}', type: _nullableObjectType));
315339
}
316340

341+
Statement functionTrampolineBody = _createFunctionTrampolineBody(
342+
function, callbackVariable, lastDefinedArgument, positionalParameters);
343+
317344
// Create a new procedure for the callback trampoline. This procedure will
318345
// be exported from Wasm to JS so it can be called from JS. The argument
319346
// returned from the supplied callback will be converted with `jsifyRaw` to
@@ -327,17 +354,10 @@ class JsUtilWasmOptimizer extends Transformer {
327354
final functionTrampoline = Procedure(
328355
Name(functionTrampolineName, _library),
329356
ProcedureKind.Method,
330-
FunctionNode(
331-
ReturnStatement(StaticInvocation(
332-
_jsifyRawTarget,
333-
Arguments([
334-
FunctionInvocation(
335-
FunctionAccessKind.FunctionType,
336-
AsExpression(VariableGet(callbackVariable), function),
337-
Arguments(callbackArguments),
338-
functionType: function),
339-
]))),
340-
positionalParameters: positionalParameters,
357+
FunctionNode(functionTrampolineBody,
358+
positionalParameters: [callbackVariable, lastDefinedArgument]
359+
.followedBy(positionalParameters)
360+
.toList(),
341361
returnType: nullableWasmExternRefType)
342362
..fileOffset = fileOffset,
343363
isStatic: true,
@@ -358,8 +378,7 @@ class JsUtilWasmOptimizer extends Transformer {
358378
/// [_createFunctionTrampoline] followed by `_wrapDartFunction`.
359379
StaticInvocation _allowInterop(
360380
Procedure node, FunctionType type, Expression argument) {
361-
String functionTrampolineName =
362-
_createFunctionTrampoline(node, type, argument);
381+
String functionTrampolineName = _createFunctionTrampoline(node, type);
363382
return StaticInvocation(
364383
_wrapDartFunctionTarget,
365384
Arguments([
@@ -440,10 +459,7 @@ class JsUtilWasmOptimizer extends Transformer {
440459
return Let(
441460
v,
442461
ConditionalExpression(
443-
StaticInvocation(
444-
_coreTypes.identicalProcedure,
445-
Arguments(
446-
[VariableGet(v), ConstantExpression(NullConstant())])),
462+
_variableNullCheck(v),
447463
ConstantExpression(NullConstant()),
448464
InstanceInvocation(InstanceAccessKind.Instance, VariableGet(v),
449465
_numToInt.name, Arguments([]),

pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ class ElementMatcher {
6464
return false;
6565
}
6666
}
67-
return true;
68-
}
69-
// The node has fewer components, which can happen, for example, when we
70-
// can't figure out the class that used to define a field. We treat the
71-
// missing components as wildcards and match the rest.
72-
for (var i = 0; i < nodeComponentCount; i++) {
73-
if (elementComponents[i] != components[i]) {
74-
return false;
67+
} else {
68+
// The node has fewer components, which can happen, for example, when we
69+
// can't figure out the class that used to define a field. We treat the
70+
// missing components as wildcards and match the rest.
71+
for (var i = 0; i < nodeComponentCount; i++) {
72+
if (elementComponents[i] != components[i]) {
73+
return false;
74+
}
7575
}
7676
}
7777
} else {

pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class TransformSetManager {
6262
var sdkRoot = analysisContext.sdkRoot;
6363
if (sdkRoot != null) {
6464
var file = sdkRoot.getChildAssumingFile('lib/_internal/$dataFileName');
65-
var transformSet = _loadTransformSet(file);
65+
var transformSet = _loadTransformSet(file, null);
6666
if (transformSet != null) {
6767
transformSets.add(transformSet);
6868
_sdkCache = transformSet;
@@ -73,40 +73,42 @@ class TransformSetManager {
7373
}
7474

7575
List<TransformSet> _fromFolder(Folder folder) {
76+
var packageName = folder.parent.shortName;
7677
var transformSets = <TransformSet>[];
7778
var file = folder.getChildAssumingFile(dataFileName);
78-
var transformSet = _loadTransformSet(file);
79+
var transformSet = _loadTransformSet(file, packageName);
7980
if (transformSet != null) {
8081
transformSets.add(transformSet);
8182
}
8283
var childFolder = folder.getChildAssumingFolder(dataFolderName);
8384
if (childFolder.exists) {
84-
_loadTransforms(transformSets, childFolder);
85+
_loadTransforms(transformSets, childFolder, packageName);
8586
}
8687
return transformSets;
8788
}
8889

8990
/// Recursively search all the children of the specified [folder],
9091
/// and add the transform sets found to the [transforms].
91-
void _loadTransforms(List<TransformSet> transforms, Folder folder) {
92+
void _loadTransforms(
93+
List<TransformSet> transforms, Folder folder, String packageName) {
9294
for (var resource in folder.getChildren()) {
9395
if (resource is File) {
9496
if (resource.shortName.endsWith('.yaml')) {
95-
var transformSet = _loadTransformSet(resource);
97+
var transformSet = _loadTransformSet(resource, packageName);
9698
if (transformSet != null) {
9799
transforms.add(transformSet);
98100
}
99101
}
100102
} else if (resource is Folder) {
101-
_loadTransforms(transforms, resource);
103+
_loadTransforms(transforms, resource, packageName);
102104
}
103105
}
104106
}
105107

106108
/// Read the [file] and parse the content. Return the transform set that was
107109
/// parsed, or `null` if the file doesn't exist, isn't readable, or if the
108110
/// content couldn't be parsed.
109-
TransformSet? _loadTransformSet(File file) {
111+
TransformSet? _loadTransformSet(File file, String? packageName) {
110112
try {
111113
var content = file.readAsStringSync();
112114
var parser = TransformSetParser(
@@ -115,7 +117,7 @@ class TransformSetManager {
115117
file.createSource(),
116118
isNonNullableByDefault: false,
117119
),
118-
file.parent.parent.shortName);
120+
packageName);
119121
return parser.parse(content);
120122
} on FileSystemException {
121123
// Fall through to return `null`.

pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ class TransformSetParser {
131131
final ErrorReporter errorReporter;
132132

133133
/// The name of the package from which the data file being translated was
134-
/// found.
135-
final String packageName;
134+
/// found, or `null` for the SDK.
135+
final String? packageName;
136136

137137
/// The description of the element that is being transformed by the current
138138
/// transformation, or `null` if we are not in the process of parsing a
@@ -1057,7 +1057,9 @@ class TransformSetParser {
10571057
if (node is YamlScalar) {
10581058
var value = node.value;
10591059
if (value is String) {
1060-
if (!(value.startsWith('dart:') || value.startsWith('package:'))) {
1060+
if (packageName != null &&
1061+
!value.startsWith('dart:') &&
1062+
!value.startsWith('package:')) {
10611063
value = 'package:$packageName/$value';
10621064
}
10631065
return Uri.parse(value);

0 commit comments

Comments
 (0)